1 /* Functions for image support on window system.
2
3 Copyright (C) 1989, 1992-2021 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or (at
10 your option) any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
19
20 #include <config.h>
21
22 #include <fcntl.h>
23 #include <math.h>
24 #include <unistd.h>
25
26 /* Include this before including <setjmp.h> to work around bugs with
27 older libpng; see Bug#17429. */
28 #if defined HAVE_PNG
29 # include <png.h>
30 #endif
31
32 #include <setjmp.h>
33
34 #include <math.h>
35 #include <stdint.h>
36 #include <c-ctype.h>
37 #include <flexmember.h>
38
39 #include "lisp.h"
40 #include "frame.h"
41 #include "process.h"
42 #include "window.h"
43 #include "buffer.h"
44 #include "dispextern.h"
45 #include "blockinput.h"
46 #include "sysstdio.h"
47 #include "systime.h"
48 #include <epaths.h>
49 #include "coding.h"
50 #include "termhooks.h"
51 #include "font.h"
52 #include "pdumper.h"
53
54 #ifdef HAVE_SYS_STAT_H
55 #include <sys/stat.h>
56 #endif /* HAVE_SYS_STAT_H */
57
58 #ifdef HAVE_SYS_TYPES_H
59 #include <sys/types.h>
60 #endif /* HAVE_SYS_TYPES_H */
61
62 #ifdef HAVE_WINDOW_SYSTEM
63 #include TERM_HEADER
64 #endif /* HAVE_WINDOW_SYSTEM */
65
66 /* Work around GCC bug 54561. */
67 #if GNUC_PREREQ (4, 3, 0)
68 # pragma GCC diagnostic ignored "-Wclobbered"
69 #endif
70
71 #ifdef HAVE_X_WINDOWS
72 typedef struct x_bitmap_record Bitmap_Record;
73 #ifndef USE_CAIRO
74 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
75 #define PUT_PIXEL XPutPixel
76 #define NO_PIXMAP None
77
78 #define PIX_MASK_RETAIN 0
79 #define PIX_MASK_DRAW 1
80 #endif /* !USE_CAIRO */
81 #endif /* HAVE_X_WINDOWS */
82
83 #if defined(USE_CAIRO) || defined(HAVE_NS)
84 #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
85 #define ARGB_TO_ULONG(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
86 #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
87 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
88 #define BLUE_FROM_ULONG(color) ((color) & 0xff)
89 #define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
90 #define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
91 #define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
92 #endif
93
94 #ifdef USE_CAIRO
95 #define GET_PIXEL image_pix_context_get_pixel
96 #define PUT_PIXEL image_pix_container_put_pixel
97 #define NO_PIXMAP 0
98
99 #define PIX_MASK_RETAIN 0
100 #define PIX_MASK_DRAW 255
101
102 static unsigned long image_alloc_image_color (struct frame *, struct image *,
103 Lisp_Object, unsigned long);
104 #endif /* USE_CAIRO */
105
106 #if defined HAVE_PGTK && defined HAVE_IMAGEMAGICK
107 /* In pgtk, we don't want to create scaled image. If we create scaled
108 * image on scale=2.0 environment, the created image is half size and
109 * Gdk scales it back, and the result is blurry. To avoid this, we
110 * hold original size image as far as we can, and let Gdk to scale it
111 * when it is shown. */
112 # define DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
113 #endif
114
115 #ifdef HAVE_NTGUI
116
117 /* We need (or want) w32.h only when we're _not_ compiling for Cygwin. */
118 #ifdef WINDOWSNT
119 # include "w32common.h"
120 # include "w32.h"
121 #endif
122
123 typedef struct w32_bitmap_record Bitmap_Record;
124 #define GET_PIXEL(ximg, x, y) GetPixel (ximg, x, y)
125 #define PUT_PIXEL XPutPixel
126 #define NO_PIXMAP 0
127
128 #define PIX_MASK_RETAIN 0
129 #define PIX_MASK_DRAW 1
130
131 #endif /* HAVE_NTGUI */
132
133 #ifdef HAVE_NS
134 typedef struct ns_bitmap_record Bitmap_Record;
135
136 #define GET_PIXEL(ximg, x, y) XGetPixel (ximg, x, y)
137 #define PUT_PIXEL XPutPixel
138 #define NO_PIXMAP 0
139
140 #define PIX_MASK_RETAIN 0
141 #define PIX_MASK_DRAW 1
142
143 #endif /* HAVE_NS */
144
145 #ifdef HAVE_PGTK
146 typedef struct pgtk_bitmap_record Bitmap_Record;
147 #endif /* HAVE_PGTK */
148
149 #if (defined HAVE_X_WINDOWS \
150 && ! (defined HAVE_NTGUI || defined USE_CAIRO || defined HAVE_NS))
151 /* W32_TODO : Color tables on W32. */
152 # define COLOR_TABLE_SUPPORT 1
153 #endif
154
155 #ifdef HAVE_HAIKU
156 #include "haiku_support.h"
157 typedef struct haiku_bitmap_record Bitmap_Record;
158
159 #define GET_PIXEL(ximg, x, y) haiku_get_pixel (ximg, x, y)
160 #define PUT_PIXEL haiku_put_pixel
161 #define NO_PIXMAP 0
162
163 #define PIX_MASK_RETAIN 0
164 #define PIX_MASK_DRAW 1
165
166 #define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
167 #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
168 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
169 #define BLUE_FROM_ULONG(color) ((color) & 0xff)
170 #define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
171 #define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
172 #define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
173
174 #endif
175
176 static void image_disable_image (struct frame *, struct image *);
177 static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
178 Lisp_Object);
179
180 static void init_color_table (void);
181 static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
182 #ifdef COLOR_TABLE_SUPPORT
183 static void free_color_table (void);
184 static unsigned long *colors_in_color_table (int *n);
185 #endif
186
187 #ifdef USE_CAIRO
188
189 static Emacs_Pix_Container
image_create_pix_container(struct frame * f,unsigned int width,unsigned int height,unsigned int depth)190 image_create_pix_container (struct frame *f, unsigned int width,
191 unsigned int height, unsigned int depth)
192 {
193 Emacs_Pix_Container pimg;
194
195 pimg = xmalloc (sizeof (*pimg));
196 pimg->width = width;
197 pimg->height = height;
198 pimg->bits_per_pixel = depth == 1 ? 8 : 32;
199 pimg->bytes_per_line = cairo_format_stride_for_width ((depth == 1
200 ? CAIRO_FORMAT_A8
201 : CAIRO_FORMAT_RGB24),
202 width);
203 pimg->data = xmalloc (pimg->bytes_per_line * height);
204
205 return pimg;
206 }
207
208 static void
image_pix_container_put_pixel(Emacs_Pix_Container image,int x,int y,unsigned long pixel)209 image_pix_container_put_pixel (Emacs_Pix_Container image,
210 int x, int y, unsigned long pixel)
211 {
212 if (image->bits_per_pixel == 32)
213 ((uint32_t *)(image->data + y * image->bytes_per_line))[x] = pixel;
214 else
215 ((uint8_t *)(image->data + y * image->bytes_per_line))[x] = pixel;
216 }
217
218 static unsigned long
image_pix_context_get_pixel(Emacs_Pix_Context image,int x,int y)219 image_pix_context_get_pixel (Emacs_Pix_Context image, int x, int y)
220 {
221 if (image->bits_per_pixel == 32)
222 return ((uint32_t *)(image->data + y * image->bytes_per_line))[x];
223 else
224 return ((uint8_t *)(image->data + y * image->bytes_per_line))[x];
225 }
226
227 static Emacs_Pix_Container
image_pix_container_create_from_bitmap_data(struct frame * f,char * data,unsigned int width,unsigned int height,unsigned long fg,unsigned long bg)228 image_pix_container_create_from_bitmap_data (struct frame *f,
229 char *data, unsigned int width,
230 unsigned int height,
231 unsigned long fg,
232 unsigned long bg)
233 {
234 Emacs_Pix_Container pimg = image_create_pix_container (f, width, height, 0);
235 int bytes_per_line = (width + (CHAR_BIT - 1)) / CHAR_BIT;
236
237 for (int y = 0; y < height; y++)
238 {
239 for (int x = 0; x < width; x++)
240 PUT_PIXEL (pimg, x, y,
241 (data[x / CHAR_BIT] >> (x % CHAR_BIT)) & 1 ? fg : bg);
242 data += bytes_per_line;
243 }
244
245 return pimg;
246 }
247
248 static cairo_surface_t *
cr_create_surface_from_pix_containers(Emacs_Pix_Container pimg,Emacs_Pix_Container mask)249 cr_create_surface_from_pix_containers (Emacs_Pix_Container pimg,
250 Emacs_Pix_Container mask)
251 {
252 cairo_surface_t *surface;
253
254 if (mask)
255 {
256 int x, y;
257
258 for (y = 0; y < pimg->height; y++)
259 for (x = 0; x < pimg->width; x++)
260 {
261 unsigned long color, alpha;
262 int r, g, b;
263
264 color = GET_PIXEL (pimg, x, y);
265 alpha = GET_PIXEL (mask, x, y);
266 r = (RED_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
267 g = (GREEN_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
268 b = (BLUE_FROM_ULONG (color) * alpha + 0x7f) / 0xff;
269 PUT_PIXEL (pimg, x, y, ARGB_TO_ULONG (alpha, r, g, b));
270 }
271 xfree (mask->data);
272 mask->data = NULL;
273 }
274 surface = cairo_image_surface_create_for_data ((unsigned char *) pimg->data,
275 (mask ? CAIRO_FORMAT_ARGB32
276 : CAIRO_FORMAT_RGB24),
277 pimg->width, pimg->height,
278 pimg->bytes_per_line);
279 static const cairo_user_data_key_t key;
280 cairo_surface_set_user_data (surface, &key, pimg->data, xfree);
281 pimg->data = NULL;
282
283 return surface;
284 }
285
286 static void
cr_put_image_to_cr_data(struct image * img)287 cr_put_image_to_cr_data (struct image *img)
288 {
289 cairo_pattern_t *pattern = NULL;
290 cairo_surface_t *surface = cr_create_surface_from_pix_containers (img->pixmap,
291 img->mask);
292 if (surface)
293 {
294 pattern = cairo_pattern_create_for_surface (surface);
295 if (img->cr_data)
296 {
297 cairo_matrix_t matrix;
298 cairo_pattern_get_matrix (img->cr_data, &matrix);
299 cairo_pattern_set_matrix (pattern, &matrix);
300 cairo_pattern_set_filter
301 (pattern, cairo_pattern_get_filter (img->cr_data));
302 cairo_pattern_destroy (img->cr_data);
303 }
304 cairo_surface_destroy (surface);
305 }
306
307 img->cr_data = pattern;
308 }
309
310 #endif /* USE_CAIRO */
311
312 #ifdef HAVE_NS
313 /* Use with images created by ns_image_for_XPM. */
314 static unsigned long
XGetPixel(Emacs_Pix_Container image,int x,int y)315 XGetPixel (Emacs_Pix_Container image, int x, int y)
316 {
317 return ns_get_pixel (image, x, y);
318 }
319
320 /* Use with images created by ns_image_for_XPM; alpha set to 1;
321 pixel is assumed to be in RGB form. */
322 static void
XPutPixel(Emacs_Pix_Container image,int x,int y,unsigned long pixel)323 XPutPixel (Emacs_Pix_Container image, int x, int y, unsigned long pixel)
324 {
325 ns_put_pixel (image, x, y, pixel);
326 }
327 #endif /* HAVE_NS */
328
329 /* Code to deal with bitmaps. Bitmaps are referenced by their bitmap
330 id, which is just an int that this section returns. Bitmaps are
331 reference counted so they can be shared among frames.
332
333 Bitmap indices are guaranteed to be > 0, so a negative number can
334 be used to indicate no bitmap.
335
336 If you use image_create_bitmap_from_data, then you must keep track
337 of the bitmaps yourself. That is, creating a bitmap from the same
338 data more than once will not be caught. */
339
340 /* Functions to access the contents of a bitmap, given an id. */
341
342 #ifdef HAVE_X_WINDOWS
343 static int
x_bitmap_height(struct frame * f,ptrdiff_t id)344 x_bitmap_height (struct frame *f, ptrdiff_t id)
345 {
346 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].height;
347 }
348
349 static int
x_bitmap_width(struct frame * f,ptrdiff_t id)350 x_bitmap_width (struct frame *f, ptrdiff_t id)
351 {
352 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].width;
353 }
354
355 #ifdef USE_CAIRO
356 cairo_pattern_t *
x_bitmap_stipple(struct frame * f,Pixmap pixmap)357 x_bitmap_stipple (struct frame *f, Pixmap pixmap)
358 {
359 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
360
361 for (ptrdiff_t i = 0; i < dpyinfo->bitmaps_last; i++)
362 {
363 struct x_bitmap_record *bm = dpyinfo->bitmaps + i;
364
365 if (bm->refcount && bm->pixmap == pixmap && bm->depth == 1)
366 {
367 if (bm->stipple == NULL)
368 {
369 cairo_surface_t *surface
370 = cairo_xlib_surface_create_for_bitmap (FRAME_X_DISPLAY (f),
371 pixmap,
372 FRAME_X_SCREEN (f),
373 bm->width, bm->height);
374 cairo_pattern_t *pattern
375 = cairo_pattern_create_for_surface (surface);
376 cairo_surface_destroy (surface);
377 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
378 bm->stipple = pattern;
379 }
380
381 return bm->stipple;
382 }
383 }
384
385 return NULL;
386 }
387
388 #endif /* USE_CAIRO */
389 #endif
390
391 #if defined (HAVE_X_WINDOWS) || defined (HAVE_NTGUI)
392 ptrdiff_t
image_bitmap_pixmap(struct frame * f,ptrdiff_t id)393 image_bitmap_pixmap (struct frame *f, ptrdiff_t id)
394 {
395 /* HAVE_NTGUI needs the explicit cast here. */
396 return (ptrdiff_t) FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
397 }
398 #endif
399
400 #ifdef HAVE_X_WINDOWS
401 int
x_bitmap_mask(struct frame * f,ptrdiff_t id)402 x_bitmap_mask (struct frame *f, ptrdiff_t id)
403 {
404 return FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].mask;
405 }
406 #endif
407
408 /* Allocate a new bitmap record. Returns index of new record. */
409
410 static ptrdiff_t
image_allocate_bitmap_record(struct frame * f)411 image_allocate_bitmap_record (struct frame *f)
412 {
413 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
414 ptrdiff_t i;
415
416 if (dpyinfo->bitmaps_last < dpyinfo->bitmaps_size)
417 return ++dpyinfo->bitmaps_last;
418
419 for (i = 0; i < dpyinfo->bitmaps_size; ++i)
420 if (dpyinfo->bitmaps[i].refcount == 0)
421 return i + 1;
422
423 dpyinfo->bitmaps =
424 xpalloc (dpyinfo->bitmaps, &dpyinfo->bitmaps_size,
425 10, -1, sizeof *dpyinfo->bitmaps);
426 return ++dpyinfo->bitmaps_last;
427 }
428
429 /* Add one reference to the reference count of the bitmap with id ID. */
430
431 void
image_reference_bitmap(struct frame * f,ptrdiff_t id)432 image_reference_bitmap (struct frame *f, ptrdiff_t id)
433 {
434 ++FRAME_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
435 }
436
437 #ifdef HAVE_PGTK
438 static cairo_pattern_t *
image_create_pattern_from_pixbuf(struct frame * f,GdkPixbuf * pixbuf)439 image_create_pattern_from_pixbuf (struct frame *f, GdkPixbuf * pixbuf)
440 {
441 GdkPixbuf *pb = gdk_pixbuf_add_alpha (pixbuf, TRUE, 255, 255, 255);
442 cairo_surface_t *surface =
443 cairo_surface_create_similar_image (cairo_get_target
444 (f->output_data.pgtk->cr_context),
445 CAIRO_FORMAT_A1,
446 gdk_pixbuf_get_width (pb),
447 gdk_pixbuf_get_height (pb));
448
449 cairo_t *cr = cairo_create (surface);
450 gdk_cairo_set_source_pixbuf (cr, pb, 0, 0);
451 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
452 cairo_paint (cr);
453 cairo_destroy (cr);
454
455 cairo_pattern_t *pat = cairo_pattern_create_for_surface (surface);
456 cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT);
457
458 cairo_surface_destroy (surface);
459 g_object_unref (pb);
460
461 return pat;
462 }
463 #endif
464
465 /* Create a bitmap for frame F from a HEIGHT x WIDTH array of bits at BITS. */
466
467 ptrdiff_t
image_create_bitmap_from_data(struct frame * f,char * bits,unsigned int width,unsigned int height)468 image_create_bitmap_from_data (struct frame *f, char *bits,
469 unsigned int width, unsigned int height)
470 {
471 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
472 ptrdiff_t id;
473
474 #ifdef HAVE_X_WINDOWS
475 Pixmap bitmap;
476 bitmap = XCreateBitmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
477 bits, width, height);
478 if (! bitmap)
479 return -1;
480 #endif /* HAVE_X_WINDOWS */
481
482 #ifdef HAVE_NTGUI
483 Lisp_Object frame UNINIT; /* The value is not used. */
484 Emacs_Pixmap bitmap;
485 bitmap = CreateBitmap (width, height,
486 FRAME_DISPLAY_INFO (XFRAME (frame))->n_planes,
487 FRAME_DISPLAY_INFO (XFRAME (frame))->n_cbits,
488 bits);
489 if (! bitmap)
490 return -1;
491 #endif /* HAVE_NTGUI */
492
493 #ifdef HAVE_NS
494 void *bitmap = ns_image_from_XBM (bits, width, height, 0, 0);
495 if (!bitmap)
496 return -1;
497 #endif
498
499 #ifdef HAVE_PGTK
500 GdkPixbuf *pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
501 FALSE,
502 8,
503 width,
504 height);
505 {
506 char *sp = bits;
507 int mask = 0x01;
508 unsigned char *buf = gdk_pixbuf_get_pixels (pixbuf);
509 int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
510 for (int y = 0; y < height; y++)
511 {
512 unsigned char *dp = buf + rowstride * y;
513 for (int x = 0; x < width; x++)
514 {
515 if (*sp & mask)
516 {
517 *dp++ = 0xff;
518 *dp++ = 0xff;
519 *dp++ = 0xff;
520 }
521 else
522 {
523 *dp++ = 0x00;
524 *dp++ = 0x00;
525 *dp++ = 0x00;
526 }
527 if ((mask <<= 1) >= 0x100)
528 {
529 mask = 0x01;
530 sp++;
531 }
532 }
533 if (mask != 0x01)
534 {
535 mask = 0x01;
536 sp++;
537 }
538 }
539 }
540 #endif /* HAVE_PGTK */
541
542 #ifdef HAVE_HAIKU
543 void *bitmap = BBitmap_new (width, height, 1);
544 BBitmap_import_mono_bits (bitmap, bits, width, height);
545 #endif
546
547 id = image_allocate_bitmap_record (f);
548
549 #ifdef HAVE_NS
550 dpyinfo->bitmaps[id - 1].img = bitmap;
551 dpyinfo->bitmaps[id - 1].depth = 1;
552 #endif
553
554 #ifdef HAVE_PGTK
555 dpyinfo->bitmaps[id - 1].img = pixbuf;
556 dpyinfo->bitmaps[id - 1].depth = 1;
557 dpyinfo->bitmaps[id - 1].pattern =
558 image_create_pattern_from_pixbuf (f, pixbuf);
559 #endif
560
561 #ifdef HAVE_HAIKU
562 dpyinfo->bitmaps[id - 1].img = bitmap;
563 dpyinfo->bitmaps[id - 1].depth = 1;
564 #endif
565
566 dpyinfo->bitmaps[id - 1].file = NULL;
567 dpyinfo->bitmaps[id - 1].height = height;
568 dpyinfo->bitmaps[id - 1].width = width;
569 dpyinfo->bitmaps[id - 1].refcount = 1;
570
571 #ifdef HAVE_X_WINDOWS
572 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
573 dpyinfo->bitmaps[id - 1].have_mask = false;
574 dpyinfo->bitmaps[id - 1].depth = 1;
575 #ifdef USE_CAIRO
576 dpyinfo->bitmaps[id - 1].stipple = NULL;
577 #endif /* USE_CAIRO */
578 #endif /* HAVE_X_WINDOWS */
579
580 #ifdef HAVE_NTGUI
581 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
582 dpyinfo->bitmaps[id - 1].hinst = NULL;
583 dpyinfo->bitmaps[id - 1].depth = 1;
584 #endif /* HAVE_NTGUI */
585
586 return id;
587 }
588
589 /* Create bitmap from file FILE for frame F. */
590
591 ptrdiff_t
image_create_bitmap_from_file(struct frame * f,Lisp_Object file)592 image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
593 {
594 #if defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
595 return -1; /* W32_TODO : bitmap support */
596 #else
597 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
598 #endif
599
600 #ifdef HAVE_NS
601 ptrdiff_t id;
602 void *bitmap = ns_image_from_file (file);
603
604 if (!bitmap)
605 return -1;
606
607
608 id = image_allocate_bitmap_record (f);
609 dpyinfo->bitmaps[id - 1].img = bitmap;
610 dpyinfo->bitmaps[id - 1].refcount = 1;
611 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
612 dpyinfo->bitmaps[id - 1].depth = 1;
613 dpyinfo->bitmaps[id - 1].height = ns_image_width (bitmap);
614 dpyinfo->bitmaps[id - 1].width = ns_image_height (bitmap);
615 return id;
616 #endif
617
618 #ifdef HAVE_PGTK
619 GError *err = NULL;
620 ptrdiff_t id;
621 void * bitmap = gdk_pixbuf_new_from_file (SSDATA (file), &err);
622
623 if (!bitmap)
624 {
625 g_error_free (err);
626 return -1;
627 }
628
629 id = image_allocate_bitmap_record (f);
630
631 dpyinfo->bitmaps[id - 1].img = bitmap;
632 dpyinfo->bitmaps[id - 1].refcount = 1;
633 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
634 //dpyinfo->bitmaps[id - 1].depth = 1;
635 dpyinfo->bitmaps[id - 1].height = gdk_pixbuf_get_width (bitmap);
636 dpyinfo->bitmaps[id - 1].width = gdk_pixbuf_get_height (bitmap);
637 dpyinfo->bitmaps[id - 1].pattern
638 = image_create_pattern_from_pixbuf (f, bitmap);
639 return id;
640 #endif
641
642 #ifdef HAVE_X_WINDOWS
643 unsigned int width, height;
644 Pixmap bitmap;
645 int xhot, yhot, result;
646 ptrdiff_t id;
647 Lisp_Object found;
648 char *filename;
649
650 /* Look for an existing bitmap with the same name. */
651 for (id = 0; id < dpyinfo->bitmaps_last; ++id)
652 {
653 if (dpyinfo->bitmaps[id].refcount
654 && dpyinfo->bitmaps[id].file
655 && !strcmp (dpyinfo->bitmaps[id].file, SSDATA (file)))
656 {
657 ++dpyinfo->bitmaps[id].refcount;
658 return id + 1;
659 }
660 }
661
662 /* Search bitmap-file-path for the file, if appropriate. */
663 if (openp (Vx_bitmap_file_path, file, Qnil, &found,
664 make_fixnum (R_OK), false, false)
665 < 0)
666 return -1;
667
668 filename = SSDATA (found);
669
670 result = XReadBitmapFile (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
671 filename, &width, &height, &bitmap, &xhot, &yhot);
672 if (result != BitmapSuccess)
673 return -1;
674
675 id = image_allocate_bitmap_record (f);
676 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
677 dpyinfo->bitmaps[id - 1].have_mask = false;
678 dpyinfo->bitmaps[id - 1].refcount = 1;
679 dpyinfo->bitmaps[id - 1].file = xlispstrdup (file);
680 dpyinfo->bitmaps[id - 1].depth = 1;
681 dpyinfo->bitmaps[id - 1].height = height;
682 dpyinfo->bitmaps[id - 1].width = width;
683 #ifdef USE_CAIRO
684 dpyinfo->bitmaps[id - 1].stipple = NULL;
685 #endif /* USE_CAIRO */
686
687 return id;
688 #endif /* HAVE_X_WINDOWS */
689 }
690
691 /* Free bitmap B. */
692
693 static void
free_bitmap_record(Display_Info * dpyinfo,Bitmap_Record * bm)694 free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
695 {
696 #ifdef HAVE_X_WINDOWS
697 XFreePixmap (dpyinfo->display, bm->pixmap);
698 if (bm->have_mask)
699 XFreePixmap (dpyinfo->display, bm->mask);
700 #ifdef USE_CAIRO
701 if (bm->stipple)
702 cairo_pattern_destroy (bm->stipple);
703 #endif /* USE_CAIRO */
704 #endif /* HAVE_X_WINDOWS */
705
706 #ifdef HAVE_NTGUI
707 DeleteObject (bm->pixmap);
708 #endif /* HAVE_NTGUI */
709
710 #ifdef HAVE_NS
711 ns_release_object (bm->img);
712 #endif
713
714 #ifdef HAVE_PGTK
715 if (bm->pattern != NULL)
716 cairo_pattern_destroy (bm->pattern);
717 #endif
718
719 #ifdef HAVE_HAIKU
720 BBitmap_free (bm->img);
721 #endif
722
723 if (bm->file)
724 {
725 xfree (bm->file);
726 bm->file = NULL;
727 }
728 }
729
730 /* Remove reference to bitmap with id number ID. */
731
732 void
image_destroy_bitmap(struct frame * f,ptrdiff_t id)733 image_destroy_bitmap (struct frame *f, ptrdiff_t id)
734 {
735 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
736
737 if (id > 0)
738 {
739 Bitmap_Record *bm = &dpyinfo->bitmaps[id - 1];
740
741 if (--bm->refcount == 0)
742 {
743 block_input ();
744 free_bitmap_record (dpyinfo, bm);
745 unblock_input ();
746 }
747 }
748 }
749
750 /* Free all the bitmaps for the display specified by DPYINFO. */
751
752 void
image_destroy_all_bitmaps(Display_Info * dpyinfo)753 image_destroy_all_bitmaps (Display_Info *dpyinfo)
754 {
755 ptrdiff_t i;
756 Bitmap_Record *bm = dpyinfo->bitmaps;
757
758 for (i = 0; i < dpyinfo->bitmaps_last; i++, bm++)
759 if (bm->refcount > 0)
760 free_bitmap_record (dpyinfo, bm);
761
762 dpyinfo->bitmaps_last = 0;
763 }
764
765 #ifndef HAVE_XRENDER
766 /* Required for the definition of image_create_x_image_and_pixmap_1 below. */
767 typedef void Picture;
768 #endif
769
770 static bool image_create_x_image_and_pixmap_1 (struct frame *, int, int, int,
771 Emacs_Pix_Container *,
772 Emacs_Pixmap *, Picture *);
773 static void image_destroy_x_image (Emacs_Pix_Container);
774
775 #ifdef HAVE_NTGUI
776 static HDC image_get_x_image_or_dc (struct frame *, struct image *,
777 bool, HGDIOBJ *);
778 static void image_unget_x_image_or_dc (struct image *, bool,
779 HDC, HGDIOBJ);
780 #else
781 static Emacs_Pix_Container image_get_x_image (struct frame *, struct image *,
782 bool);
783 static void image_unget_x_image (struct image *, bool, Emacs_Pix_Container);
784 #define image_get_x_image_or_dc(f, img, mask_p, dummy) \
785 image_get_x_image (f, img, mask_p)
786 #define image_unget_x_image_or_dc(img, mask_p, ximg, dummy) \
787 image_unget_x_image (img, mask_p, ximg)
788 #endif
789
790 #ifdef HAVE_X_WINDOWS
791
792 #ifndef USE_CAIRO
793 static void image_sync_to_pixmaps (struct frame *, struct image *);
794 #endif /* !USE_CAIRO */
795
796 /* We are working on X-specific data structures here even with cairo.
797 So we use X-specific versions of image construction/destruction
798 functions and inline the specific case of four_corners_best. */
799
800 static bool x_create_x_image_and_pixmap (struct frame *, int, int, int,
801 XImage **, Pixmap *);
802 static void x_destroy_x_image (XImage *);
803
804 /* Create a mask of a bitmap. Note is this not a perfect mask.
805 It's nicer with some borders in this context */
806
807 void
x_create_bitmap_mask(struct frame * f,ptrdiff_t id)808 x_create_bitmap_mask (struct frame *f, ptrdiff_t id)
809 {
810 Pixmap pixmap, mask;
811 XImage *ximg, *mask_img;
812 unsigned long width, height;
813 bool result;
814 unsigned long bg UNINIT;
815 unsigned long x, y, xp, xm, yp, ym;
816 GC gc;
817
818 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
819
820 if (!(id > 0))
821 return;
822
823 pixmap = image_bitmap_pixmap (f, id);
824 width = x_bitmap_width (f, id);
825 height = x_bitmap_height (f, id);
826
827 block_input ();
828 ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
829 ~0, ZPixmap);
830
831 if (!ximg)
832 {
833 unblock_input ();
834 return;
835 }
836
837 result = x_create_x_image_and_pixmap (f, width, height, 1, &mask_img, &mask);
838
839 unblock_input ();
840 if (!result)
841 {
842 XDestroyImage (ximg);
843 return;
844 }
845
846 unsigned long corner_pixels[4];
847 corner_pixels[0] = XGetPixel (ximg, 0, 0);
848 corner_pixels[1] = XGetPixel (ximg, width - 1, 0);
849 corner_pixels[2] = XGetPixel (ximg, width - 1, height - 1);
850 corner_pixels[3] = XGetPixel (ximg, 0, height - 1);
851 int i, best_count;
852 for (i = best_count = 0; i < 4; ++i)
853 {
854 int j, n;
855
856 for (j = n = 0; j < 4; ++j)
857 if (corner_pixels[i] == corner_pixels[j])
858 ++n;
859
860 if (n > best_count)
861 bg = corner_pixels[i], best_count = n;
862 }
863
864 for (y = 0; y < ximg->height; ++y)
865 {
866 for (x = 0; x < ximg->width; ++x)
867 {
868 xp = x != ximg->width - 1 ? x + 1 : 0;
869 xm = x != 0 ? x - 1 : ximg->width - 1;
870 yp = y != ximg->height - 1 ? y + 1 : 0;
871 ym = y != 0 ? y - 1 : ximg->height - 1;
872 if (XGetPixel (ximg, x, y) == bg
873 && XGetPixel (ximg, x, yp) == bg
874 && XGetPixel (ximg, x, ym) == bg
875 && XGetPixel (ximg, xp, y) == bg
876 && XGetPixel (ximg, xp, yp) == bg
877 && XGetPixel (ximg, xp, ym) == bg
878 && XGetPixel (ximg, xm, y) == bg
879 && XGetPixel (ximg, xm, yp) == bg
880 && XGetPixel (ximg, xm, ym) == bg)
881 XPutPixel (mask_img, x, y, 0);
882 else
883 XPutPixel (mask_img, x, y, 1);
884 }
885 }
886
887 eassert (input_blocked_p ());
888 gc = XCreateGC (FRAME_X_DISPLAY (f), mask, 0, NULL);
889 XPutImage (FRAME_X_DISPLAY (f), mask, gc, mask_img, 0, 0, 0, 0,
890 width, height);
891 XFreeGC (FRAME_X_DISPLAY (f), gc);
892
893 dpyinfo->bitmaps[id - 1].have_mask = true;
894 dpyinfo->bitmaps[id - 1].mask = mask;
895
896 XDestroyImage (ximg);
897 x_destroy_x_image (mask_img);
898 }
899
900 #endif /* HAVE_X_WINDOWS */
901
902 /***********************************************************************
903 Image types
904 ***********************************************************************/
905
906 /* Each image format (JPEG, TIFF, ...) supported is described by
907 a structure of the type below. */
908
909 struct image_type
910 {
911 /* Index of a symbol uniquely identifying the image type, e.g., 'jpeg'. */
912 int type;
913
914 /* Check that SPEC is a valid image specification for the given
915 image type. Value is true if SPEC is valid. */
916 bool (*valid_p) (Lisp_Object spec);
917
918 /* Load IMG which is used on frame F from information contained in
919 IMG->spec. Value is true if successful. */
920 bool (*load_img) (struct frame *f, struct image *img);
921
922 /* Free resources of image IMG which is used on frame F. */
923 void (*free_img) (struct frame *f, struct image *img);
924
925 #ifdef WINDOWSNT
926 /* Initialization function (used for dynamic loading of image
927 libraries on Windows), or NULL if none. */
928 bool (*init) (void);
929 /* An initializer for the init field. */
930 # define IMAGE_TYPE_INIT(f) f
931 #else
932 # define IMAGE_TYPE_INIT(f)
933 #endif
934 };
935
936 /* Forward function prototypes. */
937
938 static struct image_type const *lookup_image_type (Lisp_Object);
939 static void image_laplace (struct frame *, struct image *);
940 static void image_emboss (struct frame *, struct image *);
941 static void image_build_heuristic_mask (struct frame *, struct image *,
942 Lisp_Object);
943
944 static void
add_image_type(Lisp_Object type)945 add_image_type (Lisp_Object type)
946 {
947 Vimage_types = Fcons (type, Vimage_types);
948 }
949
950
951 /* Value is true if OBJECT is a valid Lisp image specification. A
952 valid image specification is a list whose car is the symbol
953 `image', and whose rest is a property list. The property list must
954 contain a value for key `:type'. That value must be the name of a
955 supported image type. The rest of the property list depends on the
956 image type. */
957
958 bool
valid_image_p(Lisp_Object object)959 valid_image_p (Lisp_Object object)
960 {
961 if (IMAGEP (object))
962 {
963 Lisp_Object tail = XCDR (object);
964 FOR_EACH_TAIL_SAFE (tail)
965 {
966 if (EQ (XCAR (tail), QCtype))
967 {
968 tail = XCDR (tail);
969 if (CONSP (tail))
970 {
971 struct image_type const *type =
972 lookup_image_type (XCAR (tail));
973 if (type)
974 return type->valid_p (object);
975 }
976 break;
977 }
978 tail = XCDR (tail);
979 if (! CONSP (tail))
980 return false;
981 }
982 }
983
984 return false;
985 }
986
987 /* Log error message with format string FORMAT and trailing arguments.
988 Signaling an error, e.g. when an image cannot be loaded, is not a
989 good idea because this would interrupt redisplay, and the error
990 message display would lead to another redisplay. This function
991 therefore simply displays a message. */
992
993 static void
image_error(const char * format,...)994 image_error (const char *format, ...)
995 {
996 va_list ap;
997 va_start (ap, format);
998 vadd_to_log (format, ap);
999 va_end (ap);
1000 }
1001
1002 static void
image_size_error(void)1003 image_size_error (void)
1004 {
1005 image_error ("Invalid image size (see `max-image-size')");
1006 }
1007
1008
1009 /***********************************************************************
1010 Image specifications
1011 ***********************************************************************/
1012
1013 enum image_value_type
1014 {
1015 IMAGE_DONT_CHECK_VALUE_TYPE,
1016 IMAGE_STRING_VALUE,
1017 IMAGE_STRING_OR_NIL_VALUE,
1018 IMAGE_SYMBOL_VALUE,
1019 IMAGE_POSITIVE_INTEGER_VALUE,
1020 IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR,
1021 IMAGE_NON_NEGATIVE_INTEGER_VALUE,
1022 IMAGE_ASCENT_VALUE,
1023 IMAGE_INTEGER_VALUE,
1024 IMAGE_FUNCTION_VALUE,
1025 IMAGE_NUMBER_VALUE,
1026 IMAGE_BOOL_VALUE
1027 };
1028
1029 /* Structure used when parsing image specifications. */
1030
1031 struct image_keyword
1032 {
1033 /* Name of keyword. */
1034 const char *name;
1035
1036 /* The type of value allowed. */
1037 enum image_value_type type;
1038
1039 /* True means key must be present. */
1040 bool mandatory_p;
1041
1042 /* Used to recognize duplicate keywords in a property list. */
1043 bool count;
1044
1045 /* The value that was found. */
1046 Lisp_Object value;
1047 };
1048
1049
1050 /* Parse image spec SPEC according to KEYWORDS. A valid image spec
1051 has the format (image KEYWORD VALUE ...). One of the keyword/
1052 value pairs must be `:type TYPE'. KEYWORDS is a vector of
1053 image_keywords structures of size NKEYWORDS describing other
1054 allowed keyword/value pairs. Value is true if SPEC is valid. */
1055
1056 static bool
parse_image_spec(Lisp_Object spec,struct image_keyword * keywords,int nkeywords,Lisp_Object type)1057 parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
1058 int nkeywords, Lisp_Object type)
1059 {
1060 int i;
1061 Lisp_Object plist;
1062
1063 if (!IMAGEP (spec))
1064 return false;
1065
1066 plist = XCDR (spec);
1067 FOR_EACH_TAIL_SAFE (plist)
1068 {
1069 Lisp_Object key, value;
1070
1071 /* First element of a pair must be a symbol. */
1072 key = XCAR (plist);
1073 plist = XCDR (plist);
1074 if (!SYMBOLP (key))
1075 return false;
1076
1077 /* There must follow a value. */
1078 if (!CONSP (plist))
1079 return false;
1080 value = XCAR (plist);
1081
1082 /* Find key in KEYWORDS. Error if not found. */
1083 for (i = 0; i < nkeywords; ++i)
1084 if (strcmp (keywords[i].name, SSDATA (SYMBOL_NAME (key))) == 0)
1085 break;
1086
1087 if (i == nkeywords)
1088 goto maybe_done;
1089
1090 /* Record that we recognized the keyword. If a keyword
1091 was found more than once, it's an error. */
1092 keywords[i].value = value;
1093 if (keywords[i].count)
1094 return false;
1095 keywords[i].count = true;
1096
1097 /* Check type of value against allowed type. */
1098 switch (keywords[i].type)
1099 {
1100 case IMAGE_STRING_VALUE:
1101 if (!STRINGP (value))
1102 return false;
1103 break;
1104
1105 case IMAGE_STRING_OR_NIL_VALUE:
1106 if (!STRINGP (value) && !NILP (value))
1107 return false;
1108 break;
1109
1110 case IMAGE_SYMBOL_VALUE:
1111 if (!SYMBOLP (value))
1112 return false;
1113 break;
1114
1115 case IMAGE_POSITIVE_INTEGER_VALUE:
1116 if (! RANGED_FIXNUMP (1, value, INT_MAX))
1117 return false;
1118 break;
1119
1120 case IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR:
1121 if (RANGED_FIXNUMP (0, value, INT_MAX))
1122 break;
1123 if (CONSP (value)
1124 && RANGED_FIXNUMP (0, XCAR (value), INT_MAX)
1125 && RANGED_FIXNUMP (0, XCDR (value), INT_MAX))
1126 break;
1127 return false;
1128
1129 case IMAGE_ASCENT_VALUE:
1130 if (SYMBOLP (value) && EQ (value, Qcenter))
1131 break;
1132 else if (RANGED_FIXNUMP (0, value, 100))
1133 break;
1134 return false;
1135
1136 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
1137 /* Unlike the other integer-related cases, this one does not
1138 verify that VALUE fits in 'int'. This is because callers
1139 want EMACS_INT. */
1140 if (!FIXNUMP (value) || XFIXNUM (value) < 0)
1141 return false;
1142 break;
1143
1144 case IMAGE_DONT_CHECK_VALUE_TYPE:
1145 break;
1146
1147 case IMAGE_FUNCTION_VALUE:
1148 value = indirect_function (value);
1149 if (FUNCTIONP (value))
1150 break;
1151 return false;
1152
1153 case IMAGE_NUMBER_VALUE:
1154 if (! NUMBERP (value))
1155 return false;
1156 break;
1157
1158 case IMAGE_INTEGER_VALUE:
1159 if (! TYPE_RANGED_FIXNUMP (int, value))
1160 return false;
1161 break;
1162
1163 case IMAGE_BOOL_VALUE:
1164 if (!NILP (value) && !EQ (value, Qt))
1165 return false;
1166 break;
1167
1168 default:
1169 emacs_abort ();
1170 break;
1171 }
1172
1173 if (EQ (key, QCtype)
1174 && !(EQ (type, value) || EQ (type, Qnative_image)))
1175 return false;
1176
1177 maybe_done:
1178 if (EQ (XCDR (plist), Qnil))
1179 {
1180 /* Check that all mandatory fields are present. */
1181 for (i = 0; i < nkeywords; ++i)
1182 if (keywords[i].mandatory_p && keywords[i].count == 0)
1183 return false;
1184
1185 return true;
1186 }
1187 }
1188
1189 return false;
1190 }
1191
1192
1193 /* Return the value of KEY in image specification SPEC. Value is nil
1194 if KEY is not present in SPEC. Set *FOUND depending on whether KEY
1195 was found in SPEC. */
1196
1197 static Lisp_Object
image_spec_value(Lisp_Object spec,Lisp_Object key,bool * found)1198 image_spec_value (Lisp_Object spec, Lisp_Object key, bool *found)
1199 {
1200 Lisp_Object tail;
1201
1202 eassert (valid_image_p (spec));
1203
1204 tail = XCDR (spec);
1205 FOR_EACH_TAIL_SAFE (tail)
1206 {
1207 if (EQ (XCAR (tail), key))
1208 {
1209 if (found)
1210 *found = 1;
1211 return XCAR (XCDR (tail));
1212 }
1213 tail = XCDR (tail);
1214 if (! CONSP (tail))
1215 break;
1216 }
1217
1218 if (found)
1219 *found = 0;
1220 return Qnil;
1221 }
1222
1223
1224 DEFUN ("image-size", Fimage_size, Simage_size, 1, 3, 0,
1225 doc: /* Return the size of image SPEC as pair (WIDTH . HEIGHT).
1226 PIXELS non-nil means return the size in pixels, otherwise return the
1227 size in canonical character units.
1228
1229 FRAME is the frame on which the image will be displayed. FRAME nil
1230 or omitted means use the selected frame.
1231
1232 Calling this function will result in the image being stored in the
1233 image cache. If this is not desirable, call `image-flush' after
1234 calling this function. */)
1235 (Lisp_Object spec, Lisp_Object pixels, Lisp_Object frame)
1236 {
1237 Lisp_Object size;
1238
1239 size = Qnil;
1240 if (valid_image_p (spec))
1241 {
1242 struct frame *f = decode_window_system_frame (frame);
1243 ptrdiff_t id = lookup_image (f, spec, -1);
1244 struct image *img = IMAGE_FROM_ID (f, id);
1245 int width = img->width + 2 * img->hmargin;
1246 int height = img->height + 2 * img->vmargin;
1247
1248 if (NILP (pixels))
1249 size = Fcons (make_float ((double) width / FRAME_COLUMN_WIDTH (f)),
1250 make_float ((double) height / FRAME_LINE_HEIGHT (f)));
1251 else
1252 size = Fcons (make_fixnum (width), make_fixnum (height));
1253 }
1254 else
1255 error ("Invalid image specification");
1256
1257 return size;
1258 }
1259
1260
1261 DEFUN ("image-mask-p", Fimage_mask_p, Simage_mask_p, 1, 2, 0,
1262 doc: /* Return t if image SPEC has a mask bitmap.
1263 FRAME is the frame on which the image will be displayed. FRAME nil
1264 or omitted means use the selected frame. */)
1265 (Lisp_Object spec, Lisp_Object frame)
1266 {
1267 Lisp_Object mask;
1268
1269 mask = Qnil;
1270 if (valid_image_p (spec))
1271 {
1272 struct frame *f = decode_window_system_frame (frame);
1273 ptrdiff_t id = lookup_image (f, spec, -1);
1274 struct image *img = IMAGE_FROM_ID (f, id);
1275 if (img->mask)
1276 mask = Qt;
1277 }
1278 else
1279 error ("Invalid image specification");
1280
1281 return mask;
1282 }
1283
1284 DEFUN ("image-metadata", Fimage_metadata, Simage_metadata, 1, 2, 0,
1285 doc: /* Return metadata for image SPEC.
1286 FRAME is the frame on which the image will be displayed. FRAME nil
1287 or omitted means use the selected frame. */)
1288 (Lisp_Object spec, Lisp_Object frame)
1289 {
1290 Lisp_Object ext;
1291
1292 ext = Qnil;
1293 if (valid_image_p (spec))
1294 {
1295 struct frame *f = decode_window_system_frame (frame);
1296 ptrdiff_t id = lookup_image (f, spec, -1);
1297 struct image *img = IMAGE_FROM_ID (f, id);
1298 ext = img->lisp_data;
1299 }
1300
1301 return ext;
1302 }
1303
1304
1305 /***********************************************************************
1306 Image type independent image structures
1307 ***********************************************************************/
1308
1309 #define MAX_IMAGE_SIZE 10.0
1310 /* Allocate and return a new image structure for image specification
1311 SPEC. SPEC has a hash value of HASH. */
1312
1313 static struct image *
make_image(Lisp_Object spec,EMACS_UINT hash)1314 make_image (Lisp_Object spec, EMACS_UINT hash)
1315 {
1316 struct image *img = xzalloc (sizeof *img);
1317 Lisp_Object file = image_spec_value (spec, QCfile, NULL);
1318
1319 eassert (valid_image_p (spec));
1320 img->dependencies = NILP (file) ? Qnil : list1 (file);
1321 img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL));
1322 eassert (img->type != NULL);
1323 img->spec = spec;
1324 img->lisp_data = Qnil;
1325 img->ascent = DEFAULT_IMAGE_ASCENT;
1326 img->hash = hash;
1327 img->corners[BOT_CORNER] = -1; /* Full image */
1328 return img;
1329 }
1330
1331
1332 /* Free image IMG which was used on frame F, including its resources. */
1333
1334 static void
free_image(struct frame * f,struct image * img)1335 free_image (struct frame *f, struct image *img)
1336 {
1337 if (img)
1338 {
1339 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1340
1341 /* Remove IMG from the hash table of its cache. */
1342 if (img->prev)
1343 img->prev->next = img->next;
1344 else
1345 c->buckets[img->hash % IMAGE_CACHE_BUCKETS_SIZE] = img->next;
1346
1347 if (img->next)
1348 img->next->prev = img->prev;
1349
1350 c->images[img->id] = NULL;
1351
1352 #if !defined USE_CAIRO && defined HAVE_XRENDER
1353 if (img->picture)
1354 XRenderFreePicture (FRAME_X_DISPLAY (f), img->picture);
1355 if (img->mask_picture)
1356 XRenderFreePicture (FRAME_X_DISPLAY (f), img->mask_picture);
1357 #endif
1358
1359 /* Free resources, then free IMG. */
1360 img->type->free_img (f, img);
1361 xfree (img->face_font_family);
1362 xfree (img);
1363 }
1364 }
1365
1366 /* Return true if the given widths and heights are valid for display. */
1367
1368 static bool
check_image_size(struct frame * f,int width,int height)1369 check_image_size (struct frame *f, int width, int height)
1370 {
1371 int w, h;
1372
1373 if (width <= 0 || height <= 0)
1374 return 0;
1375
1376 if (FIXNUMP (Vmax_image_size))
1377 return (width <= XFIXNUM (Vmax_image_size)
1378 && height <= XFIXNUM (Vmax_image_size));
1379 else if (FLOATP (Vmax_image_size))
1380 {
1381 if (f != NULL)
1382 {
1383 w = FRAME_PIXEL_WIDTH (f);
1384 h = FRAME_PIXEL_HEIGHT (f);
1385 }
1386 else
1387 w = h = 1024; /* Arbitrary size for unknown frame. */
1388 return (width <= XFLOAT_DATA (Vmax_image_size) * w
1389 && height <= XFLOAT_DATA (Vmax_image_size) * h);
1390 }
1391 else
1392 return 1;
1393 }
1394
1395 /* Prepare image IMG for display on frame F. Must be called before
1396 drawing an image. */
1397
1398 void
prepare_image_for_display(struct frame * f,struct image * img)1399 prepare_image_for_display (struct frame *f, struct image *img)
1400 {
1401 /* We're about to display IMG, so set its timestamp to `now'. */
1402 img->timestamp = current_timespec ();
1403
1404 /* If IMG doesn't have a pixmap yet, load it now, using the image
1405 type dependent loader function. */
1406 if (img->pixmap == NO_PIXMAP && !img->load_failed_p)
1407 img->load_failed_p = ! img->type->load_img (f, img);
1408
1409 #ifdef USE_CAIRO
1410 if (!img->load_failed_p)
1411 {
1412 block_input ();
1413 if (img->cr_data == NULL || (cairo_pattern_get_type (img->cr_data)
1414 != CAIRO_PATTERN_TYPE_SURFACE))
1415 {
1416 /* Fill in the background/background_transparent field while
1417 we have img->pixmap->data/img->mask->data. */
1418 IMAGE_BACKGROUND (img, f, img->pixmap);
1419 IMAGE_BACKGROUND_TRANSPARENT (img, f, img->mask);
1420 cr_put_image_to_cr_data (img);
1421 if (img->cr_data == NULL)
1422 {
1423 img->load_failed_p = 1;
1424 img->type->free_img (f, img);
1425 }
1426 }
1427 unblock_input ();
1428 }
1429 #elif defined HAVE_X_WINDOWS
1430 if (!img->load_failed_p)
1431 {
1432 block_input ();
1433 image_sync_to_pixmaps (f, img);
1434 unblock_input ();
1435 }
1436 #endif
1437 }
1438
1439
1440 /* Value is the number of pixels for the ascent of image IMG when
1441 drawn in face FACE. */
1442
1443 int
image_ascent(struct image * img,struct face * face,struct glyph_slice * slice)1444 image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1445 {
1446 int height;
1447 int ascent;
1448
1449 if (slice->height == img->height)
1450 height = img->height + img->vmargin;
1451 else if (slice->y == 0)
1452 height = slice->height + img->vmargin;
1453 else
1454 height = slice->height;
1455
1456 if (img->ascent == CENTERED_IMAGE_ASCENT)
1457 {
1458 if (face->font)
1459 {
1460 #ifdef HAVE_NTGUI
1461 /* W32 specific version. Why?. ++kfs */
1462 ascent = height / 2 - (FONT_DESCENT (face->font)
1463 - FONT_BASE (face->font)) / 2;
1464 #else
1465 /* This expression is arranged so that if the image can't be
1466 exactly centered, it will be moved slightly up. This is
1467 because a typical font is `top-heavy' (due to the presence
1468 uppercase letters), so the image placement should err towards
1469 being top-heavy too. It also just generally looks better. */
1470 ascent = (height + FONT_BASE (face->font)
1471 - FONT_DESCENT (face->font) + 1) / 2;
1472 #endif /* HAVE_NTGUI */
1473 }
1474 else
1475 ascent = height / 2;
1476 }
1477 else
1478 ascent = height * (img->ascent / 100.0);
1479
1480 return ascent;
1481 }
1482
1483
1484 /* Image background colors. */
1485
1486 /* Find the "best" corner color of a bitmap.
1487 On W32, PIMG is assumed to a device context with the bitmap selected. */
1488
1489 static RGB_PIXEL_COLOR
four_corners_best(Emacs_Pix_Context pimg,int * corners,unsigned long width,unsigned long height)1490 four_corners_best (Emacs_Pix_Context pimg, int *corners,
1491 unsigned long width, unsigned long height)
1492 {
1493 RGB_PIXEL_COLOR corner_pixels[4];
1494 RGB_PIXEL_COLOR best UNINIT;
1495 int i, best_count;
1496
1497 if (corners && corners[BOT_CORNER] >= 0)
1498 {
1499 /* Get the colors at the corner_pixels of pimg. */
1500 corner_pixels[0] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[TOP_CORNER]);
1501 corner_pixels[1] = GET_PIXEL (pimg, corners[RIGHT_CORNER] - 1, corners[TOP_CORNER]);
1502 corner_pixels[2] = GET_PIXEL (pimg, corners[RIGHT_CORNER] - 1, corners[BOT_CORNER] - 1);
1503 corner_pixels[3] = GET_PIXEL (pimg, corners[LEFT_CORNER], corners[BOT_CORNER] - 1);
1504 }
1505 else
1506
1507 {
1508 /* Get the colors at the corner_pixels of pimg. */
1509 corner_pixels[0] = GET_PIXEL (pimg, 0, 0);
1510 corner_pixels[1] = GET_PIXEL (pimg, width - 1, 0);
1511 corner_pixels[2] = GET_PIXEL (pimg, width - 1, height - 1);
1512 corner_pixels[3] = GET_PIXEL (pimg, 0, height - 1);
1513 }
1514 /* Choose the most frequently found color as background. */
1515 for (i = best_count = 0; i < 4; ++i)
1516 {
1517 int j, n;
1518
1519 for (j = n = 0; j < 4; ++j)
1520 if (corner_pixels[i] == corner_pixels[j])
1521 ++n;
1522
1523 if (n > best_count)
1524 best = corner_pixels[i], best_count = n;
1525 }
1526
1527 return best;
1528 }
1529
1530 /* Return the `background' field of IMG. If IMG doesn't have one yet,
1531 it is guessed heuristically. If non-zero, XIMG is an existing
1532 Emacs_Pix_Context object (device context with the image selected on
1533 W32) to use for the heuristic. */
1534
1535 RGB_PIXEL_COLOR
image_background(struct image * img,struct frame * f,Emacs_Pix_Context pimg)1536 image_background (struct image *img, struct frame *f, Emacs_Pix_Context pimg)
1537 {
1538 if (! img->background_valid)
1539 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1540 {
1541 bool free_pimg = !pimg;
1542 #ifdef HAVE_NTGUI
1543 HGDIOBJ prev;
1544 #endif /* HAVE_NTGUI */
1545
1546 if (free_pimg)
1547 pimg = image_get_x_image_or_dc (f, img, 0, &prev);
1548
1549 RGB_PIXEL_COLOR bg
1550 = four_corners_best (pimg, img->corners, img->width, img->height);
1551 #ifdef USE_CAIRO
1552 {
1553 char color_name[30];
1554 sprintf (color_name, "#%04x%04x%04x",
1555 (unsigned int) RED16_FROM_ULONG (bg),
1556 (unsigned int) GREEN16_FROM_ULONG (bg),
1557 (unsigned int) BLUE16_FROM_ULONG (bg));
1558 bg = image_alloc_image_color (f, img, build_string (color_name), 0);
1559 }
1560 #endif
1561 img->background = bg;
1562
1563 if (free_pimg)
1564 image_unget_x_image_or_dc (img, 0, pimg, prev);
1565
1566 img->background_valid = 1;
1567 }
1568
1569 return img->background;
1570 }
1571
1572 /* Return the `background_transparent' field of IMG. If IMG doesn't
1573 have one yet, it is guessed heuristically. If non-zero, MASK is an
1574 existing Emacs_Pix_Context (XImage* on X) object to use for the
1575 heuristic. */
1576
1577 int
image_background_transparent(struct image * img,struct frame * f,Emacs_Pix_Context mask)1578 image_background_transparent (struct image *img, struct frame *f,
1579 Emacs_Pix_Context mask)
1580 {
1581 if (! img->background_transparent_valid)
1582 /* IMG doesn't have a background yet, try to guess a reasonable value. */
1583 {
1584 if (img->mask)
1585 {
1586 bool free_mask = !mask;
1587 #ifdef HAVE_NTGUI
1588 HGDIOBJ prev;
1589 #endif /* HAVE_NTGUI */
1590
1591 if (free_mask)
1592 mask = image_get_x_image_or_dc (f, img, 1, &prev);
1593
1594 img->background_transparent
1595 = (four_corners_best (mask, img->corners, img->width, img->height) == PIX_MASK_RETAIN);
1596
1597 if (free_mask)
1598 image_unget_x_image_or_dc (img, 1, mask, prev);
1599 }
1600 else
1601 img->background_transparent = 0;
1602
1603 img->background_transparent_valid = 1;
1604 }
1605
1606 return img->background_transparent;
1607 }
1608
1609 /***********************************************************************
1610 Helper functions for X image types
1611 ***********************************************************************/
1612
1613 /* Clear X resources of image IMG on frame F according to FLAGS.
1614 FLAGS is bitwise-or of the following masks:
1615 CLEAR_IMAGE_PIXMAP free the pixmap if any.
1616 CLEAR_IMAGE_MASK means clear the mask pixmap if any.
1617 CLEAR_IMAGE_COLORS means free colors allocated for the image, if
1618 any. */
1619
1620 #define CLEAR_IMAGE_PIXMAP (1 << 0)
1621 #define CLEAR_IMAGE_MASK (1 << 1)
1622 #define CLEAR_IMAGE_COLORS (1 << 2)
1623
1624 static void
image_clear_image_1(struct frame * f,struct image * img,int flags)1625 image_clear_image_1 (struct frame *f, struct image *img, int flags)
1626 {
1627 if (flags & CLEAR_IMAGE_PIXMAP)
1628 {
1629 if (img->pixmap)
1630 {
1631 FRAME_TERMINAL (f)->free_pixmap (f, img->pixmap);
1632 img->pixmap = NO_PIXMAP;
1633 /* NOTE (HAVE_NS): background color is NOT an indexed color! */
1634 img->background_valid = 0;
1635 }
1636 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1637 if (img->ximg)
1638 {
1639 image_destroy_x_image (img->ximg);
1640 img->ximg = NULL;
1641 img->background_valid = 0;
1642 }
1643 #endif
1644 }
1645
1646 if (flags & CLEAR_IMAGE_MASK)
1647 {
1648 if (img->mask)
1649 {
1650 FRAME_TERMINAL (f)->free_pixmap (f, img->mask);
1651 img->mask = NO_PIXMAP;
1652 img->background_transparent_valid = 0;
1653 }
1654 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1655 if (img->mask_img)
1656 {
1657 image_destroy_x_image (img->mask_img);
1658 img->mask_img = NULL;
1659 img->background_transparent_valid = 0;
1660 }
1661 #endif
1662 }
1663
1664 if ((flags & CLEAR_IMAGE_COLORS) && img->ncolors)
1665 {
1666 /* W32_TODO: color table support. */
1667 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
1668 x_free_colors (f, img->colors, img->ncolors);
1669 #endif /* HAVE_X_WINDOWS && !USE_CAIRO */
1670 xfree (img->colors);
1671 img->colors = NULL;
1672 img->ncolors = 0;
1673 }
1674
1675 #ifdef USE_CAIRO
1676 if (img->cr_data)
1677 {
1678 cairo_pattern_destroy (img->cr_data);
1679 img->cr_data = NULL;
1680 }
1681 #endif /* USE_CAIRO */
1682 }
1683
1684 /* Free X resources of image IMG which is used on frame F. */
1685
1686 static void
image_clear_image(struct frame * f,struct image * img)1687 image_clear_image (struct frame *f, struct image *img)
1688 {
1689 block_input ();
1690 image_clear_image_1 (f, img,
1691 CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_MASK | CLEAR_IMAGE_COLORS);
1692 unblock_input ();
1693 }
1694
1695
1696 /* Allocate color COLOR_NAME for image IMG on frame F. If color
1697 cannot be allocated, use DFLT. Add a newly allocated color to
1698 IMG->colors, so that it can be freed again. Value is the pixel
1699 color. */
1700
1701 static unsigned long
image_alloc_image_color(struct frame * f,struct image * img,Lisp_Object color_name,unsigned long dflt)1702 image_alloc_image_color (struct frame *f, struct image *img,
1703 Lisp_Object color_name, unsigned long dflt)
1704 {
1705 Emacs_Color color;
1706 unsigned long result;
1707
1708 eassert (STRINGP (color_name));
1709
1710 if (FRAME_TERMINAL (f)->defined_color_hook (f,
1711 SSDATA (color_name),
1712 &color,
1713 true,
1714 false)
1715 && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
1716 INT_MAX))
1717 {
1718 /* This isn't called frequently so we get away with simply
1719 reallocating the color vector to the needed size, here. */
1720 ptrdiff_t ncolors = img->ncolors + 1;
1721 img->colors = xrealloc (img->colors, ncolors * sizeof *img->colors);
1722 img->colors[ncolors - 1] = color.pixel;
1723 img->ncolors = ncolors;
1724 result = color.pixel;
1725 }
1726 else
1727 result = dflt;
1728
1729 return result;
1730 }
1731
1732
1733
1734 /***********************************************************************
1735 Image Cache
1736 ***********************************************************************/
1737
1738 static void cache_image (struct frame *f, struct image *img);
1739
1740 /* Return a new, initialized image cache that is allocated from the
1741 heap. Call free_image_cache to free an image cache. */
1742
1743 struct image_cache *
make_image_cache(void)1744 make_image_cache (void)
1745 {
1746 struct image_cache *c = xmalloc (sizeof *c);
1747
1748 c->size = 50;
1749 c->used = c->refcount = 0;
1750 c->images = xmalloc (c->size * sizeof *c->images);
1751 c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets);
1752 return c;
1753 }
1754
1755 /* Find an image matching SPEC in the cache, and return it. If no
1756 image is found, return NULL. */
1757 static struct image *
search_image_cache(struct frame * f,Lisp_Object spec,EMACS_UINT hash,unsigned long foreground,unsigned long background,int font_size,char * font_family,bool ignore_colors)1758 search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
1759 unsigned long foreground, unsigned long background,
1760 int font_size, char *font_family, bool ignore_colors)
1761 {
1762 struct image *img;
1763 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1764 int i = hash % IMAGE_CACHE_BUCKETS_SIZE;
1765
1766 if (!c) return NULL;
1767
1768 /* If the image spec does not specify a background color, the cached
1769 image must have the same background color as the current frame.
1770 The foreground color must also match, for the sake of monochrome
1771 images.
1772
1773 In fact, we could ignore the foreground color matching condition
1774 for color images, or if the image spec specifies :foreground;
1775 similarly we could ignore the background color matching condition
1776 for formats that don't use transparency (such as jpeg), or if the
1777 image spec specifies :background. However, the extra memory
1778 usage is probably negligible in practice, so we don't bother. */
1779
1780 for (img = c->buckets[i]; img; img = img->next)
1781 if (img->hash == hash
1782 && !NILP (Fequal (img->spec, spec))
1783 && (ignore_colors || (img->face_foreground == foreground
1784 && img->face_background == background
1785 && img->face_font_size == font_size
1786 && (font_family
1787 &&!strcmp (font_family, img->face_font_family)))))
1788 break;
1789 return img;
1790 }
1791
1792
1793 /* Search frame F for an image with spec SPEC, and free it. */
1794
1795 static void
uncache_image(struct frame * f,Lisp_Object spec)1796 uncache_image (struct frame *f, Lisp_Object spec)
1797 {
1798 struct image *img;
1799 EMACS_UINT hash = sxhash (spec);
1800
1801 /* Because the background colors are based on the current face, we
1802 can have multiple copies of an image with the same spec. We want
1803 to remove them all to ensure the user doesn't see an old version
1804 of the image when the face changes. */
1805 while ((img = search_image_cache (f, spec, hash, 0, 0, 0, NULL, true)))
1806 {
1807 free_image (f, img);
1808 /* As display glyphs may still be referring to the image ID, we
1809 must garbage the frame (Bug#6426). */
1810 SET_FRAME_GARBAGED (f);
1811 }
1812 }
1813
1814
1815 /* Free image cache of frame F. Be aware that X frames share images
1816 caches. */
1817
1818 void
free_image_cache(struct frame * f)1819 free_image_cache (struct frame *f)
1820 {
1821 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1822 if (c)
1823 {
1824 ptrdiff_t i;
1825
1826 /* Cache should not be referenced by any frame when freed. */
1827 eassert (c->refcount == 0);
1828
1829 for (i = 0; i < c->used; ++i)
1830 free_image (f, c->images[i]);
1831 xfree (c->images);
1832 xfree (c->buckets);
1833 xfree (c);
1834 FRAME_IMAGE_CACHE (f) = NULL;
1835 }
1836 }
1837
1838
1839 /* Clear image cache of frame F. FILTER=t means free all images.
1840 FILTER=nil means clear only images that haven't been
1841 displayed for some time.
1842 Else, only free the images which have FILTER in their `dependencies'.
1843 Should be called from time to time to reduce the number of loaded images.
1844 If image-cache-eviction-delay is non-nil, this frees images in the cache
1845 which weren't displayed for at least that many seconds. */
1846
1847 static void
clear_image_cache(struct frame * f,Lisp_Object filter)1848 clear_image_cache (struct frame *f, Lisp_Object filter)
1849 {
1850 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1851
1852 if (c && !f->inhibit_clear_image_cache)
1853 {
1854 ptrdiff_t i, nfreed = 0;
1855
1856 /* Block input so that we won't be interrupted by a SIGIO
1857 while being in an inconsistent state. */
1858 block_input ();
1859
1860 if (!NILP (filter))
1861 {
1862 /* Filter image cache. */
1863 for (i = 0; i < c->used; ++i)
1864 {
1865 struct image *img = c->images[i];
1866 if (img && (EQ (Qt, filter)
1867 || !NILP (Fmember (filter, img->dependencies))))
1868 {
1869 free_image (f, img);
1870 ++nfreed;
1871 }
1872 }
1873 }
1874 else if (FIXNUMP (Vimage_cache_eviction_delay))
1875 {
1876 /* Free cache based on timestamp. */
1877 struct timespec old, t;
1878 double delay;
1879 ptrdiff_t nimages = 0;
1880
1881 for (i = 0; i < c->used; ++i)
1882 if (c->images[i])
1883 nimages++;
1884
1885 /* If the number of cached images has grown unusually large,
1886 decrease the cache eviction delay (Bug#6230). */
1887 delay = XFIXNUM (Vimage_cache_eviction_delay);
1888 if (nimages > 40)
1889 delay = 1600 * delay / nimages / nimages;
1890 delay = max (delay, 1);
1891
1892 t = current_timespec ();
1893 old = timespec_sub (t, dtotimespec (delay));
1894
1895 for (i = 0; i < c->used; ++i)
1896 {
1897 struct image *img = c->images[i];
1898 if (img && timespec_cmp (img->timestamp, old) < 0)
1899 {
1900 free_image (f, img);
1901 ++nfreed;
1902 }
1903 }
1904 }
1905
1906 /* We may be clearing the image cache because, for example,
1907 Emacs was iconified for a longer period of time. In that
1908 case, current matrices may still contain references to
1909 images freed above. So, clear these matrices. */
1910 if (nfreed)
1911 {
1912 Lisp_Object tail, frame;
1913
1914 FOR_EACH_FRAME (tail, frame)
1915 {
1916 struct frame *fr = XFRAME (frame);
1917 if (FRAME_IMAGE_CACHE (fr) == c)
1918 clear_current_matrices (fr);
1919 }
1920
1921 windows_or_buffers_changed = 19;
1922 }
1923
1924 unblock_input ();
1925 }
1926 }
1927
1928 void
clear_image_caches(Lisp_Object filter)1929 clear_image_caches (Lisp_Object filter)
1930 {
1931 /* FIXME: We want to do
1932 * struct terminal *t;
1933 * for (t = terminal_list; t; t = t->next_terminal)
1934 * clear_image_cache (t, filter); */
1935 Lisp_Object tail, frame;
1936 FOR_EACH_FRAME (tail, frame)
1937 if (FRAME_WINDOW_P (XFRAME (frame)))
1938 clear_image_cache (XFRAME (frame), filter);
1939 }
1940
1941 DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache,
1942 0, 1, 0,
1943 doc: /* Clear the image cache.
1944 FILTER nil or a frame means clear all images in the selected frame.
1945 FILTER t means clear the image caches of all frames.
1946 Anything else means clear only those images that refer to FILTER,
1947 which is then usually a filename. */)
1948 (Lisp_Object filter)
1949 {
1950 if (! (NILP (filter) || FRAMEP (filter)))
1951 clear_image_caches (filter);
1952 else
1953 clear_image_cache (decode_window_system_frame (filter), Qt);
1954
1955 return Qnil;
1956 }
1957
1958 static size_t
image_size_in_bytes(struct image * img)1959 image_size_in_bytes (struct image *img)
1960 {
1961 size_t size = 0;
1962
1963 #if defined USE_CAIRO
1964 Emacs_Pixmap pm = img->pixmap;
1965 if (pm)
1966 size += pm->height * pm->bytes_per_line;
1967 Emacs_Pixmap msk = img->mask;
1968 if (msk)
1969 size += msk->height * msk->bytes_per_line;
1970
1971 #elif defined HAVE_X_WINDOWS
1972 /* Use a nominal depth of 24 bpp for pixmap and 1 bpp for mask,
1973 to avoid having to query the server. */
1974 if (img->pixmap != NO_PIXMAP)
1975 size += img->width * img->height * 3;
1976 if (img->mask != NO_PIXMAP)
1977 size += img->width * img->height / 8;
1978
1979 if (img->ximg && img->ximg->data)
1980 size += img->ximg->bytes_per_line * img->ximg->height;
1981 if (img->mask_img && img->mask_img->data)
1982 size += img->mask_img->bytes_per_line * img->mask_img->height;
1983
1984 #elif defined HAVE_NS
1985 if (img->pixmap)
1986 size += ns_image_size_in_bytes (img->pixmap);
1987 if (img->mask)
1988 size += ns_image_size_in_bytes (img->mask);
1989
1990 #elif defined HAVE_NTGUI
1991 if (img->pixmap)
1992 size += w32_image_size (img->pixmap);
1993 if (img->mask)
1994 size += w32_image_size (img->mask);
1995
1996 #elif defined HAVE_HAIKU
1997 if (img->pixmap)
1998 size += BBitmap_bytes_length (img->pixmap);
1999 if (img->mask)
2000 size += BBitmap_bytes_length (img->mask);
2001 #endif
2002
2003 return size;
2004 }
2005
2006 static size_t
image_frame_cache_size(struct frame * f)2007 image_frame_cache_size (struct frame *f)
2008 {
2009 struct image_cache *c = FRAME_IMAGE_CACHE (f);
2010 if (!c)
2011 return 0;
2012
2013 size_t total = 0;
2014 for (ptrdiff_t i = 0; i < c->used; ++i)
2015 {
2016 struct image *img = c->images[i];
2017 total += img ? image_size_in_bytes (img) : 0;
2018 }
2019 return total;
2020 }
2021
2022 DEFUN ("image-cache-size", Fimage_cache_size, Simage_cache_size, 0, 0, 0,
2023 doc: /* Return the size of the image cache. */)
2024 (void)
2025 {
2026 Lisp_Object tail, frame;
2027 size_t total = 0;
2028
2029 FOR_EACH_FRAME (tail, frame)
2030 if (FRAME_WINDOW_P (XFRAME (frame)))
2031 total += image_frame_cache_size (XFRAME (frame));
2032
2033 return make_int (total);
2034 }
2035
2036
2037 DEFUN ("image-flush", Fimage_flush, Simage_flush,
2038 1, 2, 0,
2039 doc: /* Flush the image with specification SPEC on frame FRAME.
2040 This removes the image from the Emacs image cache. If SPEC specifies
2041 an image file, the next redisplay of this image will read from the
2042 current contents of that file.
2043
2044 FRAME nil or omitted means use the selected frame.
2045 FRAME t means refresh the image on all frames. */)
2046 (Lisp_Object spec, Lisp_Object frame)
2047 {
2048 if (!valid_image_p (spec))
2049 error ("Invalid image specification");
2050
2051 if (EQ (frame, Qt))
2052 {
2053 Lisp_Object tail;
FOR_EACH_FRAME(tail,frame)2054 FOR_EACH_FRAME (tail, frame)
2055 {
2056 struct frame *f = XFRAME (frame);
2057 if (FRAME_WINDOW_P (f))
2058 uncache_image (f, spec);
2059 }
2060 }
2061 else
2062 uncache_image (decode_window_system_frame (frame), spec);
2063
2064 return Qnil;
2065 }
2066
2067
2068 /* Compute masks and transform image IMG on frame F, as specified
2069 by the image's specification, */
2070
2071 static void
postprocess_image(struct frame * f,struct image * img)2072 postprocess_image (struct frame *f, struct image *img)
2073 {
2074 /* Manipulation of the image's mask. */
2075 if (img->pixmap)
2076 {
2077 Lisp_Object conversion, spec;
2078 Lisp_Object mask;
2079
2080 spec = img->spec;
2081
2082 /* `:heuristic-mask t'
2083 `:mask heuristic'
2084 means build a mask heuristically.
2085 `:heuristic-mask (R G B)'
2086 `:mask (heuristic (R G B))'
2087 means build a mask from color (R G B) in the
2088 image.
2089 `:mask nil'
2090 means remove a mask, if any. */
2091
2092 mask = image_spec_value (spec, QCheuristic_mask, NULL);
2093 if (!NILP (mask))
2094 image_build_heuristic_mask (f, img, mask);
2095 else
2096 {
2097 bool found_p;
2098
2099 mask = image_spec_value (spec, QCmask, &found_p);
2100
2101 if (EQ (mask, Qheuristic))
2102 image_build_heuristic_mask (f, img, Qt);
2103 else if (CONSP (mask)
2104 && EQ (XCAR (mask), Qheuristic))
2105 {
2106 if (CONSP (XCDR (mask)))
2107 image_build_heuristic_mask (f, img, XCAR (XCDR (mask)));
2108 else
2109 image_build_heuristic_mask (f, img, XCDR (mask));
2110 }
2111 else if (NILP (mask) && found_p && img->mask)
2112 image_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
2113 }
2114
2115
2116 /* Should we apply an image transformation algorithm? */
2117 conversion = image_spec_value (spec, QCconversion, NULL);
2118 if (EQ (conversion, Qdisabled))
2119 image_disable_image (f, img);
2120 else if (EQ (conversion, Qlaplace))
2121 image_laplace (f, img);
2122 else if (EQ (conversion, Qemboss))
2123 image_emboss (f, img);
2124 else if (CONSP (conversion)
2125 && EQ (XCAR (conversion), Qedge_detection))
2126 {
2127 Lisp_Object tem;
2128 tem = XCDR (conversion);
2129 if (CONSP (tem))
2130 image_edge_detection (f, img,
2131 Fplist_get (tem, QCmatrix),
2132 Fplist_get (tem, QCcolor_adjustment));
2133 }
2134 }
2135 }
2136
2137 #if defined (HAVE_IMAGEMAGICK) || defined (HAVE_NATIVE_TRANSFORMS)
2138 /* Scale an image size by returning SIZE / DIVISOR * MULTIPLIER,
2139 safely rounded and clipped to int range. */
2140
2141 static int
scale_image_size(int size,double divisor,double multiplier)2142 scale_image_size (int size, double divisor, double multiplier)
2143 {
2144 if (divisor != 0)
2145 {
2146 double scaled = size * multiplier / divisor;
2147 if (scaled < INT_MAX)
2148 {
2149 /* Use ceil, as rounding can discard fractional SVG pixels. */
2150 return ceil (scaled);
2151 }
2152 }
2153 return INT_MAX;
2154 }
2155
2156 /* Return a size, in pixels, from the value specified by SYMBOL, which
2157 may be an integer or a pair of the form (VALUE . 'em) where VALUE
2158 is a float that is multiplied by the font size to get the final
2159 dimension.
2160
2161 If the value doesn't exist in the image spec, or is invalid, return
2162 -1.
2163 */
2164 static int
image_get_dimension(struct image * img,Lisp_Object symbol)2165 image_get_dimension (struct image *img, Lisp_Object symbol)
2166 {
2167 Lisp_Object value = image_spec_value (img->spec, symbol, NULL);
2168
2169 if (FIXNATP (value))
2170 return min (XFIXNAT (value), INT_MAX);
2171 if (CONSP (value) && NUMBERP (CAR (value)) && EQ (Qem, CDR (value)))
2172 return scale_image_size (img->face_font_size, 1, XFLOATINT (CAR (value)));
2173
2174 return -1;
2175 }
2176
2177 /* Compute the desired size of an image with native size WIDTH x HEIGHT.
2178 Use IMG to deduce the size. Store the desired size into
2179 *D_WIDTH x *D_HEIGHT. Store -1 x -1 if the native size is OK. */
2180 static void
compute_image_size(double width,double height,struct image * img,int * d_width,int * d_height)2181 compute_image_size (double width, double height,
2182 struct image *img,
2183 int *d_width, int *d_height)
2184 {
2185 double scale = 1;
2186 Lisp_Object value = image_spec_value (img->spec, QCscale, NULL);
2187 if (NUMBERP (value))
2188 {
2189 double dval = XFLOATINT (value);
2190 if (0 <= dval)
2191 scale = dval;
2192 }
2193
2194 /* If width and/or height is set in the display spec assume we want
2195 to scale to those values. If either h or w is unspecified, the
2196 unspecified should be calculated from the specified to preserve
2197 aspect ratio. */
2198 int desired_width = image_get_dimension (img, QCwidth), max_width;
2199 if (desired_width < 0)
2200 max_width = image_get_dimension (img, QCmax_width);
2201 else
2202 {
2203 desired_width = scale_image_size (desired_width, 1, scale);
2204 /* :width overrides :max-width. */
2205 max_width = -1;
2206 }
2207
2208 int desired_height = image_get_dimension (img, QCheight), max_height;
2209 if (desired_height < 0)
2210 max_height = image_get_dimension (img, QCmax_height);
2211 else
2212 {
2213 desired_height = scale_image_size (desired_height, 1, scale);
2214 /* :height overrides :max-height. */
2215 max_height = -1;
2216 }
2217
2218 /* If we have both width/height set explicitly, we skip past all the
2219 aspect ratio-preserving computations below. */
2220 if (0 <= desired_width && 0 <= desired_height)
2221 goto out;
2222
2223 if (0 <= desired_width)
2224 /* Width known, calculate height. */
2225 desired_height = scale_image_size (desired_width, width, height);
2226 else if (0 <= desired_height)
2227 /* Height known, calculate width. */
2228 desired_width = scale_image_size (desired_height, height, width);
2229 else
2230 {
2231 desired_width = scale_image_size (width, 1, scale);
2232 desired_height = scale_image_size (height, 1, scale);
2233 }
2234
2235 if (0 <= max_width && max_width < desired_width)
2236 {
2237 /* The image is wider than :max-width. */
2238 desired_width = max_width;
2239 desired_height = scale_image_size (desired_width, width, height);
2240 }
2241
2242 if (0 <= max_height && max_height < desired_height)
2243 {
2244 /* The image is higher than :max-height. */
2245 desired_height = max_height;
2246 desired_width = scale_image_size (desired_height, height, width);
2247 }
2248
2249 out:
2250 *d_width = desired_width;
2251 *d_height = desired_height;
2252 }
2253
2254 /* image_set_rotation and image_set_transform use affine
2255 transformation matrices to perform various transforms on the image.
2256 The matrix is a 2D array of doubles. It is laid out like this:
2257
2258 m[0][0] = m11 | m[1][0] = m12 | m[2][0] = tx
2259 --------------+---------------+-------------
2260 m[0][1] = m21 | m[1][1] = m22 | m[2][1] = ty
2261 --------------+---------------+-------------
2262 m[0][2] = 0 | m[1][2] = 0 | m[2][2] = 1
2263
2264 tx and ty represent translations, m11 and m22 represent scaling
2265 transforms and m21 and m12 represent shear transforms. Most
2266 graphics toolkits don't require the third row, however it is
2267 necessary for multiplication.
2268
2269 Transforms are done by creating a matrix for each action we wish to
2270 take, then multiplying the transformation matrix by each of those
2271 matrices in order (matrix multiplication is not commutative).
2272 After we've done that we can use our modified transformation matrix
2273 to transform points. We take the x and y coordinates and convert
2274 them into a 3x1 matrix and multiply that by the transformation
2275 matrix and it gives us a new, transformed, set of coordinates:
2276
2277 [m11 m12 tx] [x] [m11*x+m12*y+tx*1] [x']
2278 [m21 m22 ty] X [y] = [m21*x+m22*y+ty*1] = [y']
2279 [ 0 0 1] [1] [ 0*x+0*y+1*1] [ 1]
2280
2281 We don't have to worry about the last step as the graphics toolkit
2282 will do it for us.
2283
2284 The three transforms we are concerned with are translation, scaling
2285 and rotation. The translation matrix looks like this:
2286
2287 [1 0 tx]
2288 [0 1 ty]
2289 [0 0 1]
2290
2291 Where tx and ty are the amount to translate the origin in the x and
2292 y coordinates, respectively. Since we are translating the origin
2293 and not the image data itself, it can appear backwards in use, for
2294 example to move the image 10 pixels to the right, you would set tx
2295 to -10.
2296
2297 To scale we use:
2298
2299 [x 0 0]
2300 [0 y 0]
2301 [0 0 1]
2302
2303 Where x and y are the amounts to scale in the x and y dimensions.
2304 Values smaller than 1 make the image larger, values larger than 1
2305 make it smaller. Negative values flip the image. For example to
2306 double the image size set x and y to 0.5.
2307
2308 To rotate we use:
2309
2310 [ cos(r) sin(r) 0]
2311 [-sin(r) cos(r) 0]
2312 [ 0 0 1]
2313
2314 Where r is the angle of rotation required. Rotation occurs around
2315 the origin, not the center of the image. Note that this is
2316 normally considered a counter-clockwise rotation, however because
2317 our y axis is reversed, (0, 0) at the top left, it works as a
2318 clockwise rotation.
2319
2320 The full process of rotating an image is to move the origin to the
2321 center of the image (width/2, height/2), perform the rotation, and
2322 finally move the origin back to the top left of the image, which
2323 may now be a different corner.
2324
2325 Note that different GUI backends (X, Cairo, w32, NS) want the
2326 transform matrix defined as transform from the original image to
2327 the transformed image, while others want the matrix to describe the
2328 transform of the space, which boils down to inverting the matrix.
2329
2330 It's possible to pre-calculate the matrix multiplications and just
2331 generate one transform matrix that will do everything we need in a
2332 single step, but the maths for each element is much more complex
2333 and performing the steps separately makes for more readable code. */
2334
2335 #ifndef HAVE_HAIKU
2336 typedef double matrix3x3[3][3];
2337
2338 static void
matrix3x3_mult(matrix3x3 a,matrix3x3 b,matrix3x3 result)2339 matrix3x3_mult (matrix3x3 a, matrix3x3 b, matrix3x3 result)
2340 {
2341 for (int i = 0; i < 3; i++)
2342 for (int j = 0; j < 3; j++)
2343 {
2344 double sum = 0;
2345 for (int k = 0; k < 3; k++)
2346 sum += a[i][k] * b[k][j];
2347 result[i][j] = sum;
2348 }
2349 }
2350 #endif /* not HAVE_HAIKU */
2351
2352 static void
compute_image_rotation(struct image * img,double * rotation)2353 compute_image_rotation (struct image *img, double *rotation)
2354 {
2355 bool foundp = false;
2356 Lisp_Object value = image_spec_value (img->spec, QCrotation, &foundp);
2357 if (!foundp)
2358 return;
2359 if (! NUMBERP (value))
2360 {
2361 image_error ("Invalid image `:rotation' parameter");
2362 return;
2363 }
2364
2365 Lisp_Object reduced_angle = Fmod (value, make_fixnum (360));
2366 if (FLOATP (reduced_angle))
2367 *rotation = XFLOAT_DATA (reduced_angle);
2368 else
2369 *rotation = XFIXNUM (reduced_angle);
2370 }
2371
2372 static void
image_set_transform(struct frame * f,struct image * img)2373 image_set_transform (struct frame *f, struct image *img)
2374 {
2375 # if (defined HAVE_IMAGEMAGICK \
2376 && !defined DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE)
2377 /* ImageMagick images already have the correct transform. */
2378 if (EQ (image_spec_value (img->spec, QCtype, NULL), Qimagemagick))
2379 return;
2380 # endif
2381
2382 # if !defined USE_CAIRO && defined HAVE_XRENDER
2383 if (!img->picture)
2384 return;
2385
2386 /* Store the original dimensions as we'll overwrite them later. */
2387 img->original_width = img->width;
2388 img->original_height = img->height;
2389 # endif
2390
2391 /* Determine size. */
2392 int width, height;
2393
2394 #ifdef HAVE_RSVG
2395 /* SVGs are pre-scaled to the correct size. */
2396 if (EQ (image_spec_value (img->spec, QCtype, NULL), Qsvg))
2397 {
2398 width = img->width / FRAME_SCALE_FACTOR (f);
2399 height = img->height / FRAME_SCALE_FACTOR (f);
2400 }
2401 else
2402 #endif
2403 compute_image_size (img->width, img->height, img, &width, &height);
2404
2405 /* Determine rotation. */
2406 double rotation = 0.0;
2407 compute_image_rotation (img, &rotation);
2408
2409 #ifndef HAVE_HAIKU
2410 # if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
2411 /* We want scale up operations to use a nearest neighbor filter to
2412 show real pixels instead of munging them, but scale down
2413 operations to use a blended filter, to avoid aliasing and the like.
2414
2415 TODO: implement for Windows. */
2416 bool smoothing;
2417 Lisp_Object s = image_spec_value (img->spec, QCtransform_smoothing, NULL);
2418 if (NILP (s))
2419 smoothing = (width < img->width) || (height < img->height);
2420 else
2421 smoothing = !NILP (s);
2422 # endif
2423
2424 /* Perform scale transformation. */
2425
2426 matrix3x3 matrix
2427 = {
2428 # if defined USE_CAIRO || defined HAVE_XRENDER
2429 [0][0] = (!IEEE_FLOATING_POINT && width == 0 ? DBL_MAX
2430 : img->width / (double) width),
2431 [1][1] = (!IEEE_FLOATING_POINT && height == 0 ? DBL_MAX
2432 : img->height / (double) height),
2433 # elif defined HAVE_NTGUI || defined HAVE_NS
2434 [0][0] = (!IEEE_FLOATING_POINT && img->width == 0 ? DBL_MAX
2435 : width / (double) img->width),
2436 [1][1] = (!IEEE_FLOATING_POINT && img->height == 0 ? DBL_MAX
2437 : height / (double) img->height),
2438 # else
2439 [0][0] = 1, [1][1] = 1,
2440 # endif
2441 [2][2] = 1 };
2442 img->width = width;
2443 img->height = height;
2444
2445 /* Perform rotation transformation. */
2446
2447 int rotate_flag = -1;
2448 if (rotation == 0)
2449 rotate_flag = 0;
2450 else
2451 {
2452 # if (defined USE_CAIRO || defined HAVE_XRENDER \
2453 || defined HAVE_NTGUI || defined HAVE_NS)
2454 int cos_r, sin_r;
2455 if (rotation == 90)
2456 {
2457 width = img->height;
2458 height = img->width;
2459 cos_r = 0;
2460 sin_r = 1;
2461 rotate_flag = 1;
2462 }
2463 else if (rotation == 180)
2464 {
2465 cos_r = -1;
2466 sin_r = 0;
2467 rotate_flag = 1;
2468 }
2469 else if (rotation == 270)
2470 {
2471 width = img->height;
2472 height = img->width;
2473 cos_r = 0;
2474 sin_r = -1;
2475 rotate_flag = 1;
2476 }
2477
2478 if (0 < rotate_flag)
2479 {
2480 # if defined USE_CAIRO || defined HAVE_XRENDER
2481 /* 1. Translate so (0, 0) is in the center of the image. */
2482 matrix3x3 t
2483 = { [0][0] = 1,
2484 [1][1] = 1,
2485 [2][0] = img->width*.5, [2][1] = img->height*.5, [2][2] = 1 };
2486 matrix3x3 u;
2487 matrix3x3_mult (t, matrix, u);
2488
2489 /* 2. Rotate. */
2490 matrix3x3 rot = { [0][0] = cos_r, [0][1] = -sin_r,
2491 [1][0] = sin_r, [1][1] = cos_r,
2492 [2][2] = 1 };
2493 matrix3x3 v;
2494 matrix3x3_mult (rot, u, v);
2495
2496 /* 3. Translate back. */
2497 t[2][0] = width * -.5;
2498 t[2][1] = height * -.5;
2499 matrix3x3_mult (t, v, matrix);
2500 # else
2501 /* 1. Translate so (0, 0) is in the center of the image. */
2502 matrix3x3 t
2503 = { [0][0] = 1,
2504 [1][1] = 1,
2505 [2][0] = img->width*-.5, [2][1] = img->height*-.5, [2][2] = 1 };
2506 matrix3x3 u;
2507 matrix3x3_mult (matrix, t, u);
2508
2509 /* 2. Rotate. */
2510 matrix3x3 rot = { [0][0] = cos_r, [0][1] = sin_r,
2511 [1][0] = -sin_r, [1][1] = cos_r,
2512 [2][2] = 1 };
2513 matrix3x3 v;
2514 matrix3x3_mult (u, rot, v);
2515
2516 /* 3. Translate back. */
2517 t[2][0] = width * .5;
2518 t[2][1] = height * .5;
2519 matrix3x3_mult (v, t, matrix);
2520 # endif
2521 img->width = width;
2522 img->height = height;
2523 }
2524 # endif
2525 }
2526
2527 if (rotate_flag < 0)
2528 image_error ("No native support for rotation by %g degrees",
2529 make_float (rotation));
2530
2531 # if defined (HAVE_NS)
2532 /* Under NS the transform is applied to the drawing surface at
2533 drawing time, so store it for later. */
2534 ns_image_set_transform (img->pixmap, matrix);
2535 ns_image_set_smoothing (img->pixmap, smoothing);
2536 # elif defined USE_CAIRO
2537 cairo_matrix_t cr_matrix = {matrix[0][0], matrix[0][1], matrix[1][0],
2538 matrix[1][1], matrix[2][0], matrix[2][1]};
2539 cairo_pattern_t *pattern = cairo_pattern_create_rgb (0, 0, 0);
2540 cairo_pattern_set_matrix (pattern, &cr_matrix);
2541 cairo_pattern_set_filter (pattern, smoothing
2542 ? CAIRO_FILTER_BEST : CAIRO_FILTER_NEAREST);
2543 /* Dummy solid color pattern just to record pattern matrix. */
2544 img->cr_data = pattern;
2545 # elif defined (HAVE_XRENDER)
2546 if (img->picture)
2547 {
2548 XTransform tmat
2549 = {{{XDoubleToFixed (matrix[0][0]),
2550 XDoubleToFixed (matrix[1][0]),
2551 XDoubleToFixed (matrix[2][0])},
2552 {XDoubleToFixed (matrix[0][1]),
2553 XDoubleToFixed (matrix[1][1]),
2554 XDoubleToFixed (matrix[2][1])},
2555 {XDoubleToFixed (matrix[0][2]),
2556 XDoubleToFixed (matrix[1][2]),
2557 XDoubleToFixed (matrix[2][2])}}};
2558
2559 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->picture,
2560 smoothing ? FilterBest : FilterNearest, 0, 0);
2561 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->picture, &tmat);
2562
2563 if (img->mask_picture)
2564 {
2565 XRenderSetPictureFilter (FRAME_X_DISPLAY (f), img->mask_picture,
2566 smoothing ? FilterBest : FilterNearest, 0, 0);
2567 XRenderSetPictureTransform (FRAME_X_DISPLAY (f), img->mask_picture,
2568 &tmat);
2569 }
2570 }
2571 # elif defined HAVE_NTGUI
2572 /* Store the transform matrix for application at draw time. */
2573 img->xform.eM11 = matrix[0][0];
2574 img->xform.eM12 = matrix[0][1];
2575 img->xform.eM21 = matrix[1][0];
2576 img->xform.eM22 = matrix[1][1];
2577 img->xform.eDx = matrix[2][0];
2578 img->xform.eDy = matrix[2][1];
2579 # endif
2580 #else
2581 if (rotation != 0 &&
2582 rotation != 90 &&
2583 rotation != 180 &&
2584 rotation != 270 &&
2585 rotation != 360)
2586 {
2587 image_error ("No native support for rotation by %g degrees",
2588 make_float (rotation));
2589 return;
2590 }
2591
2592 rotation = fmod (rotation, 360.0);
2593
2594 if (rotation == 90 || rotation == 270)
2595 {
2596 int w = width;
2597 width = height;
2598 height = w;
2599 }
2600
2601 img->have_be_transforms_p = rotation != 0 || (img->width != width) || (img->height != height);
2602 img->be_rotate = rotation;
2603 img->be_scale_x = 1.0 / (img->width / (double) width);
2604 img->be_scale_y = 1.0 / (img->height / (double) height);
2605 img->width = width;
2606 img->height = height;
2607 #endif /* not HAVE_HAIKU */
2608 }
2609
2610 #endif /* HAVE_IMAGEMAGICK || HAVE_NATIVE_TRANSFORMS */
2611
2612 /* Return the id of image with Lisp specification SPEC on frame F.
2613 SPEC must be a valid Lisp image specification (see valid_image_p). */
2614
2615 ptrdiff_t
lookup_image(struct frame * f,Lisp_Object spec,int face_id)2616 lookup_image (struct frame *f, Lisp_Object spec, int face_id)
2617 {
2618 struct image *img;
2619 EMACS_UINT hash;
2620
2621 if (FRAME_FACE_CACHE (f) == NULL)
2622 init_frame_faces (f);
2623 if (FRAME_FACE_CACHE (f)->used == 0)
2624 recompute_basic_faces (f);
2625 if (face_id < 0 || face_id >= FRAME_FACE_CACHE (f)->used)
2626 face_id = DEFAULT_FACE_ID;
2627
2628 struct face *face = FACE_FROM_ID (f, face_id);
2629 unsigned long foreground = face->foreground;
2630 unsigned long background = face->background;
2631 int font_size = face->font->pixel_size;
2632 char *font_family = SSDATA (face->lface[LFACE_FAMILY_INDEX]);
2633
2634 /* F must be a window-system frame, and SPEC must be a valid image
2635 specification. */
2636 eassert (FRAME_WINDOW_P (f));
2637 eassert (valid_image_p (spec));
2638
2639 /* Look up SPEC in the hash table of the image cache. */
2640 hash = sxhash (spec);
2641 img = search_image_cache (f, spec, hash, foreground, background,
2642 font_size, font_family, false);
2643 if (img && img->load_failed_p)
2644 {
2645 free_image (f, img);
2646 img = NULL;
2647 }
2648
2649 /* If not found, create a new image and cache it. */
2650 if (img == NULL)
2651 {
2652 block_input ();
2653 img = make_image (spec, hash);
2654 cache_image (f, img);
2655 img->face_foreground = foreground;
2656 img->face_background = background;
2657 img->face_font_size = font_size;
2658 img->face_font_family = xmalloc (strlen (font_family) + 1);
2659 strcpy (img->face_font_family, font_family);
2660 img->load_failed_p = ! img->type->load_img (f, img);
2661
2662 /* If we can't load the image, and we don't have a width and
2663 height, use some arbitrary width and height so that we can
2664 draw a rectangle for it. */
2665 if (img->load_failed_p)
2666 {
2667 Lisp_Object value;
2668
2669 value = image_spec_value (spec, QCwidth, NULL);
2670 img->width = (FIXNUMP (value)
2671 ? XFIXNAT (value) : DEFAULT_IMAGE_WIDTH);
2672 value = image_spec_value (spec, QCheight, NULL);
2673 img->height = (FIXNUMP (value)
2674 ? XFIXNAT (value) : DEFAULT_IMAGE_HEIGHT);
2675 }
2676 else
2677 {
2678 /* Handle image type independent image attributes
2679 `:ascent ASCENT', `:margin MARGIN', `:relief RELIEF',
2680 `:background COLOR'. */
2681 Lisp_Object ascent, margin, relief, bg;
2682 int relief_bound;
2683
2684 ascent = image_spec_value (spec, QCascent, NULL);
2685 if (FIXNUMP (ascent))
2686 img->ascent = XFIXNUM (ascent);
2687 else if (EQ (ascent, Qcenter))
2688 img->ascent = CENTERED_IMAGE_ASCENT;
2689
2690 margin = image_spec_value (spec, QCmargin, NULL);
2691 if (FIXNUMP (margin))
2692 img->vmargin = img->hmargin = XFIXNUM (margin);
2693 else if (CONSP (margin))
2694 {
2695 img->hmargin = XFIXNUM (XCAR (margin));
2696 img->vmargin = XFIXNUM (XCDR (margin));
2697 }
2698
2699 relief = image_spec_value (spec, QCrelief, NULL);
2700 relief_bound = INT_MAX - max (img->hmargin, img->vmargin);
2701 if (RANGED_FIXNUMP (- relief_bound, relief, relief_bound))
2702 {
2703 img->relief = XFIXNUM (relief);
2704 img->hmargin += eabs (img->relief);
2705 img->vmargin += eabs (img->relief);
2706 }
2707
2708 if (! img->background_valid)
2709 {
2710 bg = image_spec_value (img->spec, QCbackground, NULL);
2711 if (!NILP (bg))
2712 {
2713 img->background
2714 = image_alloc_image_color (f, img, bg, background);
2715 img->background_valid = 1;
2716 }
2717 }
2718
2719 /* Do image transformations and compute masks, unless we
2720 don't have the image yet. */
2721 if (!EQ (builtin_lisp_symbol (img->type->type), Qpostscript))
2722 postprocess_image (f, img);
2723
2724 /* postprocess_image above may modify the image or the mask,
2725 relying on the image's real width and height, so
2726 image_set_transform must be called after it. */
2727 #ifdef HAVE_NATIVE_TRANSFORMS
2728 image_set_transform (f, img);
2729 #endif
2730 }
2731
2732 unblock_input ();
2733 }
2734
2735 /* We're using IMG, so set its timestamp to `now'. */
2736 img->timestamp = current_timespec ();
2737
2738 /* Value is the image id. */
2739 return img->id;
2740 }
2741
2742
2743 /* Cache image IMG in the image cache of frame F. */
2744
2745 static void
cache_image(struct frame * f,struct image * img)2746 cache_image (struct frame *f, struct image *img)
2747 {
2748 struct image_cache *c = FRAME_IMAGE_CACHE (f);
2749 ptrdiff_t i;
2750
2751 if (!c)
2752 c = FRAME_IMAGE_CACHE (f) = make_image_cache ();
2753
2754 /* Find a free slot in c->images. */
2755 for (i = 0; i < c->used; ++i)
2756 if (c->images[i] == NULL)
2757 break;
2758
2759 /* If no free slot found, maybe enlarge c->images. */
2760 if (i == c->used && c->used == c->size)
2761 c->images = xpalloc (c->images, &c->size, 1, -1, sizeof *c->images);
2762
2763 /* Add IMG to c->images, and assign IMG an id. */
2764 c->images[i] = img;
2765 img->id = i;
2766 if (i == c->used)
2767 ++c->used;
2768
2769 /* Add IMG to the cache's hash table. */
2770 i = img->hash % IMAGE_CACHE_BUCKETS_SIZE;
2771 img->next = c->buckets[i];
2772 if (img->next)
2773 img->next->prev = img;
2774 img->prev = NULL;
2775 c->buckets[i] = img;
2776 }
2777
2778
2779 /* Call FN on every image in the image cache of frame F. Used to mark
2780 Lisp Objects in the image cache. */
2781
2782 /* Mark Lisp objects in image IMG. */
2783
2784 static void
mark_image(struct image * img)2785 mark_image (struct image *img)
2786 {
2787 mark_object (img->spec);
2788 mark_object (img->dependencies);
2789
2790 if (!NILP (img->lisp_data))
2791 mark_object (img->lisp_data);
2792 }
2793
2794
2795 void
mark_image_cache(struct image_cache * c)2796 mark_image_cache (struct image_cache *c)
2797 {
2798 if (c)
2799 {
2800 ptrdiff_t i;
2801 for (i = 0; i < c->used; ++i)
2802 if (c->images[i])
2803 mark_image (c->images[i]);
2804 }
2805 }
2806
2807
2808
2809 /***********************************************************************
2810 X / NS / W32 support code
2811 ***********************************************************************/
2812
2813 #ifdef HAVE_X_WINDOWS
2814 static bool
x_check_image_size(XImage * ximg,int width,int height)2815 x_check_image_size (XImage *ximg, int width, int height)
2816 {
2817 /* Respect Xlib's limits: it cannot deal with images that have more
2818 than INT_MAX (and/or UINT_MAX) bytes. And respect Emacs's limits
2819 of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object. */
2820 enum
2821 {
2822 XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
2823 X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
2824 };
2825
2826 int bitmap_pad, depth, bytes_per_line;
2827 if (ximg)
2828 {
2829 bitmap_pad = ximg->bitmap_pad;
2830 depth = ximg->depth;
2831 bytes_per_line = ximg->bytes_per_line;
2832 }
2833 else
2834 {
2835 bitmap_pad = 8;
2836 depth = 1;
2837 bytes_per_line = (width >> 3) + ((width & 7) != 0);
2838 }
2839 return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
2840 && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
2841 }
2842
2843 static bool
x_create_x_image_and_pixmap(struct frame * f,int width,int height,int depth,XImage ** ximg,Pixmap * pixmap)2844 x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
2845 XImage **ximg, Pixmap *pixmap)
2846 {
2847 Display *display = FRAME_X_DISPLAY (f);
2848 Drawable drawable = FRAME_X_DRAWABLE (f);
2849 Screen *screen = FRAME_X_SCREEN (f);
2850
2851 eassert (input_blocked_p ());
2852
2853 if (depth <= 0)
2854 depth = DefaultDepthOfScreen (screen);
2855 *ximg = XCreateImage (display, DefaultVisualOfScreen (screen),
2856 depth, ZPixmap, 0, NULL, width, height,
2857 depth > 16 ? 32 : depth > 8 ? 16 : 8, 0);
2858 if (*ximg == NULL)
2859 {
2860 image_error ("Unable to allocate X image");
2861 return 0;
2862 }
2863
2864 if (! x_check_image_size (*ximg, width, height))
2865 {
2866 x_destroy_x_image (*ximg);
2867 *ximg = NULL;
2868 image_error ("Image too large (%dx%d)",
2869 make_fixnum (width), make_fixnum (height));
2870 return 0;
2871 }
2872
2873 /* Allocate image raster. */
2874 (*ximg)->data = xmalloc ((*ximg)->bytes_per_line * height);
2875
2876 /* Allocate a pixmap of the same size. */
2877 *pixmap = XCreatePixmap (display, drawable, width, height, depth);
2878 if (*pixmap == NO_PIXMAP)
2879 {
2880 x_destroy_x_image (*ximg);
2881 *ximg = NULL;
2882 image_error ("Unable to create X pixmap");
2883 return 0;
2884 }
2885
2886 return 1;
2887 }
2888
2889 static void
x_destroy_x_image(XImage * ximg)2890 x_destroy_x_image (XImage *ximg)
2891 {
2892 eassert (input_blocked_p ());
2893 if (ximg)
2894 {
2895 xfree (ximg->data);
2896 ximg->data = NULL;
2897 }
2898 }
2899
2900 # if !defined USE_CAIRO && defined HAVE_XRENDER
2901 /* Create and return an XRender Picture for XRender transforms. */
2902 static Picture
x_create_xrender_picture(struct frame * f,Emacs_Pixmap pixmap,int depth)2903 x_create_xrender_picture (struct frame *f, Emacs_Pixmap pixmap, int depth)
2904 {
2905 Picture p;
2906 Display *display = FRAME_X_DISPLAY (f);
2907 int event_basep, error_basep;
2908
2909 if (XRenderQueryExtension (display, &event_basep, &error_basep))
2910 {
2911 if (depth <= 0)
2912 depth = DefaultDepthOfScreen (FRAME_X_SCREEN (f));
2913 if (depth == 32 || depth == 24 || depth == 8 || depth == 4 || depth == 1)
2914 {
2915 /* FIXME: Do we need to handle all possible bit depths?
2916 XRenderFindStandardFormat supports PictStandardARGB32,
2917 PictStandardRGB24, PictStandardA8, PictStandardA4,
2918 PictStandardA1, and PictStandardNUM (what is this?!).
2919
2920 XRenderFindFormat may support more, but I don't
2921 understand the documentation. */
2922 XRenderPictFormat *format;
2923 format = XRenderFindStandardFormat (display,
2924 depth == 32 ? PictStandardARGB32
2925 : depth == 24 ? PictStandardRGB24
2926 : depth == 8 ? PictStandardA8
2927 : depth == 4 ? PictStandardA4
2928 : PictStandardA1);
2929
2930 /* Set the Picture repeat to "pad". This means when
2931 operations look at pixels outside the image area they
2932 will use the value of the nearest real pixel instead of
2933 using a transparent black pixel. */
2934 XRenderPictureAttributes attr;
2935 unsigned long attr_mask = CPRepeat;
2936 attr.repeat = RepeatPad;
2937
2938 p = XRenderCreatePicture (display, pixmap, format, attr_mask, &attr);
2939 }
2940 else
2941 {
2942 image_error ("Specified image bit depth is not supported by XRender");
2943 return 0;
2944 }
2945 }
2946 else
2947 {
2948 /* XRender not supported on this display. */
2949 return 0;
2950 }
2951
2952 return p;
2953 }
2954 # endif /* !defined USE_CAIRO && defined HAVE_XRENDER */
2955 #endif /* HAVE_X_WINDOWS */
2956
2957 /* Return true if XIMG's size WIDTH x HEIGHT doesn't break the
2958 windowing system.
2959 WIDTH and HEIGHT must both be positive.
2960 If XIMG is null, assume it is a bitmap. */
2961
2962 static bool
image_check_image_size(Emacs_Pix_Container ximg,int width,int height)2963 image_check_image_size (Emacs_Pix_Container ximg, int width, int height)
2964 {
2965 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
2966 return x_check_image_size (ximg, width, height);
2967 #else
2968 /* FIXME: Implement this check for the HAVE_NS and HAVE_NTGUI cases.
2969 For now, assume that every image size is allowed on these systems. */
2970 return 1;
2971 #endif
2972 }
2973
2974 /* Create an Emacs_Pix_Container and a pixmap of size WIDTH x
2975 HEIGHT for use on frame F. Set *PIMG and *PIXMAP to the
2976 Emacs_Pix_Container and Emacs_Pixmap created. Set (*PIMG)->data
2977 to a raster of WIDTH x HEIGHT pixels allocated via xmalloc. Print
2978 error messages via image_error if an error occurs. Value is true
2979 if successful.
2980
2981 On W32, a DEPTH of zero signifies a 24 bit image, otherwise DEPTH
2982 should indicate the bit depth of the image. */
2983
2984 static bool
image_create_x_image_and_pixmap_1(struct frame * f,int width,int height,int depth,Emacs_Pix_Container * pimg,Emacs_Pixmap * pixmap,Picture * picture)2985 image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int depth,
2986 Emacs_Pix_Container *pimg,
2987 Emacs_Pixmap *pixmap, Picture *picture)
2988 {
2989 #ifdef USE_CAIRO
2990 eassert (input_blocked_p ());
2991
2992 /* Allocate a pixmap of the same size. */
2993 *pixmap = image_create_pix_container (f, width, height, depth);
2994 if (*pixmap == NO_PIXMAP)
2995 {
2996 *pimg = NULL;
2997 image_error ("Unable to create X pixmap", Qnil, Qnil);
2998 return 0;
2999 }
3000
3001 *pimg = *pixmap;
3002 return 1;
3003 #elif defined HAVE_X_WINDOWS
3004 if (!x_create_x_image_and_pixmap (f, width, height, depth, pimg, pixmap))
3005 return 0;
3006 # ifdef HAVE_XRENDER
3007 if (picture)
3008 *picture = x_create_xrender_picture (f, *pixmap, depth);
3009 # endif
3010
3011 return 1;
3012 #endif /* HAVE_X_WINDOWS */
3013
3014 #ifdef HAVE_HAIKU
3015 if (depth == 0)
3016 depth = 24;
3017
3018 if (depth != 24 && depth != 1)
3019 {
3020 *pimg = NULL;
3021 image_error ("Invalid image bit depth specified");
3022 return 0;
3023 }
3024
3025 *pixmap = BBitmap_new (width, height, depth == 1);
3026
3027 if (*pixmap == NO_PIXMAP)
3028 {
3029 *pimg = NULL;
3030 image_error ("Unable to create pixmap", Qnil, Qnil);
3031 return 0;
3032 }
3033
3034 *pimg = *pixmap;
3035 return 1;
3036 #endif
3037
3038 #ifdef HAVE_NTGUI
3039
3040 BITMAPINFOHEADER *header;
3041 HDC hdc;
3042 int scanline_width_bits;
3043 int remainder;
3044 int palette_colors = 0;
3045
3046 if (depth == 0)
3047 depth = 24;
3048
3049 if (depth != 1 && depth != 4 && depth != 8
3050 && depth != 16 && depth != 24 && depth != 32)
3051 {
3052 image_error ("Invalid image bit depth specified");
3053 return 0;
3054 }
3055
3056 scanline_width_bits = width * depth;
3057 remainder = scanline_width_bits % 32;
3058
3059 if (remainder)
3060 scanline_width_bits += 32 - remainder;
3061
3062 /* Bitmaps with a depth less than 16 need a palette. */
3063 /* BITMAPINFO structure already contains the first RGBQUAD. */
3064 if (depth < 16)
3065 palette_colors = 1 << (depth - 1);
3066
3067 *pimg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
3068
3069 header = &(*pimg)->info.bmiHeader;
3070 memset (&(*pimg)->info, 0, sizeof (BITMAPINFO));
3071 header->biSize = sizeof (*header);
3072 header->biWidth = width;
3073 header->biHeight = -height; /* negative indicates a top-down bitmap. */
3074 header->biPlanes = 1;
3075 header->biBitCount = depth;
3076 header->biCompression = BI_RGB;
3077 header->biClrUsed = palette_colors;
3078
3079 /* TODO: fill in palette. */
3080 if (depth == 1)
3081 {
3082 (*pimg)->info.bmiColors[0].rgbBlue = 0;
3083 (*pimg)->info.bmiColors[0].rgbGreen = 0;
3084 (*pimg)->info.bmiColors[0].rgbRed = 0;
3085 (*pimg)->info.bmiColors[0].rgbReserved = 0;
3086 /* bmiColors is a variable-length array declared by w32api
3087 headers as bmiColors[1], which triggers a warning under
3088 -Warray-bounds; shut that up. */
3089 # if GNUC_PREREQ (4, 4, 0)
3090 # pragma GCC push_options
3091 # pragma GCC diagnostic ignored "-Warray-bounds"
3092 # endif
3093 (*pimg)->info.bmiColors[1].rgbBlue = 255;
3094 (*pimg)->info.bmiColors[1].rgbGreen = 255;
3095 (*pimg)->info.bmiColors[1].rgbRed = 255;
3096 (*pimg)->info.bmiColors[1].rgbReserved = 0;
3097 # if GNUC_PREREQ (4, 4, 0)
3098 # pragma GCC pop_options
3099 # endif
3100 }
3101
3102 hdc = get_frame_dc (f);
3103
3104 /* Create a DIBSection and raster array for the bitmap,
3105 and store its handle in *pixmap. */
3106 *pixmap = CreateDIBSection (hdc, &(*pimg)->info,
3107 (depth < 16) ? DIB_PAL_COLORS : DIB_RGB_COLORS,
3108 /* casting avoids a GCC warning */
3109 (void **) &(*pimg)->data, NULL, 0);
3110
3111 /* Realize display palette and garbage all frames. */
3112 release_frame_dc (f, hdc);
3113
3114 if (*pixmap == NULL)
3115 {
3116 DWORD err = GetLastError ();
3117 Lisp_Object errcode;
3118 /* All system errors are < 10000, so the following is safe. */
3119 XSETINT (errcode, err);
3120 image_error ("Unable to create bitmap, error code %d", errcode);
3121 image_destroy_x_image (*pimg);
3122 *pimg = NULL;
3123 return 0;
3124 }
3125
3126 return 1;
3127
3128 #endif /* HAVE_NTGUI */
3129
3130 #ifdef HAVE_NS
3131 *pixmap = ns_image_for_XPM (width, height, depth);
3132 if (*pixmap == 0)
3133 {
3134 *pimg = NULL;
3135 image_error ("Unable to allocate NSImage for XPM pixmap");
3136 return 0;
3137 }
3138 *pimg = *pixmap;
3139 return 1;
3140 #endif
3141 }
3142
3143
3144 /* Destroy Emacs_Pix_Container PIMG. Free data associated with PIMG. */
3145
3146 static void
image_destroy_x_image(Emacs_Pix_Container pimg)3147 image_destroy_x_image (Emacs_Pix_Container pimg)
3148 {
3149 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
3150 x_destroy_x_image (pimg);
3151 #else
3152 eassert (input_blocked_p ());
3153 if (pimg)
3154 {
3155 #ifdef USE_CAIRO
3156 #endif /* USE_CAIRO */
3157 #ifdef HAVE_NTGUI
3158 /* Data will be freed by DestroyObject. */
3159 pimg->data = NULL;
3160 xfree (pimg);
3161 #endif /* HAVE_NTGUI */
3162 #ifdef HAVE_NS
3163 ns_release_object (pimg);
3164 #endif /* HAVE_NS */
3165 }
3166 #endif
3167 }
3168
3169
3170 /* Put Emacs_Pix_Container PIMG into pixmap PIXMAP on frame F.
3171 WIDTH and HEIGHT are width and height of both the image and
3172 pixmap. */
3173
3174 static void
gui_put_x_image(struct frame * f,Emacs_Pix_Container pimg,Emacs_Pixmap pixmap,int width,int height)3175 gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
3176 Emacs_Pixmap pixmap, int width, int height)
3177 {
3178 #if defined USE_CAIRO || defined HAVE_HAIKU
3179 eassert (pimg == pixmap);
3180 #elif defined HAVE_X_WINDOWS
3181 GC gc;
3182
3183 eassert (input_blocked_p ());
3184 gc = XCreateGC (FRAME_X_DISPLAY (f), pixmap, 0, NULL);
3185 XPutImage (FRAME_X_DISPLAY (f), pixmap, gc, pimg, 0, 0, 0, 0,
3186 pimg->width, pimg->height);
3187 XFreeGC (FRAME_X_DISPLAY (f), gc);
3188 #endif /* HAVE_X_WINDOWS */
3189
3190 #ifdef HAVE_NS
3191 eassert (pimg == pixmap);
3192 ns_retain_object (pimg);
3193 #endif
3194 }
3195
3196 /* Thin wrapper for image_create_x_image_and_pixmap_1, so that it matches
3197 with image_put_x_image. */
3198
3199 static bool
image_create_x_image_and_pixmap(struct frame * f,struct image * img,int width,int height,int depth,Emacs_Pix_Container * ximg,bool mask_p)3200 image_create_x_image_and_pixmap (struct frame *f, struct image *img,
3201 int width, int height, int depth,
3202 Emacs_Pix_Container *ximg, bool mask_p)
3203 {
3204 eassert ((!mask_p ? img->pixmap : img->mask) == NO_PIXMAP);
3205
3206 Picture *picture = NULL;
3207 #if !defined USE_CAIRO && defined HAVE_XRENDER
3208 picture = !mask_p ? &img->picture : &img->mask_picture;
3209 #endif
3210 return image_create_x_image_and_pixmap_1 (f, width, height, depth, ximg,
3211 !mask_p ? &img->pixmap : &img->mask,
3212 picture);
3213 }
3214
3215 /* Put pixel image PIMG into image IMG on frame F, as a mask if and only
3216 if MASK_P. On X, this simply records PIMG on a member of IMG, so
3217 it can be put into the pixmap afterwards via image_sync_to_pixmaps.
3218 On the other platforms, it puts PIMG into the pixmap, then frees
3219 the pixel image and its buffer. */
3220
3221 static void
image_put_x_image(struct frame * f,struct image * img,Emacs_Pix_Container ximg,bool mask_p)3222 image_put_x_image (struct frame *f, struct image *img, Emacs_Pix_Container ximg,
3223 bool mask_p)
3224 {
3225 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
3226 if (!mask_p)
3227 {
3228 eassert (img->ximg == NULL);
3229 img->ximg = ximg;
3230 }
3231 else
3232 {
3233 eassert (img->mask_img == NULL);
3234 img->mask_img = ximg;
3235 }
3236 #else
3237 gui_put_x_image (f, ximg, !mask_p ? img->pixmap : img->mask,
3238 img->width, img->height);
3239 image_destroy_x_image (ximg);
3240 #endif
3241 }
3242
3243 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
3244 /* Put the X images recorded in IMG on frame F into pixmaps, then free
3245 the X images and their buffers. */
3246
3247 static void
image_sync_to_pixmaps(struct frame * f,struct image * img)3248 image_sync_to_pixmaps (struct frame *f, struct image *img)
3249 {
3250 if (img->ximg)
3251 {
3252 gui_put_x_image (f, img->ximg, img->pixmap, img->width, img->height);
3253 image_destroy_x_image (img->ximg);
3254 img->ximg = NULL;
3255 }
3256 if (img->mask_img)
3257 {
3258 gui_put_x_image (f, img->mask_img, img->mask, img->width, img->height);
3259 image_destroy_x_image (img->mask_img);
3260 img->mask_img = NULL;
3261 }
3262 }
3263 #endif
3264
3265 #ifdef HAVE_NTGUI
3266 /* Create a memory device context for IMG on frame F. It stores the
3267 currently selected GDI object into *PREV for future restoration by
3268 image_unget_x_image_or_dc. */
3269
3270 static HDC
image_get_x_image_or_dc(struct frame * f,struct image * img,bool mask_p,HGDIOBJ * prev)3271 image_get_x_image_or_dc (struct frame *f, struct image *img, bool mask_p,
3272 HGDIOBJ *prev)
3273 {
3274 HDC frame_dc = get_frame_dc (f);
3275 HDC ximg = CreateCompatibleDC (frame_dc);
3276
3277 release_frame_dc (f, frame_dc);
3278 *prev = SelectObject (ximg, !mask_p ? img->pixmap : img->mask);
3279
3280 return ximg;
3281 }
3282
3283 static void
image_unget_x_image_or_dc(struct image * img,bool mask_p,HDC ximg,HGDIOBJ prev)3284 image_unget_x_image_or_dc (struct image *img, bool mask_p,
3285 HDC ximg, HGDIOBJ prev)
3286 {
3287 SelectObject (ximg, prev);
3288 DeleteDC (ximg);
3289 }
3290 #else /* !HAVE_NTGUI */
3291 /* Get the X image for IMG on frame F. The resulting X image data
3292 should be treated as read-only at least on X. */
3293
3294 static Emacs_Pix_Container
image_get_x_image(struct frame * f,struct image * img,bool mask_p)3295 image_get_x_image (struct frame *f, struct image *img, bool mask_p)
3296 {
3297 #if defined USE_CAIRO || defined (HAVE_HAIKU)
3298 return !mask_p ? img->pixmap : img->mask;
3299 #elif defined HAVE_X_WINDOWS
3300 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
3301
3302 if (ximg_in_img)
3303 return ximg_in_img;
3304 #ifdef HAVE_XRENDER
3305 else if (img->picture)
3306 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
3307 0, 0, img->original_width, img->original_height, ~0, ZPixmap);
3308 #endif
3309 else
3310 return XGetImage (FRAME_X_DISPLAY (f), !mask_p ? img->pixmap : img->mask,
3311 0, 0, img->width, img->height, ~0, ZPixmap);
3312 #elif defined (HAVE_NS)
3313 Emacs_Pix_Container pixmap = !mask_p ? img->pixmap : img->mask;
3314
3315 ns_retain_object (pixmap);
3316 return pixmap;
3317 #endif
3318 }
3319
3320 static void
image_unget_x_image(struct image * img,bool mask_p,Emacs_Pix_Container ximg)3321 image_unget_x_image (struct image *img, bool mask_p, Emacs_Pix_Container ximg)
3322 {
3323 #ifdef USE_CAIRO
3324 #elif defined HAVE_X_WINDOWS
3325 XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
3326
3327 if (ximg_in_img)
3328 eassert (ximg == ximg_in_img);
3329 else
3330 XDestroyImage (ximg);
3331 #elif defined (HAVE_NS)
3332 ns_release_object (ximg);
3333 #endif
3334 }
3335 #endif /* !HAVE_NTGUI */
3336
3337
3338 /***********************************************************************
3339 File Handling
3340 ***********************************************************************/
3341
3342 /* Find image file FILE. Look in data-directory/images, then
3343 x-bitmap-file-path. Value is the full name of the file
3344 found, or nil if not found. If PFD is nonnull store into *PFD a
3345 readable file descriptor for the file, opened in binary mode. If
3346 PFD is null, do not open the file. */
3347
3348 static Lisp_Object
image_find_image_fd(Lisp_Object file,int * pfd)3349 image_find_image_fd (Lisp_Object file, int *pfd)
3350 {
3351 Lisp_Object file_found, search_path;
3352 int fd;
3353
3354 /* TODO I think this should use something like image-load-path
3355 instead. Unfortunately, that can contain non-string elements. */
3356 search_path = Fcons (Fexpand_file_name (build_string ("images"),
3357 Vdata_directory),
3358 Vx_bitmap_file_path);
3359
3360 /* Try to find FILE in data-directory/images, then x-bitmap-file-path. */
3361 fd = openp (search_path, file, Qnil, &file_found,
3362 pfd ? Qt : make_fixnum (R_OK), false, false);
3363 if (fd == -2)
3364 {
3365 /* The file exists locally, but has a file name handler.
3366 (This happens, e.g., under Auto Image File Mode.)
3367 'openp' didn't open the file, so we should, because the
3368 caller expects that. */
3369 Lisp_Object encoded_name = ENCODE_FILE (file_found);
3370 fd = emacs_open (SSDATA (encoded_name), O_RDONLY, 0);
3371 }
3372 else if (fd < 0)
3373 return Qnil;
3374 if (pfd)
3375 *pfd = fd;
3376 return file_found;
3377 }
3378
3379 /* Find image file FILE. Look in data-directory/images, then
3380 x-bitmap-file-path. Value is the full name of the file found, or
3381 nil if not found. */
3382
3383 Lisp_Object
image_find_image_file(Lisp_Object file)3384 image_find_image_file (Lisp_Object file)
3385 {
3386 return image_find_image_fd (file, 0);
3387 }
3388
3389 /* Read FILE into memory. Value is a pointer to a buffer allocated
3390 with xmalloc holding FILE's contents. Value is null if an error
3391 occurred. FD is a file descriptor open for reading FILE. Set
3392 *SIZE to the size of the file. */
3393
3394 static char *
slurp_file(int fd,ptrdiff_t * size)3395 slurp_file (int fd, ptrdiff_t *size)
3396 {
3397 FILE *fp = fdopen (fd, "rb");
3398
3399 char *buf = NULL;
3400 struct stat st;
3401
3402 if (fp)
3403 {
3404 ptrdiff_t count = SPECPDL_INDEX ();
3405 record_unwind_protect_ptr (fclose_unwind, fp);
3406
3407 if (fstat (fileno (fp), &st) == 0
3408 && 0 <= st.st_size && st.st_size < min (PTRDIFF_MAX, SIZE_MAX))
3409 {
3410 /* Report an error if we read past the purported EOF.
3411 This can happen if the file grows as we read it. */
3412 ptrdiff_t buflen = st.st_size;
3413 buf = xmalloc (buflen + 1);
3414 if (fread (buf, 1, buflen + 1, fp) == buflen)
3415 *size = buflen;
3416 else
3417 {
3418 xfree (buf);
3419 buf = NULL;
3420 }
3421 }
3422
3423 unbind_to (count, Qnil);
3424 }
3425
3426 return buf;
3427 }
3428
3429
3430
3431 /***********************************************************************
3432 XBM images
3433 ***********************************************************************/
3434
3435 static bool xbm_file_p (Lisp_Object);
3436
3437
3438 /* Indices of image specification fields in xbm_format, below. */
3439
3440 enum xbm_keyword_index
3441 {
3442 XBM_TYPE,
3443 XBM_FILE,
3444 XBM_WIDTH,
3445 XBM_HEIGHT,
3446 XBM_STRIDE,
3447 XBM_DATA,
3448 XBM_FOREGROUND,
3449 XBM_BACKGROUND,
3450 XBM_ASCENT,
3451 XBM_MARGIN,
3452 XBM_RELIEF,
3453 XBM_ALGORITHM,
3454 XBM_HEURISTIC_MASK,
3455 XBM_MASK,
3456 XBM_LAST
3457 };
3458
3459 /* Vector of image_keyword structures describing the format
3460 of valid XBM image specifications. */
3461
3462 static const struct image_keyword xbm_format[XBM_LAST] =
3463 {
3464 {":type", IMAGE_SYMBOL_VALUE, 1},
3465 {":file", IMAGE_STRING_VALUE, 0},
3466 {":width", IMAGE_POSITIVE_INTEGER_VALUE, 0},
3467 {":height", IMAGE_POSITIVE_INTEGER_VALUE, 0},
3468 {":stride", IMAGE_POSITIVE_INTEGER_VALUE, 0},
3469 {":data", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3470 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
3471 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
3472 {":ascent", IMAGE_ASCENT_VALUE, 0},
3473 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
3474 {":relief", IMAGE_INTEGER_VALUE, 0},
3475 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3476 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
3477 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
3478 };
3479
3480 /* Tokens returned from xbm_scan. */
3481
3482 enum xbm_token
3483 {
3484 XBM_TK_IDENT = 256,
3485 XBM_TK_NUMBER,
3486 XBM_TK_OVERFLOW
3487 };
3488
3489
3490 /* Return true if OBJECT is a valid XBM-type image specification.
3491 A valid specification is a list starting with the symbol `image'
3492 The rest of the list is a property list which must contain an
3493 entry `:type xbm'.
3494
3495 If the specification specifies a file to load, it must contain
3496 an entry `:file FILENAME' where FILENAME is a string.
3497
3498 If the specification is for a bitmap loaded from memory it must
3499 contain `:width WIDTH', `:height HEIGHT', and `:data DATA', where
3500 WIDTH and HEIGHT are integers > 0. DATA may be:
3501
3502 1. a string large enough to hold the bitmap data, i.e. it must
3503 have a size >= (WIDTH + 7) / 8 * HEIGHT
3504
3505 2. a bool-vector of size >= WIDTH * HEIGHT
3506
3507 3. a vector of strings or bool-vectors, one for each line of the
3508 bitmap.
3509
3510 4. a string containing an in-memory XBM file. WIDTH and HEIGHT
3511 may not be specified in this case because they are defined in the
3512 XBM file.
3513
3514 Both the file and data forms may contain the additional entries
3515 `:background COLOR' and `:foreground COLOR'. If not present,
3516 foreground and background of the frame on which the image is
3517 displayed is used. */
3518
3519 static bool
xbm_image_p(Lisp_Object object)3520 xbm_image_p (Lisp_Object object)
3521 {
3522 struct image_keyword kw[XBM_LAST];
3523
3524 memcpy (kw, xbm_format, sizeof kw);
3525 if (!parse_image_spec (object, kw, XBM_LAST, Qxbm))
3526 return 0;
3527
3528 eassert (EQ (kw[XBM_TYPE].value, Qxbm));
3529
3530 if (kw[XBM_FILE].count)
3531 {
3532 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_DATA].count)
3533 return 0;
3534 }
3535 else if (kw[XBM_DATA].count && xbm_file_p (kw[XBM_DATA].value))
3536 {
3537 /* In-memory XBM file. */
3538 if (kw[XBM_WIDTH].count || kw[XBM_HEIGHT].count || kw[XBM_FILE].count)
3539 return 0;
3540 }
3541 else
3542 {
3543 Lisp_Object data;
3544 int width, height, stride;
3545
3546 /* Entries for `:width', `:height' and `:data' must be present. */
3547 if (!kw[XBM_WIDTH].count
3548 || !kw[XBM_HEIGHT].count
3549 || !kw[XBM_DATA].count)
3550 return 0;
3551
3552 data = kw[XBM_DATA].value;
3553 width = XFIXNAT (kw[XBM_WIDTH].value);
3554 height = XFIXNAT (kw[XBM_HEIGHT].value);
3555
3556 if (!kw[XBM_STRIDE].count)
3557 stride = width;
3558 else
3559 stride = XFIXNAT (kw[XBM_STRIDE].value);
3560
3561 /* Check type of data, and width and height against contents of
3562 data. */
3563 if (VECTORP (data))
3564 {
3565 EMACS_INT i;
3566
3567 /* Number of elements of the vector must be >= height. */
3568 if (ASIZE (data) < height)
3569 return 0;
3570
3571 /* Each string or bool-vector in data must be large enough
3572 for one line of the image. */
3573 for (i = 0; i < height; ++i)
3574 {
3575 Lisp_Object elt = AREF (data, i);
3576
3577 if (STRINGP (elt))
3578 {
3579 if (SCHARS (elt) < stride / CHAR_BIT)
3580 return 0;
3581 }
3582 else if (BOOL_VECTOR_P (elt))
3583 {
3584 if (bool_vector_size (elt) < width)
3585 return 0;
3586 }
3587 else
3588 return 0;
3589 }
3590 }
3591 else if (STRINGP (data))
3592 {
3593 if (SCHARS (data) < stride / CHAR_BIT * height)
3594 return 0;
3595 }
3596 else if (BOOL_VECTOR_P (data))
3597 {
3598 if (height > 1 && stride != (width + CHAR_BIT - 1)
3599 / CHAR_BIT * CHAR_BIT)
3600 return 0;
3601
3602 if (bool_vector_size (data) / height < stride)
3603 return 0;
3604 }
3605 else
3606 return 0;
3607 }
3608
3609 return 1;
3610 }
3611
3612
3613 /* Scan a bitmap file. FP is the stream to read from. Value is
3614 either an enumerator from enum xbm_token, or a character for a
3615 single-character token, or 0 at end of file. If scanning an
3616 identifier, store the lexeme of the identifier in SVAL. If
3617 scanning a number, store its value in *IVAL. */
3618
3619 static int
xbm_scan(char ** s,char * end,char * sval,int * ival)3620 xbm_scan (char **s, char *end, char *sval, int *ival)
3621 {
3622 unsigned char c UNINIT;
3623 char *sval_end = sval + BUFSIZ;
3624
3625 loop:
3626
3627 /* Skip white space. */
3628 while (*s < end && (c = *(*s)++, c_isspace (c)))
3629 ;
3630
3631 if (*s >= end)
3632 c = 0;
3633 else if (c_isdigit (c))
3634 {
3635 int value = 0, digit;
3636 bool overflow = false;
3637
3638 if (c == '0' && *s < end)
3639 {
3640 c = *(*s)++;
3641 if (c == 'x' || c == 'X')
3642 {
3643 while (*s < end)
3644 {
3645 c = *(*s)++;
3646 digit = char_hexdigit (c);
3647 if (digit < 0)
3648 break;
3649 overflow |= INT_MULTIPLY_WRAPV (value, 16, &value);
3650 value += digit;
3651 }
3652 }
3653 else if ('0' <= c && c <= '7')
3654 {
3655 value = c - '0';
3656 while (*s < end
3657 && (c = *(*s)++, '0' <= c && c <= '7'))
3658 {
3659 overflow |= INT_MULTIPLY_WRAPV (value, 8, &value);
3660 value += c - '0';
3661 }
3662 }
3663 }
3664 else
3665 {
3666 value = c - '0';
3667 while (*s < end
3668 && (c = *(*s)++, c_isdigit (c)))
3669 {
3670 overflow |= INT_MULTIPLY_WRAPV (value, 10, &value);
3671 overflow |= INT_ADD_WRAPV (value, c - '0', &value);
3672 }
3673 }
3674
3675 if (*s < end)
3676 *s = *s - 1;
3677 *ival = value;
3678 return overflow ? XBM_TK_OVERFLOW : XBM_TK_NUMBER;
3679 }
3680 else if (c_isalpha (c) || c == '_')
3681 {
3682 *sval++ = c;
3683 while (*s < end && sval < sval_end
3684 && (c = *(*s)++, (c_isalnum (c) || c == '_')))
3685 *sval++ = c;
3686 *sval = 0;
3687 if (*s < end)
3688 *s = *s - 1;
3689 return XBM_TK_IDENT;
3690 }
3691 else if (c == '/' && **s == '*')
3692 {
3693 /* C-style comment. */
3694 ++*s;
3695 while (**s && (**s != '*' || *(*s + 1) != '/'))
3696 ++*s;
3697 if (**s)
3698 {
3699 *s += 2;
3700 goto loop;
3701 }
3702 }
3703
3704 return c;
3705 }
3706
3707 #ifdef HAVE_NTGUI
3708
3709 /* Create a Windows bitmap from X bitmap data. */
3710 static HBITMAP
w32_create_pixmap_from_bitmap_data(int width,int height,char * data)3711 w32_create_pixmap_from_bitmap_data (int width, int height, char *data)
3712 {
3713 static unsigned char swap_nibble[16]
3714 = { 0x0, 0x8, 0x4, 0xc, /* 0000 1000 0100 1100 */
3715 0x2, 0xa, 0x6, 0xe, /* 0010 1010 0110 1110 */
3716 0x1, 0x9, 0x5, 0xd, /* 0001 1001 0101 1101 */
3717 0x3, 0xb, 0x7, 0xf }; /* 0011 1011 0111 1111 */
3718 int i, j, w1, w2;
3719 unsigned char *bits, *p;
3720 HBITMAP bmp;
3721
3722 w1 = (width + 7) / 8; /* nb of 8bits elt in X bitmap */
3723 w2 = ((width + 15) / 16) * 2; /* nb of 16bits elt in W32 bitmap */
3724 bits = alloca (height * w2);
3725 memset (bits, 0, height * w2);
3726 for (i = 0; i < height; i++)
3727 {
3728 p = bits + i*w2;
3729 for (j = 0; j < w1; j++)
3730 {
3731 /* Bitswap XBM bytes to match how Windows does things. */
3732 unsigned char c = *data++;
3733 *p++ = (unsigned char)((swap_nibble[c & 0xf] << 4)
3734 | (swap_nibble[(c>>4) & 0xf]));
3735 }
3736 }
3737 bmp = CreateBitmap (width, height, 1, 1, (char *) bits);
3738
3739 return bmp;
3740 }
3741
3742 static void
convert_mono_to_color_image(struct frame * f,struct image * img,COLORREF foreground,COLORREF background)3743 convert_mono_to_color_image (struct frame *f, struct image *img,
3744 COLORREF foreground, COLORREF background)
3745 {
3746 HDC hdc, old_img_dc, new_img_dc;
3747 HGDIOBJ old_prev, new_prev;
3748 HBITMAP new_pixmap;
3749
3750 hdc = get_frame_dc (f);
3751 old_img_dc = CreateCompatibleDC (hdc);
3752 new_img_dc = CreateCompatibleDC (hdc);
3753 new_pixmap = CreateCompatibleBitmap (hdc, img->width, img->height);
3754 release_frame_dc (f, hdc);
3755 old_prev = SelectObject (old_img_dc, img->pixmap);
3756 new_prev = SelectObject (new_img_dc, new_pixmap);
3757 SetTextColor (new_img_dc, foreground);
3758 SetBkColor (new_img_dc, background);
3759
3760 BitBlt (new_img_dc, 0, 0, img->width, img->height, old_img_dc,
3761 0, 0, SRCCOPY);
3762
3763 SelectObject (old_img_dc, old_prev);
3764 SelectObject (new_img_dc, new_prev);
3765 DeleteDC (old_img_dc);
3766 DeleteDC (new_img_dc);
3767 DeleteObject (img->pixmap);
3768 if (new_pixmap == 0)
3769 fputs ("Failed to convert image to color.\n", stderr);
3770 else
3771 img->pixmap = new_pixmap;
3772 }
3773
3774 #define XBM_BIT_SHUFFLE(b) (~(b))
3775
3776 #else
3777
3778 #define XBM_BIT_SHUFFLE(b) (b)
3779
3780 #endif /* HAVE_NTGUI */
3781
3782
3783 static void
Create_Pixmap_From_Bitmap_Data(struct frame * f,struct image * img,char * data,RGB_PIXEL_COLOR fg,RGB_PIXEL_COLOR bg,bool non_default_colors)3784 Create_Pixmap_From_Bitmap_Data (struct frame *f, struct image *img, char *data,
3785 RGB_PIXEL_COLOR fg, RGB_PIXEL_COLOR bg,
3786 bool non_default_colors)
3787 {
3788 #ifdef USE_CAIRO
3789 Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}};
3790 FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg));
3791 fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue);
3792 bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue);
3793 img->pixmap
3794 = image_pix_container_create_from_bitmap_data (f, data, img->width,
3795 img->height, fg, bg);
3796 #elif defined HAVE_X_WINDOWS
3797 img->pixmap
3798 = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
3799 FRAME_X_DRAWABLE (f),
3800 data,
3801 img->width, img->height,
3802 fg, bg,
3803 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
3804 # if !defined USE_CAIRO && defined HAVE_XRENDER
3805 if (img->pixmap)
3806 img->picture = x_create_xrender_picture (f, img->pixmap, 0);
3807 # endif
3808
3809 #elif defined HAVE_NTGUI
3810 img->pixmap
3811 = w32_create_pixmap_from_bitmap_data (img->width, img->height, data);
3812
3813 /* If colors were specified, transfer the bitmap to a color one. */
3814 if (non_default_colors)
3815 convert_mono_to_color_image (f, img, fg, bg);
3816 #elif defined HAVE_NS
3817 img->pixmap = ns_image_from_XBM (data, img->width, img->height, fg, bg);
3818 #endif
3819 }
3820
3821
3822
3823 /* Replacement for XReadBitmapFileData which isn't available under old
3824 X versions. CONTENTS is a pointer to a buffer to parse; END is the
3825 buffer's end. Set *WIDTH and *HEIGHT to the width and height of
3826 the image. Return in *DATA the bitmap data allocated with xmalloc.
3827 Value is true if successful. DATA null means just test if
3828 CONTENTS looks like an in-memory XBM file. If INHIBIT_IMAGE_ERROR,
3829 inhibit the call to image_error when the image size is invalid (the
3830 bitmap remains unread). */
3831
3832 static bool
xbm_read_bitmap_data(struct frame * f,char * contents,char * end,int * width,int * height,char ** data,bool inhibit_image_error)3833 xbm_read_bitmap_data (struct frame *f, char *contents, char *end,
3834 int *width, int *height, char **data,
3835 bool inhibit_image_error)
3836 {
3837 char *s = contents;
3838 char buffer[BUFSIZ];
3839 bool padding_p = 0;
3840 bool v10 = 0;
3841 int bytes_per_line, i, nbytes;
3842 char *p;
3843 int value;
3844 int LA1;
3845
3846 #define match() \
3847 LA1 = xbm_scan (&s, end, buffer, &value)
3848
3849 #define expect(TOKEN) \
3850 do \
3851 { \
3852 if (LA1 != (TOKEN)) \
3853 goto failure; \
3854 match (); \
3855 } \
3856 while (0)
3857
3858 #define expect_ident(IDENT) \
3859 if (LA1 == XBM_TK_IDENT && strcmp (buffer, (IDENT)) == 0) \
3860 match (); \
3861 else \
3862 goto failure
3863
3864 *width = *height = -1;
3865 if (data)
3866 *data = NULL;
3867 LA1 = xbm_scan (&s, end, buffer, &value);
3868
3869 /* Parse defines for width, height and hot-spots. */
3870 while (LA1 == '#')
3871 {
3872 match ();
3873 expect_ident ("define");
3874 expect (XBM_TK_IDENT);
3875
3876 if (LA1 == XBM_TK_NUMBER)
3877 {
3878 char *q = strrchr (buffer, '_');
3879 q = q ? q + 1 : buffer;
3880 if (strcmp (q, "width") == 0)
3881 *width = value;
3882 else if (strcmp (q, "height") == 0)
3883 *height = value;
3884 }
3885 expect (XBM_TK_NUMBER);
3886 }
3887
3888 if (!check_image_size (f, *width, *height))
3889 {
3890 if (!inhibit_image_error)
3891 image_size_error ();
3892 goto failure;
3893 }
3894 else if (data == NULL)
3895 goto success;
3896
3897 /* Parse bits. Must start with `static'. */
3898 expect_ident ("static");
3899 if (LA1 == XBM_TK_IDENT)
3900 {
3901 if (strcmp (buffer, "unsigned") == 0)
3902 {
3903 match ();
3904 expect_ident ("char");
3905 }
3906 else if (strcmp (buffer, "short") == 0)
3907 {
3908 match ();
3909 v10 = 1;
3910 if (*width % 16 && *width % 16 < 9)
3911 padding_p = 1;
3912 }
3913 else if (strcmp (buffer, "char") == 0)
3914 match ();
3915 else
3916 goto failure;
3917 }
3918 else
3919 goto failure;
3920
3921 expect (XBM_TK_IDENT);
3922 expect ('[');
3923 expect (']');
3924 expect ('=');
3925 expect ('{');
3926
3927 if (! image_check_image_size (0, *width, *height))
3928 {
3929 if (!inhibit_image_error)
3930 image_error ("Image too large (%dx%d)",
3931 make_fixnum (*width), make_fixnum (*height));
3932 goto failure;
3933 }
3934 bytes_per_line = (*width + 7) / 8 + padding_p;
3935 nbytes = bytes_per_line * *height;
3936 p = *data = xmalloc (nbytes);
3937
3938 if (v10)
3939 {
3940 for (i = 0; i < nbytes; i += 2)
3941 {
3942 int val = value;
3943 expect (XBM_TK_NUMBER);
3944
3945 *p++ = XBM_BIT_SHUFFLE (val);
3946 if (!padding_p || ((i + 2) % bytes_per_line))
3947 *p++ = XBM_BIT_SHUFFLE (value >> 8);
3948
3949 if (LA1 == ',' || LA1 == '}')
3950 match ();
3951 else
3952 goto failure;
3953 }
3954 }
3955 else
3956 {
3957 for (i = 0; i < nbytes; ++i)
3958 {
3959 int val = value;
3960 expect (XBM_TK_NUMBER);
3961
3962 *p++ = XBM_BIT_SHUFFLE (val);
3963
3964 if (LA1 == ',' || LA1 == '}')
3965 match ();
3966 else
3967 goto failure;
3968 }
3969 }
3970
3971 success:
3972 return 1;
3973
3974 failure:
3975
3976 if (data && *data)
3977 {
3978 xfree (*data);
3979 *data = NULL;
3980 }
3981 return 0;
3982
3983 #undef match
3984 #undef expect
3985 #undef expect_ident
3986 }
3987
3988
3989 /* Load XBM image IMG which will be displayed on frame F from buffer
3990 CONTENTS. END is the end of the buffer. Value is true if
3991 successful. */
3992
3993 static bool
xbm_load_image(struct frame * f,struct image * img,char * contents,char * end)3994 xbm_load_image (struct frame *f, struct image *img, char *contents, char *end)
3995 {
3996 bool rc;
3997 char *data;
3998 bool success_p = 0;
3999
4000 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height,
4001 &data, 0);
4002 if (rc)
4003 {
4004 unsigned long foreground = img->face_foreground;
4005 unsigned long background = img->face_background;
4006 bool non_default_colors = 0;
4007 Lisp_Object value;
4008
4009 eassert (img->width > 0 && img->height > 0);
4010
4011 /* Get foreground and background colors, maybe allocate colors. */
4012 value = image_spec_value (img->spec, QCforeground, NULL);
4013 if (!NILP (value))
4014 {
4015 foreground = image_alloc_image_color (f, img, value, foreground);
4016 non_default_colors = 1;
4017 }
4018 value = image_spec_value (img->spec, QCbackground, NULL);
4019 if (!NILP (value))
4020 {
4021 background = image_alloc_image_color (f, img, value, background);
4022 img->background = background;
4023 img->background_valid = 1;
4024 non_default_colors = 1;
4025 }
4026
4027 if (image_check_image_size (0, img->width, img->height))
4028 Create_Pixmap_From_Bitmap_Data (f, img, data,
4029 foreground, background,
4030 non_default_colors);
4031 else
4032 img->pixmap = NO_PIXMAP;
4033 xfree (data);
4034
4035 if (img->pixmap == NO_PIXMAP)
4036 {
4037 image_clear_image (f, img);
4038 image_error ("Unable to create X pixmap for `%s'", img->spec);
4039 }
4040 else
4041 success_p = 1;
4042 }
4043 else
4044 image_error ("Error loading XBM image `%s'", img->spec);
4045
4046 return success_p;
4047 }
4048
4049
4050 /* Value is true if DATA looks like an in-memory XBM file. */
4051
4052 static bool
xbm_file_p(Lisp_Object data)4053 xbm_file_p (Lisp_Object data)
4054 {
4055 int w, h;
4056 return (STRINGP (data)
4057 && xbm_read_bitmap_data (NULL, SSDATA (data),
4058 SSDATA (data) + SBYTES (data),
4059 &w, &h, NULL, 1));
4060 }
4061
4062
4063 /* Fill image IMG which is used on frame F with pixmap data. Value is
4064 true if successful. */
4065
4066 static bool
xbm_load(struct frame * f,struct image * img)4067 xbm_load (struct frame *f, struct image *img)
4068 {
4069 bool success_p = 0;
4070 Lisp_Object file_name;
4071
4072 eassert (xbm_image_p (img->spec));
4073
4074 /* If IMG->spec specifies a file name, create a non-file spec from it. */
4075 file_name = image_spec_value (img->spec, QCfile, NULL);
4076 if (STRINGP (file_name))
4077 {
4078 int fd;
4079 Lisp_Object file = image_find_image_fd (file_name, &fd);
4080 if (!STRINGP (file))
4081 {
4082 image_error ("Cannot find image file `%s'", file_name);
4083 return 0;
4084 }
4085
4086 ptrdiff_t size;
4087 char *contents = slurp_file (fd, &size);
4088 if (contents == NULL)
4089 {
4090 image_error ("Error loading XBM image `%s'", file);
4091 return 0;
4092 }
4093
4094 success_p = xbm_load_image (f, img, contents, contents + size);
4095 xfree (contents);
4096 }
4097 else
4098 {
4099 struct image_keyword fmt[XBM_LAST];
4100 Lisp_Object data;
4101 unsigned long foreground = img->face_foreground;
4102 unsigned long background = img->face_background;
4103 bool non_default_colors = 0;
4104 char *bits;
4105 bool parsed_p;
4106 bool in_memory_file_p = 0;
4107
4108 /* See if data looks like an in-memory XBM file. */
4109 data = image_spec_value (img->spec, QCdata, NULL);
4110 in_memory_file_p = xbm_file_p (data);
4111
4112 /* Parse the image specification. */
4113 memcpy (fmt, xbm_format, sizeof fmt);
4114 parsed_p = parse_image_spec (img->spec, fmt, XBM_LAST, Qxbm);
4115 eassert (parsed_p);
4116
4117 /* Get specified width, and height. */
4118 if (!in_memory_file_p)
4119 {
4120 img->width = XFIXNAT (fmt[XBM_WIDTH].value);
4121 img->height = XFIXNAT (fmt[XBM_HEIGHT].value);
4122 eassert (img->width > 0 && img->height > 0);
4123 if (!check_image_size (f, img->width, img->height))
4124 {
4125 image_size_error ();
4126 return 0;
4127 }
4128 }
4129
4130 /* Get foreground and background colors, maybe allocate colors. */
4131 if (fmt[XBM_FOREGROUND].count
4132 && STRINGP (fmt[XBM_FOREGROUND].value))
4133 {
4134 foreground = image_alloc_image_color (f,
4135 img,
4136 fmt[XBM_FOREGROUND].value,
4137 foreground);
4138 non_default_colors = 1;
4139 }
4140
4141 if (fmt[XBM_BACKGROUND].count
4142 && STRINGP (fmt[XBM_BACKGROUND].value))
4143 {
4144 background = image_alloc_image_color (f,
4145 img,
4146 fmt[XBM_BACKGROUND].value,
4147 background);
4148 non_default_colors = 1;
4149 }
4150
4151 if (in_memory_file_p)
4152 success_p = xbm_load_image (f, img, SSDATA (data),
4153 SSDATA (data) + SBYTES (data));
4154 else
4155 {
4156 USE_SAFE_ALLOCA;
4157
4158 if (VECTORP (data))
4159 {
4160 int i;
4161 char *p;
4162 int nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT;
4163
4164 SAFE_NALLOCA (bits, nbytes, img->height);
4165 p = bits;
4166 for (i = 0; i < img->height; ++i, p += nbytes)
4167 {
4168 Lisp_Object line = AREF (data, i);
4169 if (STRINGP (line))
4170 memcpy (p, SDATA (line), nbytes);
4171 else
4172 memcpy (p, bool_vector_data (line), nbytes);
4173 }
4174 }
4175 else if (STRINGP (data))
4176 bits = SSDATA (data);
4177 else
4178 bits = (char *) bool_vector_data (data);
4179
4180 #ifdef HAVE_NTGUI
4181 {
4182 char *invertedBits;
4183 int nbytes, i;
4184 /* Windows mono bitmaps are reversed compared with X. */
4185 invertedBits = bits;
4186 nbytes = (img->width + CHAR_BIT - 1) / CHAR_BIT * img->height;
4187 SAFE_NALLOCA (bits, 1, nbytes);
4188 for (i = 0; i < nbytes; i++)
4189 bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
4190 }
4191 #endif
4192 /* Create the pixmap. */
4193
4194 if (image_check_image_size (0, img->width, img->height))
4195 Create_Pixmap_From_Bitmap_Data (f, img, bits,
4196 foreground, background,
4197 non_default_colors);
4198 else
4199 img->pixmap = NO_PIXMAP;
4200
4201 if (img->pixmap)
4202 success_p = 1;
4203 else
4204 {
4205 image_error ("Unable to create pixmap for XBM image `%s'",
4206 img->spec);
4207 image_clear_image (f, img);
4208 }
4209
4210 SAFE_FREE ();
4211 }
4212 }
4213
4214 return success_p;
4215 }
4216
4217
4218
4219 /***********************************************************************
4220 XPM images
4221 ***********************************************************************/
4222
4223 #if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_PGTK)
4224
4225 static bool xpm_image_p (Lisp_Object object);
4226 static bool xpm_load (struct frame *f, struct image *img);
4227
4228 #endif /* HAVE_XPM || HAVE_NS */
4229
4230 #ifdef HAVE_XPM
4231 #ifdef HAVE_NTGUI
4232 /* Indicate to xpm.h that we don't have Xlib. */
4233 #define FOR_MSW
4234 /* simx.h in xpm defines XColor and XImage differently than Emacs. */
4235 /* It also defines Display the same way as Emacs, but gcc 3.3 still barfs. */
4236 #define XColor xpm_XColor
4237 #define XImage xpm_XImage
4238 #define Display xpm_Display
4239 #ifdef CYGWIN
4240 #include "noX/xpm.h"
4241 #else /* not CYGWIN */
4242 #include "X11/xpm.h"
4243 #endif /* not CYGWIN */
4244 #undef FOR_MSW
4245 #undef XColor
4246 #undef XImage
4247 #undef Display
4248 #else /* not HAVE_NTGUI */
4249 #include "X11/xpm.h"
4250 #endif /* not HAVE_NTGUI */
4251 #endif /* HAVE_XPM */
4252
4253 #if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
4254
4255 /* Indices of image specification fields in xpm_format, below. */
4256
4257 enum xpm_keyword_index
4258 {
4259 XPM_TYPE,
4260 XPM_FILE,
4261 XPM_DATA,
4262 XPM_ASCENT,
4263 XPM_MARGIN,
4264 XPM_RELIEF,
4265 XPM_ALGORITHM,
4266 XPM_HEURISTIC_MASK,
4267 XPM_MASK,
4268 XPM_COLOR_SYMBOLS,
4269 XPM_BACKGROUND,
4270 XPM_LAST
4271 };
4272
4273 #if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
4274 /* Vector of image_keyword structures describing the format
4275 of valid XPM image specifications. */
4276
4277 static const struct image_keyword xpm_format[XPM_LAST] =
4278 {
4279 {":type", IMAGE_SYMBOL_VALUE, 1},
4280 {":file", IMAGE_STRING_VALUE, 0},
4281 {":data", IMAGE_STRING_VALUE, 0},
4282 {":ascent", IMAGE_ASCENT_VALUE, 0},
4283 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
4284 {":relief", IMAGE_INTEGER_VALUE, 0},
4285 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4286 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4287 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4288 {":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
4289 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
4290 };
4291 #endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
4292
4293 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
4294
4295 /* Define ALLOC_XPM_COLORS if we can use Emacs' own color allocation
4296 functions for allocating image colors. Our own functions handle
4297 color allocation failures more gracefully than the ones on the XPM
4298 lib. */
4299
4300 #if defined XpmAllocColor && defined XpmFreeColors && defined XpmColorClosure
4301 #define ALLOC_XPM_COLORS
4302 #endif
4303 #endif /* HAVE_X_WINDOWS && !USE_CAIRO */
4304
4305 #ifdef ALLOC_XPM_COLORS
4306
4307 static struct xpm_cached_color *xpm_cache_color (struct frame *, char *,
4308 XColor *, int);
4309
4310 /* An entry in a hash table used to cache color definitions of named
4311 colors. This cache is necessary to speed up XPM image loading in
4312 case we do color allocations ourselves. Without it, we would need
4313 a call to XParseColor per pixel in the image.
4314
4315 FIXME Now that we're using x_parse_color and its cache, reevaluate
4316 the need for this caching layer. */
4317
4318 struct xpm_cached_color
4319 {
4320 /* Next in collision chain. */
4321 struct xpm_cached_color *next;
4322
4323 /* Color definition (RGB and pixel color). */
4324 XColor color;
4325
4326 /* Color name. */
4327 char name[FLEXIBLE_ARRAY_MEMBER];
4328 };
4329
4330 /* The hash table used for the color cache, and its bucket vector
4331 size (which should be prime). */
4332
4333 #define XPM_COLOR_CACHE_BUCKETS 1009
4334 static struct xpm_cached_color **xpm_color_cache;
4335
4336 /* Initialize the color cache. */
4337
4338 static void
xpm_init_color_cache(struct frame * f,XpmAttributes * attrs)4339 xpm_init_color_cache (struct frame *f, XpmAttributes *attrs)
4340 {
4341 size_t nbytes = XPM_COLOR_CACHE_BUCKETS * sizeof *xpm_color_cache;
4342 xpm_color_cache = xzalloc (nbytes);
4343 init_color_table ();
4344
4345 if (attrs->valuemask & XpmColorSymbols)
4346 {
4347 int i;
4348 XColor color;
4349
4350 for (i = 0; i < attrs->numsymbols; ++i)
4351 if (x_parse_color (f, attrs->colorsymbols[i].value, &color))
4352 {
4353 color.pixel = lookup_rgb_color (f, color.red, color.green,
4354 color.blue);
4355 xpm_cache_color (f, attrs->colorsymbols[i].name, &color, -1);
4356 }
4357 }
4358 }
4359
4360 /* Free the color cache. */
4361
4362 static void
xpm_free_color_cache(void)4363 xpm_free_color_cache (void)
4364 {
4365 struct xpm_cached_color *p, *next;
4366 int i;
4367
4368 for (i = 0; i < XPM_COLOR_CACHE_BUCKETS; ++i)
4369 for (p = xpm_color_cache[i]; p; p = next)
4370 {
4371 next = p->next;
4372 xfree (p);
4373 }
4374
4375 xfree (xpm_color_cache);
4376 xpm_color_cache = NULL;
4377 free_color_table ();
4378 }
4379
4380 /* Return the bucket index for color named COLOR_NAME in the color
4381 cache. */
4382
4383 static int
xpm_color_bucket(char * color_name)4384 xpm_color_bucket (char *color_name)
4385 {
4386 EMACS_UINT hash = hash_string (color_name, strlen (color_name));
4387 return hash % XPM_COLOR_CACHE_BUCKETS;
4388 }
4389
4390
4391 /* On frame F, cache values COLOR for color with name COLOR_NAME.
4392 BUCKET, if >= 0, is a precomputed bucket index. Value is the cache
4393 entry added. */
4394
4395 static struct xpm_cached_color *
xpm_cache_color(struct frame * f,char * color_name,XColor * color,int bucket)4396 xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
4397 {
4398 size_t nbytes;
4399 struct xpm_cached_color *p;
4400
4401 if (bucket < 0)
4402 bucket = xpm_color_bucket (color_name);
4403
4404 nbytes = FLEXSIZEOF (struct xpm_cached_color, name, strlen (color_name) + 1);
4405 p = xmalloc (nbytes);
4406 strcpy (p->name, color_name);
4407 p->color = *color;
4408 p->next = xpm_color_cache[bucket];
4409 xpm_color_cache[bucket] = p;
4410 return p;
4411 }
4412
4413 /* Look up color COLOR_NAME for frame F in the color cache. If found,
4414 return the cached definition in *COLOR. Otherwise, make a new
4415 entry in the cache and allocate the color. Value is false if color
4416 allocation failed. */
4417
4418 static bool
xpm_lookup_color(struct frame * f,char * color_name,XColor * color)4419 xpm_lookup_color (struct frame *f, char *color_name, XColor *color)
4420 {
4421 struct xpm_cached_color *p;
4422 int h = xpm_color_bucket (color_name);
4423
4424 for (p = xpm_color_cache[h]; p; p = p->next)
4425 if (strcmp (p->name, color_name) == 0)
4426 break;
4427
4428 if (p != NULL)
4429 *color = p->color;
4430 else if (x_parse_color (f, color_name, color))
4431 {
4432 color->pixel = lookup_rgb_color (f, color->red, color->green,
4433 color->blue);
4434 p = xpm_cache_color (f, color_name, color, h);
4435 }
4436 /* You get `opaque' at least from ImageMagick converting pbm to xpm
4437 with transparency, and it's useful. */
4438 else if (strcmp ("opaque", color_name) == 0)
4439 {
4440 memset (color, 0, sizeof (XColor)); /* Is this necessary/correct? */
4441 color->pixel = FRAME_FOREGROUND_PIXEL (f);
4442 p = xpm_cache_color (f, color_name, color, h);
4443 }
4444
4445 return p != NULL;
4446 }
4447
4448
4449 /* Callback for allocating color COLOR_NAME. Called from the XPM lib.
4450 CLOSURE is a pointer to the frame on which we allocate the
4451 color. Return in *COLOR the allocated color. Value is non-zero
4452 if successful. */
4453
4454 static int
xpm_alloc_color(Display * dpy,Colormap cmap,char * color_name,XColor * color,void * closure)4455 xpm_alloc_color (Display *dpy, Colormap cmap, char *color_name, XColor *color,
4456 void *closure)
4457 {
4458 return xpm_lookup_color (closure, color_name, color);
4459 }
4460
4461
4462 /* Callback for freeing NPIXELS colors contained in PIXELS. CLOSURE
4463 is a pointer to the frame on which we allocate the color. Value is
4464 non-zero if successful. */
4465
4466 static int
xpm_free_colors(Display * dpy,Colormap cmap,Pixel * pixels,int npixels,void * closure)4467 xpm_free_colors (Display *dpy, Colormap cmap, Pixel *pixels, int npixels, void *closure)
4468 {
4469 return 1;
4470 }
4471
4472 #endif /* ALLOC_XPM_COLORS */
4473
4474
4475 #ifdef WINDOWSNT
4476
4477 /* XPM library details. */
4478
4479 DEF_DLL_FN (void, XpmFreeAttributes, (XpmAttributes *));
4480 DEF_DLL_FN (int, XpmCreateImageFromBuffer,
4481 (Display *, char *, xpm_XImage **,
4482 xpm_XImage **, XpmAttributes *));
4483 DEF_DLL_FN (int, XpmReadFileToImage,
4484 (Display *, char *, xpm_XImage **,
4485 xpm_XImage **, XpmAttributes *));
4486 DEF_DLL_FN (void, XImageFree, (xpm_XImage *));
4487
4488 static bool
init_xpm_functions(void)4489 init_xpm_functions (void)
4490 {
4491 HMODULE library;
4492
4493 if (!(library = w32_delayed_load (Qxpm)))
4494 return 0;
4495
4496 LOAD_DLL_FN (library, XpmFreeAttributes);
4497 LOAD_DLL_FN (library, XpmCreateImageFromBuffer);
4498 LOAD_DLL_FN (library, XpmReadFileToImage);
4499 LOAD_DLL_FN (library, XImageFree);
4500 return 1;
4501 }
4502
4503 # undef XImageFree
4504 # undef XpmCreateImageFromBuffer
4505 # undef XpmFreeAttributes
4506 # undef XpmReadFileToImage
4507
4508 # define XImageFree fn_XImageFree
4509 # define XpmCreateImageFromBuffer fn_XpmCreateImageFromBuffer
4510 # define XpmFreeAttributes fn_XpmFreeAttributes
4511 # define XpmReadFileToImage fn_XpmReadFileToImage
4512
4513 #endif /* WINDOWSNT */
4514
4515 #if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
4516 /* Value is true if COLOR_SYMBOLS is a valid color symbols list
4517 for XPM images. Such a list must consist of conses whose car and
4518 cdr are strings. */
4519
4520 static bool
xpm_valid_color_symbols_p(Lisp_Object color_symbols)4521 xpm_valid_color_symbols_p (Lisp_Object color_symbols)
4522 {
4523 while (CONSP (color_symbols))
4524 {
4525 Lisp_Object sym = XCAR (color_symbols);
4526 if (!CONSP (sym)
4527 || !STRINGP (XCAR (sym))
4528 || !STRINGP (XCDR (sym)))
4529 break;
4530 color_symbols = XCDR (color_symbols);
4531 }
4532
4533 return NILP (color_symbols);
4534 }
4535
4536 /* Value is true if OBJECT is a valid XPM image specification. */
4537
4538 static bool
xpm_image_p(Lisp_Object object)4539 xpm_image_p (Lisp_Object object)
4540 {
4541 struct image_keyword fmt[XPM_LAST];
4542 memcpy (fmt, xpm_format, sizeof fmt);
4543 return (parse_image_spec (object, fmt, XPM_LAST, Qxpm)
4544 /* Either `:file' or `:data' must be present. */
4545 && fmt[XPM_FILE].count + fmt[XPM_DATA].count == 1
4546 /* Either no `:color-symbols' or it's a list of conses
4547 whose car and cdr are strings. */
4548 && (! fmt[XPM_COLOR_SYMBOLS].count
4549 || xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
4550 }
4551 #endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU || HAVE_PGTK */
4552
4553 #endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU */
4554
4555 #if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
4556 ptrdiff_t
x_create_bitmap_from_xpm_data(struct frame * f,const char ** bits)4557 x_create_bitmap_from_xpm_data (struct frame *f, const char **bits)
4558 {
4559 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
4560 ptrdiff_t id;
4561 int rc;
4562 XpmAttributes attrs;
4563 Pixmap bitmap, mask;
4564
4565 memset (&attrs, 0, sizeof attrs);
4566
4567 attrs.visual = FRAME_X_VISUAL (f);
4568 attrs.colormap = FRAME_X_COLORMAP (f);
4569 attrs.valuemask |= XpmVisual;
4570 attrs.valuemask |= XpmColormap;
4571
4572 #ifdef ALLOC_XPM_COLORS
4573 attrs.color_closure = f;
4574 attrs.alloc_color = xpm_alloc_color;
4575 attrs.free_colors = xpm_free_colors;
4576 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
4577 xpm_init_color_cache (f, &attrs);
4578 #endif
4579
4580 rc = XpmCreatePixmapFromData (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
4581 (char **) bits, &bitmap, &mask, &attrs);
4582 if (rc != XpmSuccess)
4583 {
4584 XpmFreeAttributes (&attrs);
4585 return -1;
4586 }
4587
4588 id = image_allocate_bitmap_record (f);
4589 dpyinfo->bitmaps[id - 1].pixmap = bitmap;
4590 dpyinfo->bitmaps[id - 1].have_mask = true;
4591 dpyinfo->bitmaps[id - 1].mask = mask;
4592 dpyinfo->bitmaps[id - 1].file = NULL;
4593 dpyinfo->bitmaps[id - 1].height = attrs.height;
4594 dpyinfo->bitmaps[id - 1].width = attrs.width;
4595 dpyinfo->bitmaps[id - 1].depth = attrs.depth;
4596 dpyinfo->bitmaps[id - 1].refcount = 1;
4597 #ifdef USE_CAIRO
4598 dpyinfo->bitmaps[id - 1].stipple = NULL;
4599 #endif /* USE_CAIRO */
4600
4601 #ifdef ALLOC_XPM_COLORS
4602 xpm_free_color_cache ();
4603 #endif
4604 XpmFreeAttributes (&attrs);
4605 return id;
4606 }
4607 #endif /* defined (HAVE_XPM) && defined (HAVE_X_WINDOWS) */
4608
4609 /* Load image IMG which will be displayed on frame F. Value is
4610 true if successful. */
4611
4612 #if defined HAVE_XPM && !defined USE_CAIRO
4613
4614 static bool
xpm_load(struct frame * f,struct image * img)4615 xpm_load (struct frame *f, struct image *img)
4616 {
4617 int rc;
4618 XpmAttributes attrs;
4619 Lisp_Object specified_file, color_symbols;
4620 USE_SAFE_ALLOCA;
4621
4622 #ifdef HAVE_NTGUI
4623 HDC hdc;
4624 xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
4625 #endif /* HAVE_NTGUI */
4626
4627 /* Configure the XPM lib. Use the visual of frame F. Allocate
4628 close colors. Return colors allocated. */
4629 memset (&attrs, 0, sizeof attrs);
4630
4631 #ifndef HAVE_NTGUI
4632 attrs.visual = FRAME_X_VISUAL (f);
4633 attrs.colormap = FRAME_X_COLORMAP (f);
4634 attrs.valuemask |= XpmVisual;
4635 attrs.valuemask |= XpmColormap;
4636 #endif /* HAVE_NTGUI */
4637
4638 #ifdef ALLOC_XPM_COLORS
4639 /* Allocate colors with our own functions which handle
4640 failing color allocation more gracefully. */
4641 attrs.color_closure = f;
4642 attrs.alloc_color = xpm_alloc_color;
4643 attrs.free_colors = xpm_free_colors;
4644 attrs.valuemask |= XpmAllocColor | XpmFreeColors | XpmColorClosure;
4645 #else /* not ALLOC_XPM_COLORS */
4646 /* Let the XPM lib allocate colors. */
4647 attrs.valuemask |= XpmReturnAllocPixels;
4648 #ifdef XpmAllocCloseColors
4649 attrs.alloc_close_colors = 1;
4650 attrs.valuemask |= XpmAllocCloseColors;
4651 #else /* not XpmAllocCloseColors */
4652 attrs.closeness = 600;
4653 attrs.valuemask |= XpmCloseness;
4654 #endif /* not XpmAllocCloseColors */
4655 #endif /* ALLOC_XPM_COLORS */
4656
4657 /* If image specification contains symbolic color definitions, add
4658 these to `attrs'. */
4659 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
4660 if (CONSP (color_symbols))
4661 {
4662 Lisp_Object tail;
4663 XpmColorSymbol *xpm_syms;
4664 ptrdiff_t i, size;
4665
4666 attrs.valuemask |= XpmColorSymbols;
4667
4668 /* Count number of symbols. */
4669 attrs.numsymbols = 0;
4670 for (tail = color_symbols; CONSP (tail); tail = XCDR (tail))
4671 ++attrs.numsymbols;
4672
4673 /* Allocate an XpmColorSymbol array. */
4674 SAFE_NALLOCA (xpm_syms, 1, attrs.numsymbols);
4675 size = attrs.numsymbols * sizeof *xpm_syms;
4676 memset (xpm_syms, 0, size);
4677 attrs.colorsymbols = xpm_syms;
4678
4679 /* Fill the color symbol array. */
4680 for (tail = color_symbols, i = 0;
4681 CONSP (tail);
4682 ++i, tail = XCDR (tail))
4683 {
4684 Lisp_Object name;
4685 Lisp_Object color;
4686 char *empty_string = (char *) "";
4687
4688 if (!CONSP (XCAR (tail)))
4689 {
4690 xpm_syms[i].name = empty_string;
4691 xpm_syms[i].value = empty_string;
4692 continue;
4693 }
4694 name = XCAR (XCAR (tail));
4695 color = XCDR (XCAR (tail));
4696 if (STRINGP (name))
4697 SAFE_ALLOCA_STRING (xpm_syms[i].name, name);
4698 else
4699 xpm_syms[i].name = empty_string;
4700 if (STRINGP (color))
4701 SAFE_ALLOCA_STRING (xpm_syms[i].value, color);
4702 else
4703 xpm_syms[i].value = empty_string;
4704 }
4705 }
4706
4707 /* Create a pixmap for the image, either from a file, or from a
4708 string buffer containing data in the same format as an XPM file. */
4709 #ifdef ALLOC_XPM_COLORS
4710 xpm_init_color_cache (f, &attrs);
4711 #endif
4712
4713 specified_file = image_spec_value (img->spec, QCfile, NULL);
4714
4715 #ifdef HAVE_NTGUI
4716 {
4717 HDC frame_dc = get_frame_dc (f);
4718 hdc = CreateCompatibleDC (frame_dc);
4719 release_frame_dc (f, frame_dc);
4720 }
4721 #endif /* HAVE_NTGUI */
4722
4723 if (STRINGP (specified_file))
4724 {
4725 Lisp_Object file = image_find_image_file (specified_file);
4726 if (!STRINGP (file))
4727 {
4728 image_error ("Cannot find image file `%s'", specified_file);
4729 #ifdef ALLOC_XPM_COLORS
4730 xpm_free_color_cache ();
4731 #endif
4732 SAFE_FREE ();
4733 return 0;
4734 }
4735
4736 file = ENCODE_FILE (file);
4737 #ifdef HAVE_NTGUI
4738 #ifdef WINDOWSNT
4739 /* FILE is encoded in UTF-8, but image libraries on Windows
4740 support neither UTF-8 nor UTF-16 encoded file names. So we
4741 need to re-encode it in ANSI. */
4742 file = ansi_encode_filename (file);
4743 #endif
4744 /* XpmReadFileToPixmap is not available in the Windows port of
4745 libxpm. But XpmReadFileToImage almost does what we want. */
4746 rc = XpmReadFileToImage (&hdc, SSDATA (file),
4747 &xpm_image, &xpm_mask,
4748 &attrs);
4749 #else
4750 rc = XpmReadFileToImage (FRAME_X_DISPLAY (f), SSDATA (file),
4751 &img->ximg, &img->mask_img,
4752 &attrs);
4753 #endif /* HAVE_NTGUI */
4754 }
4755 else
4756 {
4757 Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
4758 if (!STRINGP (buffer))
4759 {
4760 image_error ("Invalid image data `%s'", buffer);
4761 #ifdef ALLOC_XPM_COLORS
4762 xpm_free_color_cache ();
4763 #endif
4764 SAFE_FREE ();
4765 return 0;
4766 }
4767 #ifdef HAVE_NTGUI
4768 /* XpmCreatePixmapFromBuffer is not available in the Windows port
4769 of libxpm. But XpmCreateImageFromBuffer almost does what we want. */
4770 rc = XpmCreateImageFromBuffer (&hdc, SSDATA (buffer),
4771 &xpm_image, &xpm_mask,
4772 &attrs);
4773 #else
4774 rc = XpmCreateImageFromBuffer (FRAME_X_DISPLAY (f), SSDATA (buffer),
4775 &img->ximg, &img->mask_img,
4776 &attrs);
4777 #endif /* HAVE_NTGUI */
4778 }
4779
4780 #ifdef HAVE_X_WINDOWS
4781 if (rc == XpmSuccess)
4782 {
4783 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
4784 img->ximg->width, img->ximg->height,
4785 img->ximg->depth);
4786 if (img->pixmap == NO_PIXMAP)
4787 {
4788 image_clear_image (f, img);
4789 rc = XpmNoMemory;
4790 }
4791 else
4792 {
4793 # if !defined USE_CAIRO && defined HAVE_XRENDER
4794 img->picture = x_create_xrender_picture (f, img->pixmap,
4795 img->ximg->depth);
4796 # endif
4797 if (img->mask_img)
4798 {
4799 img->mask = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
4800 img->mask_img->width,
4801 img->mask_img->height,
4802 img->mask_img->depth);
4803 if (img->mask == NO_PIXMAP)
4804 {
4805 image_clear_image (f, img);
4806 rc = XpmNoMemory;
4807 }
4808 # if !defined USE_CAIRO && defined HAVE_XRENDER
4809 else
4810 img->mask_picture = x_create_xrender_picture
4811 (f, img->mask, img->mask_img->depth);
4812 # endif
4813 }
4814 }
4815 }
4816 #endif
4817
4818 if (rc == XpmSuccess)
4819 {
4820 #if defined (COLOR_TABLE_SUPPORT) && defined (ALLOC_XPM_COLORS)
4821 img->colors = colors_in_color_table (&img->ncolors);
4822 #else /* not ALLOC_XPM_COLORS */
4823 int i;
4824
4825 #ifdef HAVE_NTGUI
4826 /* W32 XPM uses XImage to wrap what W32 Emacs calls a Pixmap,
4827 plus some duplicate attributes. */
4828 if (xpm_image && xpm_image->bitmap)
4829 {
4830 img->pixmap = xpm_image->bitmap;
4831 /* XImageFree in libXpm frees XImage struct without destroying
4832 the bitmap, which is what we want. */
4833 XImageFree (xpm_image);
4834 }
4835 if (xpm_mask && xpm_mask->bitmap)
4836 {
4837 /* The mask appears to be inverted compared with what we expect.
4838 TODO: invert our expectations. See other places where we
4839 have to invert bits because our idea of masks is backwards. */
4840 HGDIOBJ old_obj;
4841 old_obj = SelectObject (hdc, xpm_mask->bitmap);
4842
4843 PatBlt (hdc, 0, 0, xpm_mask->width, xpm_mask->height, DSTINVERT);
4844 SelectObject (hdc, old_obj);
4845
4846 img->mask = xpm_mask->bitmap;
4847 XImageFree (xpm_mask);
4848 DeleteDC (hdc);
4849 }
4850
4851 DeleteDC (hdc);
4852 #endif /* HAVE_NTGUI */
4853
4854 /* Remember allocated colors. */
4855 img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
4856 img->ncolors = attrs.nalloc_pixels;
4857 for (i = 0; i < attrs.nalloc_pixels; ++i)
4858 {
4859 img->colors[i] = attrs.alloc_pixels[i];
4860 #ifdef DEBUG_X_COLORS
4861 register_color (img->colors[i]);
4862 #endif
4863 }
4864 #endif /* not ALLOC_XPM_COLORS */
4865
4866 img->width = attrs.width;
4867 img->height = attrs.height;
4868 eassert (img->width > 0 && img->height > 0);
4869
4870 /* The call to XpmFreeAttributes below frees attrs.alloc_pixels. */
4871 XpmFreeAttributes (&attrs);
4872
4873 #ifdef HAVE_X_WINDOWS
4874 /* Maybe fill in the background field while we have ximg handy. */
4875 IMAGE_BACKGROUND (img, f, img->ximg);
4876 if (img->mask_img)
4877 /* Fill in the background_transparent field while we have the
4878 mask handy. */
4879 image_background_transparent (img, f, img->mask_img);
4880 #endif
4881 }
4882 else
4883 {
4884 #ifdef HAVE_NTGUI
4885 DeleteDC (hdc);
4886 #endif /* HAVE_NTGUI */
4887
4888 switch (rc)
4889 {
4890 case XpmOpenFailed:
4891 image_error ("Error opening XPM file (%s)", img->spec);
4892 break;
4893
4894 case XpmFileInvalid:
4895 image_error ("Invalid XPM file (%s)", img->spec);
4896 break;
4897
4898 case XpmNoMemory:
4899 image_error ("Out of memory (%s)", img->spec);
4900 break;
4901
4902 case XpmColorFailed:
4903 image_error ("Color allocation error (%s)", img->spec);
4904 break;
4905
4906 default:
4907 image_error ("Unknown error (%s)", img->spec);
4908 break;
4909 }
4910 }
4911
4912 #ifdef ALLOC_XPM_COLORS
4913 xpm_free_color_cache ();
4914 #endif
4915 SAFE_FREE ();
4916 return rc == XpmSuccess;
4917 }
4918
4919 #endif /* HAVE_XPM && !USE_CAIRO */
4920
4921 #if (defined USE_CAIRO && defined HAVE_XPM) \
4922 || (defined HAVE_NS && !defined HAVE_XPM) \
4923 || (defined HAVE_HAIKU && !defined HAVE_XPM) \
4924 || (defined HAVE_PGTK && !defined HAVE_XPM)
4925
4926 /* XPM support functions for NS and Haiku where libxpm is not available, and for
4927 Cairo. Only XPM version 3 (without any extensions) is supported. */
4928
4929 static void xpm_put_color_table_v (Lisp_Object, const char *,
4930 int, Lisp_Object);
4931 static Lisp_Object xpm_get_color_table_v (Lisp_Object, const char *, int);
4932 static void xpm_put_color_table_h (Lisp_Object, const char *,
4933 int, Lisp_Object);
4934 static Lisp_Object xpm_get_color_table_h (Lisp_Object, const char *, int);
4935
4936 /* Tokens returned from xpm_scan. */
4937
4938 enum xpm_token
4939 {
4940 XPM_TK_IDENT = 256,
4941 XPM_TK_STRING,
4942 XPM_TK_EOF
4943 };
4944
4945 /* Scan an XPM data and return a character (< 256) or a token defined
4946 by enum xpm_token above. *S and END are the start (inclusive) and
4947 the end (exclusive) addresses of the data, respectively. Advance
4948 *S while scanning. If token is either XPM_TK_IDENT or
4949 XPM_TK_STRING, *BEG and *LEN are set to the start address and the
4950 length of the corresponding token, respectively. */
4951
4952 static int
xpm_scan(const char ** s,const char * end,const char ** beg,ptrdiff_t * len)4953 xpm_scan (const char **s, const char *end, const char **beg, ptrdiff_t *len)
4954 {
4955 unsigned char c;
4956
4957 while (*s < end)
4958 {
4959 /* Skip white-space. */
4960 do
4961 c = *(*s)++;
4962 while (c_isspace (c) && *s < end);
4963
4964 /* gnus-pointer.xpm uses '-' in its identifier.
4965 sb-dir-plus.xpm uses '+' in its identifier. */
4966 if (c_isalpha (c) || c == '_' || c == '-' || c == '+')
4967 {
4968 *beg = *s - 1;
4969 while (*s < end
4970 && (c = **s, c_isalnum (c)
4971 || c == '_' || c == '-' || c == '+'))
4972 ++*s;
4973 *len = *s - *beg;
4974 return XPM_TK_IDENT;
4975 }
4976 else if (c == '"')
4977 {
4978 *beg = *s;
4979 while (*s < end && **s != '"')
4980 ++*s;
4981 *len = *s - *beg;
4982 if (*s < end)
4983 ++*s;
4984 return XPM_TK_STRING;
4985 }
4986 else if (c == '/')
4987 {
4988 if (*s < end && **s == '*')
4989 {
4990 /* C-style comment. */
4991 ++*s;
4992 do
4993 {
4994 while (*s < end && *(*s)++ != '*')
4995 ;
4996 }
4997 while (*s < end && **s != '/');
4998 if (*s < end)
4999 ++*s;
5000 }
5001 else
5002 return c;
5003 }
5004 else
5005 return c;
5006 }
5007
5008 return XPM_TK_EOF;
5009 }
5010
5011 /* Functions for color table lookup in XPM data. A key is a string
5012 specifying the color of each pixel in XPM data. A value is either
5013 an integer that specifies a pixel color, Qt that specifies
5014 transparency, or Qnil for the unspecified color. If the length of
5015 the key string is one, a vector is used as a table. Otherwise, a
5016 hash table is used. */
5017
5018 static Lisp_Object
xpm_make_color_table_v(void (** put_func)(Lisp_Object,const char *,int,Lisp_Object),Lisp_Object (** get_func)(Lisp_Object,const char *,int))5019 xpm_make_color_table_v (void (**put_func) (Lisp_Object, const char *, int,
5020 Lisp_Object),
5021 Lisp_Object (**get_func) (Lisp_Object, const char *,
5022 int))
5023 {
5024 *put_func = xpm_put_color_table_v;
5025 *get_func = xpm_get_color_table_v;
5026 return make_nil_vector (256);
5027 }
5028
5029 static void
xpm_put_color_table_v(Lisp_Object color_table,const char * chars_start,int chars_len,Lisp_Object color)5030 xpm_put_color_table_v (Lisp_Object color_table,
5031 const char *chars_start,
5032 int chars_len,
5033 Lisp_Object color)
5034 {
5035 unsigned char uc = *chars_start;
5036 ASET (color_table, uc, color);
5037 }
5038
5039 static Lisp_Object
xpm_get_color_table_v(Lisp_Object color_table,const char * chars_start,int chars_len)5040 xpm_get_color_table_v (Lisp_Object color_table,
5041 const char *chars_start,
5042 int chars_len)
5043 {
5044 unsigned char uc = *chars_start;
5045 return AREF (color_table, uc);
5046 }
5047
5048 static Lisp_Object
xpm_make_color_table_h(void (** put_func)(Lisp_Object,const char *,int,Lisp_Object),Lisp_Object (** get_func)(Lisp_Object,const char *,int))5049 xpm_make_color_table_h (void (**put_func) (Lisp_Object, const char *, int,
5050 Lisp_Object),
5051 Lisp_Object (**get_func) (Lisp_Object, const char *,
5052 int))
5053 {
5054 *put_func = xpm_put_color_table_h;
5055 *get_func = xpm_get_color_table_h;
5056 return make_hash_table (hashtest_equal, DEFAULT_HASH_SIZE,
5057 DEFAULT_REHASH_SIZE, DEFAULT_REHASH_THRESHOLD,
5058 Qnil, false);
5059 }
5060
5061 static void
xpm_put_color_table_h(Lisp_Object color_table,const char * chars_start,int chars_len,Lisp_Object color)5062 xpm_put_color_table_h (Lisp_Object color_table,
5063 const char *chars_start,
5064 int chars_len,
5065 Lisp_Object color)
5066 {
5067 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
5068 Lisp_Object chars = make_unibyte_string (chars_start, chars_len), hash_code;
5069
5070 hash_lookup (table, chars, &hash_code);
5071 hash_put (table, chars, color, hash_code);
5072 }
5073
5074 static Lisp_Object
xpm_get_color_table_h(Lisp_Object color_table,const char * chars_start,int chars_len)5075 xpm_get_color_table_h (Lisp_Object color_table,
5076 const char *chars_start,
5077 int chars_len)
5078 {
5079 struct Lisp_Hash_Table *table = XHASH_TABLE (color_table);
5080 ptrdiff_t i =
5081 hash_lookup (table, make_unibyte_string (chars_start, chars_len), NULL);
5082
5083 return i >= 0 ? HASH_VALUE (table, i) : Qnil;
5084 }
5085
5086 enum xpm_color_key {
5087 XPM_COLOR_KEY_S,
5088 XPM_COLOR_KEY_M,
5089 XPM_COLOR_KEY_G4,
5090 XPM_COLOR_KEY_G,
5091 XPM_COLOR_KEY_C
5092 };
5093
5094 static const char xpm_color_key_strings[][4] = {"s", "m", "g4", "g", "c"};
5095
5096 static int
xpm_str_to_color_key(const char * s)5097 xpm_str_to_color_key (const char *s)
5098 {
5099 int i;
5100
5101 for (i = 0; i < ARRAYELTS (xpm_color_key_strings); i++)
5102 if (strcmp (xpm_color_key_strings[i], s) == 0)
5103 return i;
5104 return -1;
5105 }
5106
5107 static bool
xpm_load_image(struct frame * f,struct image * img,const char * contents,const char * end)5108 xpm_load_image (struct frame *f,
5109 struct image *img,
5110 const char *contents,
5111 const char *end)
5112 {
5113 const char *s = contents, *beg, *str;
5114 char buffer[BUFSIZ];
5115 int width, height, x, y;
5116 int num_colors, chars_per_pixel;
5117 ptrdiff_t len;
5118 int LA1;
5119 void (*put_color_table) (Lisp_Object, const char *, int, Lisp_Object);
5120 Lisp_Object (*get_color_table) (Lisp_Object, const char *, int);
5121 Lisp_Object frame, color_symbols, color_table;
5122 int best_key;
5123 #if !defined (HAVE_NS)
5124 bool have_mask = false;
5125 #endif
5126 Emacs_Pix_Container ximg = NULL, mask_img = NULL;
5127
5128 #define match() \
5129 LA1 = xpm_scan (&s, end, &beg, &len)
5130
5131 #define expect(TOKEN) \
5132 do \
5133 { \
5134 if (LA1 != (TOKEN)) \
5135 goto failure; \
5136 match (); \
5137 } \
5138 while (0)
5139
5140 #define expect_ident(IDENT) \
5141 if (LA1 == XPM_TK_IDENT \
5142 && strlen ((IDENT)) == len && memcmp ((IDENT), beg, len) == 0) \
5143 match (); \
5144 else \
5145 goto failure
5146
5147 if (!(end - s >= 9 && memcmp (s, "/* XPM */", 9) == 0))
5148 goto failure;
5149 s += 9;
5150 match ();
5151 expect_ident ("static");
5152 expect_ident ("char");
5153 expect ('*');
5154 expect (XPM_TK_IDENT);
5155 expect ('[');
5156 expect (']');
5157 expect ('=');
5158 expect ('{');
5159 expect (XPM_TK_STRING);
5160 if (len >= BUFSIZ)
5161 goto failure;
5162 memcpy (buffer, beg, len);
5163 buffer[len] = '\0';
5164 if (sscanf (buffer, "%d %d %d %d", &width, &height,
5165 &num_colors, &chars_per_pixel) != 4
5166 || width <= 0 || height <= 0
5167 || num_colors <= 0 || chars_per_pixel <= 0)
5168 goto failure;
5169
5170 if (!check_image_size (f, width, height))
5171 {
5172 image_size_error ();
5173 goto failure;
5174 }
5175
5176 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)
5177 #ifndef HAVE_NS
5178 || !image_create_x_image_and_pixmap (f, img, width, height, 1,
5179 &mask_img, 1)
5180 #endif
5181 )
5182 {
5183 image_error ("Image too large");
5184 goto failure;
5185 }
5186
5187 expect (',');
5188
5189 XSETFRAME (frame, f);
5190 if (!NILP (Fxw_display_color_p (frame)))
5191 best_key = XPM_COLOR_KEY_C;
5192 else if (!NILP (Fx_display_grayscale_p (frame)))
5193 best_key = (XFIXNAT (Fx_display_planes (frame)) > 2
5194 ? XPM_COLOR_KEY_G : XPM_COLOR_KEY_G4);
5195 else
5196 best_key = XPM_COLOR_KEY_M;
5197
5198 color_symbols = image_spec_value (img->spec, QCcolor_symbols, NULL);
5199 if (chars_per_pixel == 1)
5200 color_table = xpm_make_color_table_v (&put_color_table,
5201 &get_color_table);
5202 else
5203 color_table = xpm_make_color_table_h (&put_color_table,
5204 &get_color_table);
5205
5206 while (num_colors-- > 0)
5207 {
5208 char *color, *max_color = NULL;
5209 int key, next_key, max_key = 0;
5210 Lisp_Object symbol_color = Qnil, color_val;
5211 Emacs_Color cdef;
5212
5213 expect (XPM_TK_STRING);
5214 if (len <= chars_per_pixel || len >= BUFSIZ + chars_per_pixel)
5215 goto failure;
5216 memcpy (buffer, beg + chars_per_pixel, len - chars_per_pixel);
5217 buffer[len - chars_per_pixel] = '\0';
5218
5219 str = strtok (buffer, " \t");
5220 if (str == NULL)
5221 goto failure;
5222 key = xpm_str_to_color_key (str);
5223 if (key < 0)
5224 goto failure;
5225 do
5226 {
5227 color = strtok (NULL, " \t");
5228 if (color == NULL)
5229 goto failure;
5230
5231 while ((str = strtok (NULL, " \t")) != NULL)
5232 {
5233 next_key = xpm_str_to_color_key (str);
5234 if (next_key >= 0)
5235 break;
5236 color[strlen (color)] = ' ';
5237 }
5238
5239 if (key == XPM_COLOR_KEY_S)
5240 {
5241 if (NILP (symbol_color))
5242 symbol_color = build_string (color);
5243 }
5244 else if (max_key < key && key <= best_key)
5245 {
5246 max_key = key;
5247 max_color = color;
5248 }
5249 key = next_key;
5250 }
5251 while (str);
5252
5253 color_val = Qnil;
5254 if (!NILP (color_symbols) && !NILP (symbol_color))
5255 {
5256 Lisp_Object specified_color = Fassoc (symbol_color, color_symbols, Qnil);
5257
5258 if (CONSP (specified_color) && STRINGP (XCDR (specified_color)))
5259 {
5260 if (xstrcasecmp (SSDATA (XCDR (specified_color)), "None") == 0)
5261 color_val = Qt;
5262 else if (FRAME_TERMINAL (f)->defined_color_hook
5263 (f, SSDATA (XCDR (specified_color)), &cdef, false, false))
5264 color_val
5265 = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green,
5266 cdef.blue));
5267 }
5268 }
5269 if (NILP (color_val) && max_color)
5270 {
5271 if (xstrcasecmp (max_color, "None") == 0)
5272 color_val = Qt;
5273 else if (FRAME_TERMINAL (f)->defined_color_hook
5274 (f, max_color, &cdef, false, false))
5275 color_val = make_fixnum (lookup_rgb_color (f, cdef.red, cdef.green,
5276 cdef.blue));
5277 }
5278 if (!NILP (color_val))
5279 (*put_color_table) (color_table, beg, chars_per_pixel, color_val);
5280
5281 expect (',');
5282 }
5283
5284 unsigned long frame_fg = FRAME_FOREGROUND_PIXEL (f);
5285 #ifdef USE_CAIRO
5286 {
5287 Emacs_Color color = {.pixel = frame_fg};
5288 FRAME_TERMINAL (f)->query_colors (f, &color, 1);
5289 frame_fg = lookup_rgb_color (f, color.red, color.green, color.blue);
5290 }
5291 #endif
5292 for (y = 0; y < height; y++)
5293 {
5294 expect (XPM_TK_STRING);
5295 str = beg;
5296 if (len < width * chars_per_pixel)
5297 goto failure;
5298 for (x = 0; x < width; x++, str += chars_per_pixel)
5299 {
5300 Lisp_Object color_val =
5301 (*get_color_table) (color_table, str, chars_per_pixel);
5302
5303 PUT_PIXEL (ximg, x, y,
5304 FIXNUMP (color_val) ? XFIXNUM (color_val) : frame_fg);
5305 #ifndef HAVE_NS
5306 PUT_PIXEL (mask_img, x, y,
5307 (!EQ (color_val, Qt) ? PIX_MASK_DRAW
5308 : (have_mask = true, PIX_MASK_RETAIN)));
5309 #else
5310 if (EQ (color_val, Qt))
5311 ns_set_alpha (ximg, x, y, 0);
5312 #endif
5313 }
5314 if (y + 1 < height)
5315 expect (',');
5316 }
5317
5318 img->width = width;
5319 img->height = height;
5320
5321 /* Maybe fill in the background field while we have ximg handy. */
5322 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
5323 IMAGE_BACKGROUND (img, f, ximg);
5324
5325 image_put_x_image (f, img, ximg, 0);
5326 #ifndef HAVE_NS
5327 if (have_mask)
5328 {
5329 /* Fill in the background_transparent field while we have the
5330 mask handy. */
5331 image_background_transparent (img, f, mask_img);
5332
5333 image_put_x_image (f, img, mask_img, 1);
5334 }
5335 else
5336 {
5337 image_destroy_x_image (mask_img);
5338 image_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
5339 }
5340 #endif
5341 return 1;
5342
5343 failure:
5344 image_error ("Invalid XPM3 file (%s)", img->spec);
5345 image_destroy_x_image (ximg);
5346 image_destroy_x_image (mask_img);
5347 image_clear_image (f, img);
5348 return 0;
5349
5350 #undef match
5351 #undef expect
5352 #undef expect_ident
5353 }
5354
5355 static bool
xpm_load(struct frame * f,struct image * img)5356 xpm_load (struct frame *f,
5357 struct image *img)
5358 {
5359 bool success_p = 0;
5360 Lisp_Object file_name;
5361
5362 /* If IMG->spec specifies a file name, create a non-file spec from it. */
5363 file_name = image_spec_value (img->spec, QCfile, NULL);
5364 if (STRINGP (file_name))
5365 {
5366 int fd;
5367 Lisp_Object file = image_find_image_fd (file_name, &fd);
5368 if (!STRINGP (file))
5369 {
5370 image_error ("Cannot find image file `%s'", file_name);
5371 return 0;
5372 }
5373
5374 ptrdiff_t size;
5375 char *contents = slurp_file (fd, &size);
5376 if (contents == NULL)
5377 {
5378 image_error ("Error loading XPM image `%s'", file);
5379 return 0;
5380 }
5381
5382 success_p = xpm_load_image (f, img, contents, contents + size);
5383 xfree (contents);
5384 }
5385 else
5386 {
5387 Lisp_Object data;
5388
5389 data = image_spec_value (img->spec, QCdata, NULL);
5390 if (!STRINGP (data))
5391 {
5392 image_error ("Invalid image data `%s'", data);
5393 return 0;
5394 }
5395 success_p = xpm_load_image (f, img, SSDATA (data),
5396 SSDATA (data) + SBYTES (data));
5397 }
5398
5399 return success_p;
5400 }
5401
5402 #endif /* HAVE_NS && !HAVE_XPM */
5403
5404
5405
5406 /***********************************************************************
5407 Color table
5408 ***********************************************************************/
5409
5410 #ifdef COLOR_TABLE_SUPPORT
5411
5412 /* An entry in the color table mapping an RGB color to a pixel color. */
5413
5414 struct ct_color
5415 {
5416 int r, g, b;
5417 unsigned long pixel;
5418
5419 /* Next in color table collision list. */
5420 struct ct_color *next;
5421 };
5422
5423 /* The bucket vector size to use. Must be prime. */
5424
5425 #define CT_SIZE 101
5426
5427 /* Value is a hash of the RGB color given by R, G, and B. */
5428
5429 static unsigned
ct_hash_rgb(unsigned r,unsigned g,unsigned b)5430 ct_hash_rgb (unsigned r, unsigned g, unsigned b)
5431 {
5432 return (r << 16) ^ (g << 8) ^ b;
5433 }
5434
5435 /* The color hash table. */
5436
5437 static struct ct_color **ct_table;
5438
5439 /* Number of entries in the color table. */
5440
5441 static int ct_colors_allocated;
5442 enum
5443 {
5444 ct_colors_allocated_max =
5445 min (INT_MAX,
5446 min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long))
5447 };
5448
5449 /* Initialize the color table. */
5450
5451 static void
init_color_table(void)5452 init_color_table (void)
5453 {
5454 int size = CT_SIZE * sizeof (*ct_table);
5455 ct_table = xzalloc (size);
5456 ct_colors_allocated = 0;
5457 }
5458
5459
5460 /* Free memory associated with the color table. */
5461
5462 static void
free_color_table(void)5463 free_color_table (void)
5464 {
5465 int i;
5466 struct ct_color *p, *next;
5467
5468 for (i = 0; i < CT_SIZE; ++i)
5469 for (p = ct_table[i]; p; p = next)
5470 {
5471 next = p->next;
5472 xfree (p);
5473 }
5474
5475 xfree (ct_table);
5476 ct_table = NULL;
5477 }
5478
5479
5480 /* Value is a pixel color for RGB color R, G, B on frame F. If an
5481 entry for that color already is in the color table, return the
5482 pixel color of that entry. Otherwise, allocate a new color for R,
5483 G, B, and make an entry in the color table. */
5484
5485 static unsigned long
lookup_rgb_color(struct frame * f,int r,int g,int b)5486 lookup_rgb_color (struct frame *f, int r, int g, int b)
5487 {
5488 unsigned hash = ct_hash_rgb (r, g, b);
5489 int i = hash % CT_SIZE;
5490 struct ct_color *p;
5491 Display_Info *dpyinfo;
5492
5493 /* Handle TrueColor visuals specially, which improves performance by
5494 two orders of magnitude. Freeing colors on TrueColor visuals is
5495 a nop, and pixel colors specify RGB values directly. See also
5496 the Xlib spec, chapter 3.1. */
5497 dpyinfo = FRAME_DISPLAY_INFO (f);
5498 if (dpyinfo->red_bits > 0)
5499 {
5500 /* Apply gamma-correction like normal color allocation does. */
5501 if (f->gamma)
5502 {
5503 XColor color;
5504 color.red = r, color.green = g, color.blue = b;
5505 gamma_correct (f, &color);
5506 r = color.red, g = color.green, b = color.blue;
5507 }
5508
5509 return x_make_truecolor_pixel (dpyinfo, r, g, b);
5510 }
5511
5512 for (p = ct_table[i]; p; p = p->next)
5513 if (p->r == r && p->g == g && p->b == b)
5514 break;
5515
5516 if (p == NULL)
5517 {
5518
5519 #ifdef HAVE_X_WINDOWS
5520 XColor color;
5521 Colormap cmap;
5522 bool rc;
5523 #else
5524 COLORREF color;
5525 #endif
5526
5527 if (ct_colors_allocated_max <= ct_colors_allocated)
5528 return FRAME_FOREGROUND_PIXEL (f);
5529
5530 #ifdef HAVE_X_WINDOWS
5531 color.red = r;
5532 color.green = g;
5533 color.blue = b;
5534
5535 cmap = FRAME_X_COLORMAP (f);
5536 rc = x_alloc_nearest_color (f, cmap, &color);
5537 if (rc)
5538 {
5539 ++ct_colors_allocated;
5540 p = xmalloc (sizeof *p);
5541 p->r = r;
5542 p->g = g;
5543 p->b = b;
5544 p->pixel = color.pixel;
5545 p->next = ct_table[i];
5546 ct_table[i] = p;
5547 }
5548 else
5549 return FRAME_FOREGROUND_PIXEL (f);
5550
5551 #else
5552 #ifdef HAVE_NTGUI
5553 color = PALETTERGB (r, g, b);
5554 #else
5555 color = RGB_TO_ULONG (r, g, b);
5556 #endif /* HAVE_NTGUI */
5557 ++ct_colors_allocated;
5558 p = xmalloc (sizeof *p);
5559 p->r = r;
5560 p->g = g;
5561 p->b = b;
5562 p->pixel = color;
5563 p->next = ct_table[i];
5564 ct_table[i] = p;
5565 #endif /* HAVE_X_WINDOWS */
5566
5567 }
5568
5569 return p->pixel;
5570 }
5571
5572
5573 /* Look up pixel color PIXEL which is used on frame F in the color
5574 table. If not already present, allocate it. Value is PIXEL. */
5575
5576 static unsigned long
lookup_pixel_color(struct frame * f,unsigned long pixel)5577 lookup_pixel_color (struct frame *f, unsigned long pixel)
5578 {
5579 int i = pixel % CT_SIZE;
5580 struct ct_color *p;
5581
5582 for (p = ct_table[i]; p; p = p->next)
5583 if (p->pixel == pixel)
5584 break;
5585
5586 if (p == NULL)
5587 {
5588 XColor color;
5589 Colormap cmap;
5590 bool rc;
5591
5592 if (ct_colors_allocated >= ct_colors_allocated_max)
5593 return FRAME_FOREGROUND_PIXEL (f);
5594
5595 #ifdef HAVE_X_WINDOWS
5596 cmap = FRAME_X_COLORMAP (f);
5597 color.pixel = pixel;
5598 x_query_colors (f, &color, 1);
5599 rc = x_alloc_nearest_color (f, cmap, &color);
5600 #else
5601 block_input ();
5602 cmap = DefaultColormapOfScreen (FRAME_X_SCREEN (f));
5603 color.pixel = pixel;
5604 XQueryColor (NULL, cmap, &color);
5605 rc = x_alloc_nearest_color (f, cmap, &color);
5606 unblock_input ();
5607 #endif /* HAVE_X_WINDOWS */
5608
5609 if (rc)
5610 {
5611 ++ct_colors_allocated;
5612
5613 p = xmalloc (sizeof *p);
5614 p->r = color.red;
5615 p->g = color.green;
5616 p->b = color.blue;
5617 p->pixel = pixel;
5618 p->next = ct_table[i];
5619 ct_table[i] = p;
5620 }
5621 else
5622 return FRAME_FOREGROUND_PIXEL (f);
5623 }
5624 return p->pixel;
5625 }
5626
5627
5628 /* Value is a vector of all pixel colors contained in the color table,
5629 allocated via xmalloc. Set *N to the number of colors. */
5630
5631 static unsigned long *
colors_in_color_table(int * n)5632 colors_in_color_table (int *n)
5633 {
5634 int i, j;
5635 struct ct_color *p;
5636 unsigned long *colors;
5637
5638 if (ct_colors_allocated == 0)
5639 {
5640 *n = 0;
5641 colors = NULL;
5642 }
5643 else
5644 {
5645 colors = xmalloc (ct_colors_allocated * sizeof *colors);
5646 *n = ct_colors_allocated;
5647
5648 for (i = j = 0; i < CT_SIZE; ++i)
5649 for (p = ct_table[i]; p; p = p->next)
5650 colors[j++] = p->pixel;
5651 }
5652
5653 return colors;
5654 }
5655
5656 #else /* COLOR_TABLE_SUPPORT */
5657
5658 static unsigned long
lookup_rgb_color(struct frame * f,int r,int g,int b)5659 lookup_rgb_color (struct frame *f, int r, int g, int b)
5660 {
5661 #ifdef HAVE_NTGUI
5662 return PALETTERGB (r >> 8, g >> 8, b >> 8);
5663 #elif defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
5664 return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
5665 #else
5666 xsignal1 (Qfile_error,
5667 build_string ("This Emacs mishandles this image file type"));
5668 #endif
5669 }
5670
5671 static void
init_color_table(void)5672 init_color_table (void)
5673 {
5674 }
5675 #endif /* COLOR_TABLE_SUPPORT */
5676
5677
5678 /***********************************************************************
5679 Algorithms
5680 ***********************************************************************/
5681
5682 /* Edge detection matrices for different edge-detection
5683 strategies. */
5684
5685 static int emboss_matrix[9] = {
5686 /* x - 1 x x + 1 */
5687 2, -1, 0, /* y - 1 */
5688 -1, 0, 1, /* y */
5689 0, 1, -2 /* y + 1 */
5690 };
5691
5692 static int laplace_matrix[9] = {
5693 /* x - 1 x x + 1 */
5694 1, 0, 0, /* y - 1 */
5695 0, 0, 0, /* y */
5696 0, 0, -1 /* y + 1 */
5697 };
5698
5699 /* Value is the intensity of the color whose red/green/blue values
5700 are R, G, and B. */
5701
5702 #define COLOR_INTENSITY(R, G, B) ((2 * (R) + 3 * (G) + (B)) / 6)
5703
5704
5705 /* On frame F, return an array of Emacs_Color structures describing image
5706 IMG->pixmap. Each Emacs_Color structure has its pixel color set. RGB_P
5707 means also fill the red/green/blue members of the Emacs_Color
5708 structures. Value is a pointer to the array of Emacs_Color structures,
5709 allocated with xmalloc; it must be freed by the caller. */
5710
5711 static Emacs_Color *
image_to_emacs_colors(struct frame * f,struct image * img,bool rgb_p)5712 image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
5713 {
5714 int x, y;
5715 Emacs_Color *colors, *p;
5716 Emacs_Pix_Context ximg;
5717 ptrdiff_t nbytes;
5718 #ifdef HAVE_NTGUI
5719 HGDIOBJ prev;
5720 #endif /* HAVE_NTGUI */
5721
5722 if (INT_MULTIPLY_WRAPV (sizeof *colors, img->width, &nbytes)
5723 || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes)
5724 || SIZE_MAX < nbytes)
5725 memory_full (SIZE_MAX);
5726 colors = xmalloc (nbytes);
5727
5728 /* Get the X image or create a memory device context for IMG. */
5729 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
5730
5731 /* Fill the `pixel' members of the Emacs_Color array. I wished there
5732 were an easy and portable way to circumvent XGetPixel. */
5733 p = colors;
5734 for (y = 0; y < img->height; ++y)
5735 {
5736 #if !defined USE_CAIRO && !defined HAVE_NS && !defined HAVE_HAIKU
5737 Emacs_Color *row = p;
5738 for (x = 0; x < img->width; ++x, ++p)
5739 p->pixel = GET_PIXEL (ximg, x, y);
5740 if (rgb_p)
5741 {
5742 FRAME_TERMINAL (f)->query_colors (f, row, img->width);
5743 }
5744 #else /* USE_CAIRO || HAVE_NS || HAVE_HAIKU */
5745 for (x = 0; x < img->width; ++x, ++p)
5746 {
5747 p->pixel = GET_PIXEL (ximg, x, y);
5748 if (rgb_p)
5749 {
5750 p->red = RED16_FROM_ULONG (p->pixel);
5751 p->green = GREEN16_FROM_ULONG (p->pixel);
5752 p->blue = BLUE16_FROM_ULONG (p->pixel);
5753 }
5754 }
5755 #endif /* USE_CAIRO || HAVE_NS */
5756 }
5757
5758 image_unget_x_image_or_dc (img, 0, ximg, prev);
5759
5760 return colors;
5761 }
5762
5763 #ifdef HAVE_NTGUI
5764
5765 /* Put a pixel of COLOR at position X, Y in XIMG. XIMG must have been
5766 created with CreateDIBSection, with the pointer to the bit values
5767 stored in ximg->data. */
5768
5769 static void
XPutPixel(XImage * ximg,int x,int y,COLORREF color)5770 XPutPixel (XImage *ximg, int x, int y, COLORREF color)
5771 {
5772 int width = ximg->info.bmiHeader.biWidth;
5773 unsigned char * pixel;
5774
5775 /* True color images. */
5776 if (ximg->info.bmiHeader.biBitCount == 24)
5777 {
5778 int rowbytes = width * 3;
5779 /* Ensure scanlines are aligned on 4 byte boundaries. */
5780 if (rowbytes % 4)
5781 rowbytes += 4 - (rowbytes % 4);
5782
5783 pixel = ximg->data + y * rowbytes + x * 3;
5784 /* Windows bitmaps are in BGR order. */
5785 *pixel = GetBValue (color);
5786 *(pixel + 1) = GetGValue (color);
5787 *(pixel + 2) = GetRValue (color);
5788 }
5789 /* Monochrome images. */
5790 else if (ximg->info.bmiHeader.biBitCount == 1)
5791 {
5792 int rowbytes = width / 8;
5793 /* Ensure scanlines are aligned on 4 byte boundaries. */
5794 if (rowbytes % 4)
5795 rowbytes += 4 - (rowbytes % 4);
5796 pixel = ximg->data + y * rowbytes + x / 8;
5797 /* Filter out palette info. */
5798 if (color & 0x00ffffff)
5799 *pixel = *pixel | (1 << x % 8);
5800 else
5801 *pixel = *pixel & ~(1 << x % 8);
5802 }
5803 else
5804 image_error ("XPutPixel: palette image not supported");
5805 }
5806
5807 #endif /* HAVE_NTGUI */
5808
5809 /* Create IMG->pixmap from an array COLORS of Emacs_Color structures, whose
5810 RGB members are set. F is the frame on which this all happens.
5811 COLORS will be freed; an existing IMG->pixmap will be freed, too. */
5812
5813 static void
image_from_emacs_colors(struct frame * f,struct image * img,Emacs_Color * colors)5814 image_from_emacs_colors (struct frame *f, struct image *img, Emacs_Color *colors)
5815 {
5816 int x, y;
5817 Emacs_Pix_Container oimg = NULL;
5818 Emacs_Color *p;
5819
5820 init_color_table ();
5821
5822 image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP | CLEAR_IMAGE_COLORS);
5823 image_create_x_image_and_pixmap (f, img, img->width, img->height, 0,
5824 &oimg, 0);
5825 p = colors;
5826 for (y = 0; y < img->height; ++y)
5827 for (x = 0; x < img->width; ++x, ++p)
5828 {
5829 unsigned long pixel;
5830 pixel = lookup_rgb_color (f, p->red, p->green, p->blue);
5831 PUT_PIXEL (oimg, x, y, pixel);
5832 }
5833
5834 xfree (colors);
5835
5836 image_put_x_image (f, img, oimg, 0);
5837 #ifdef COLOR_TABLE_SUPPORT
5838 img->colors = colors_in_color_table (&img->ncolors);
5839 free_color_table ();
5840 #endif /* COLOR_TABLE_SUPPORT */
5841 }
5842
5843
5844 /* On frame F, perform edge-detection on image IMG.
5845
5846 MATRIX is a nine-element array specifying the transformation
5847 matrix. See emboss_matrix for an example.
5848
5849 COLOR_ADJUST is a color adjustment added to each pixel of the
5850 outgoing image. */
5851
5852 static void
image_detect_edges(struct frame * f,struct image * img,int * matrix,int color_adjust)5853 image_detect_edges (struct frame *f, struct image *img,
5854 int *matrix, int color_adjust)
5855 {
5856 Emacs_Color *colors = image_to_emacs_colors (f, img, 1);
5857 Emacs_Color *new, *p;
5858 int x, y, i, sum;
5859 ptrdiff_t nbytes;
5860
5861 for (i = sum = 0; i < 9; ++i)
5862 sum += eabs (matrix[i]);
5863
5864 #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X))
5865
5866 if (INT_MULTIPLY_WRAPV (sizeof *new, img->width, &nbytes)
5867 || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes))
5868 memory_full (SIZE_MAX);
5869 new = xmalloc (nbytes);
5870
5871 for (y = 0; y < img->height; ++y)
5872 {
5873 p = COLOR (new, 0, y);
5874 p->red = p->green = p->blue = 0xffff/2;
5875 p = COLOR (new, img->width - 1, y);
5876 p->red = p->green = p->blue = 0xffff/2;
5877 }
5878
5879 for (x = 1; x < img->width - 1; ++x)
5880 {
5881 p = COLOR (new, x, 0);
5882 p->red = p->green = p->blue = 0xffff/2;
5883 p = COLOR (new, x, img->height - 1);
5884 p->red = p->green = p->blue = 0xffff/2;
5885 }
5886
5887 for (y = 1; y < img->height - 1; ++y)
5888 {
5889 p = COLOR (new, 1, y);
5890
5891 for (x = 1; x < img->width - 1; ++x, ++p)
5892 {
5893 int r, g, b, yy, xx;
5894
5895 r = g = b = i = 0;
5896 for (yy = y - 1; yy < y + 2; ++yy)
5897 for (xx = x - 1; xx < x + 2; ++xx, ++i)
5898 if (matrix[i])
5899 {
5900 Emacs_Color *t = COLOR (colors, xx, yy);
5901 r += matrix[i] * t->red;
5902 g += matrix[i] * t->green;
5903 b += matrix[i] * t->blue;
5904 }
5905
5906 r = (r / sum + color_adjust) & 0xffff;
5907 g = (g / sum + color_adjust) & 0xffff;
5908 b = (b / sum + color_adjust) & 0xffff;
5909 p->red = p->green = p->blue = COLOR_INTENSITY (r, g, b);
5910 }
5911 }
5912
5913 xfree (colors);
5914 image_from_emacs_colors (f, img, new);
5915
5916 #undef COLOR
5917 }
5918
5919
5920 /* Perform the pre-defined `emboss' edge-detection on image IMG
5921 on frame F. */
5922
5923 static void
image_emboss(struct frame * f,struct image * img)5924 image_emboss (struct frame *f, struct image *img)
5925 {
5926 image_detect_edges (f, img, emboss_matrix, 0xffff / 2);
5927 }
5928
5929
5930 /* Transform image IMG which is used on frame F with a Laplace
5931 edge-detection algorithm. The result is an image that can be used
5932 to draw disabled buttons, for example. */
5933
5934 static void
image_laplace(struct frame * f,struct image * img)5935 image_laplace (struct frame *f, struct image *img)
5936 {
5937 image_detect_edges (f, img, laplace_matrix, 45000);
5938 }
5939
5940
5941 /* Perform edge-detection on image IMG on frame F, with specified
5942 transformation matrix MATRIX and color-adjustment COLOR_ADJUST.
5943
5944 MATRIX must be either
5945
5946 - a list of at least 9 numbers in row-major form
5947 - a vector of at least 9 numbers
5948
5949 COLOR_ADJUST nil means use a default; otherwise it must be a
5950 number. */
5951
5952 static void
image_edge_detection(struct frame * f,struct image * img,Lisp_Object matrix,Lisp_Object color_adjust)5953 image_edge_detection (struct frame *f, struct image *img,
5954 Lisp_Object matrix, Lisp_Object color_adjust)
5955 {
5956 int i = 0;
5957 int trans[9];
5958
5959 if (CONSP (matrix))
5960 {
5961 for (i = 0;
5962 i < 9 && CONSP (matrix) && NUMBERP (XCAR (matrix));
5963 ++i, matrix = XCDR (matrix))
5964 trans[i] = XFLOATINT (XCAR (matrix));
5965 }
5966 else if (VECTORP (matrix) && ASIZE (matrix) >= 9)
5967 {
5968 for (i = 0; i < 9 && NUMBERP (AREF (matrix, i)); ++i)
5969 trans[i] = XFLOATINT (AREF (matrix, i));
5970 }
5971
5972 if (NILP (color_adjust))
5973 color_adjust = make_fixnum (0xffff / 2);
5974
5975 if (i == 9 && NUMBERP (color_adjust))
5976 image_detect_edges (f, img, trans, XFLOATINT (color_adjust));
5977 }
5978
5979
5980 #if defined HAVE_X_WINDOWS || defined USE_CAIRO
5981 static void
image_pixmap_draw_cross(struct frame * f,Emacs_Pixmap pixmap,int x,int y,unsigned int width,unsigned int height,unsigned long color)5982 image_pixmap_draw_cross (struct frame *f, Emacs_Pixmap pixmap,
5983 int x, int y, unsigned int width, unsigned int height,
5984 unsigned long color)
5985 {
5986 #ifdef USE_CAIRO
5987 cairo_surface_t *surface
5988 = cairo_image_surface_create_for_data ((unsigned char *) pixmap->data,
5989 (pixmap->bits_per_pixel == 32
5990 ? CAIRO_FORMAT_RGB24
5991 : CAIRO_FORMAT_A8),
5992 pixmap->width, pixmap->height,
5993 pixmap->bytes_per_line);
5994 cairo_t *cr = cairo_create (surface);
5995 cairo_surface_destroy (surface);
5996 cairo_set_source_rgb (cr, RED_FROM_ULONG (color) / 255.0,
5997 GREEN_FROM_ULONG (color) / 255.0,
5998 BLUE_FROM_ULONG (color) / 255.0);
5999 cairo_move_to (cr, x + 0.5, y + 0.5);
6000 cairo_rel_line_to (cr, width - 1, height - 1);
6001 cairo_rel_move_to (cr, 0, - (height - 1));
6002 cairo_rel_line_to (cr, - (width - 1), height - 1);
6003 cairo_set_line_width (cr, 1);
6004 cairo_stroke (cr);
6005 cairo_destroy (cr);
6006 #elif HAVE_X_WINDOWS
6007 Display *dpy = FRAME_X_DISPLAY (f);
6008 GC gc = XCreateGC (dpy, pixmap, 0, NULL);
6009
6010 XSetForeground (dpy, gc, color);
6011 XDrawLine (dpy, pixmap, gc, x, y, x + width - 1, y + height - 1);
6012 XDrawLine (dpy, pixmap, gc, x, y + height - 1, x + width - 1, y);
6013 XFreeGC (dpy, gc);
6014 #endif /* HAVE_X_WINDOWS */
6015 }
6016 #endif /* HAVE_X_WINDOWS || USE_CAIRO */
6017
6018 /* Transform image IMG on frame F so that it looks disabled. */
6019
6020 static void
image_disable_image(struct frame * f,struct image * img)6021 image_disable_image (struct frame *f, struct image *img)
6022 {
6023 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
6024 #ifdef HAVE_NTGUI
6025 int n_planes = dpyinfo->n_planes * dpyinfo->n_cbits;
6026 #else
6027 int n_planes = dpyinfo->n_planes;
6028 #endif /* HAVE_NTGUI */
6029
6030 if (n_planes >= 2)
6031 {
6032 /* Color (or grayscale). Convert to gray, and equalize. Just
6033 drawing such images with a stipple can look very odd, so
6034 we're using this method instead. */
6035 Emacs_Color *colors = image_to_emacs_colors (f, img, 1);
6036 Emacs_Color *p, *end;
6037 const int h = 15000;
6038 const int l = 30000;
6039
6040 for (p = colors, end = colors + img->width * img->height;
6041 p < end;
6042 ++p)
6043 {
6044 int i = COLOR_INTENSITY (p->red, p->green, p->blue);
6045 int i2 = (0xffff - h - l) * i / 0xffff + l;
6046 p->red = p->green = p->blue = i2;
6047 }
6048
6049 image_from_emacs_colors (f, img, colors);
6050 }
6051
6052 /* Draw a cross over the disabled image, if we must or if we
6053 should. */
6054 if (n_planes < 2 || cross_disabled_images)
6055 {
6056 #ifndef HAVE_NTGUI
6057 #ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
6058 #ifndef HAVE_HAIKU
6059
6060 #ifndef USE_CAIRO
6061 #define CrossForeground(f) BLACK_PIX_DEFAULT (f)
6062 #define MaskForeground(f) WHITE_PIX_DEFAULT (f)
6063 #else /* USE_CAIRO */
6064 #define CrossForeground(f) 0
6065 #define MaskForeground(f) PIX_MASK_DRAW
6066 #endif /* USE_CAIRO */
6067
6068 #ifndef USE_CAIRO
6069 image_sync_to_pixmaps (f, img);
6070 #endif /* !USE_CAIRO */
6071 image_pixmap_draw_cross (f, img->pixmap, 0, 0, img->width, img->height,
6072 CrossForeground (f));
6073 if (img->mask)
6074 image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height,
6075 MaskForeground (f));
6076 #endif /* !HAVE_HAIKU */
6077 #endif /* !HAVE_NS */
6078 #else
6079 HDC hdc, bmpdc;
6080 HGDIOBJ prev;
6081
6082 hdc = get_frame_dc (f);
6083 bmpdc = CreateCompatibleDC (hdc);
6084 release_frame_dc (f, hdc);
6085
6086 prev = SelectObject (bmpdc, img->pixmap);
6087
6088 SetTextColor (bmpdc, BLACK_PIX_DEFAULT (f));
6089 MoveToEx (bmpdc, 0, 0, NULL);
6090 LineTo (bmpdc, img->width - 1, img->height - 1);
6091 MoveToEx (bmpdc, 0, img->height - 1, NULL);
6092 LineTo (bmpdc, img->width - 1, 0);
6093
6094 if (img->mask)
6095 {
6096 SelectObject (bmpdc, img->mask);
6097 SetTextColor (bmpdc, WHITE_PIX_DEFAULT (f));
6098 MoveToEx (bmpdc, 0, 0, NULL);
6099 LineTo (bmpdc, img->width - 1, img->height - 1);
6100 MoveToEx (bmpdc, 0, img->height - 1, NULL);
6101 LineTo (bmpdc, img->width - 1, 0);
6102 }
6103 SelectObject (bmpdc, prev);
6104 DeleteDC (bmpdc);
6105 #endif /* HAVE_NTGUI */
6106 }
6107 }
6108
6109
6110 /* Build a mask for image IMG which is used on frame F. FILE is the
6111 name of an image file, for error messages. HOW determines how to
6112 determine the background color of IMG. If it is a list '(R G B)',
6113 with R, G, and B being integers >= 0, take that as the color of the
6114 background. Otherwise, determine the background color of IMG
6115 heuristically. */
6116
6117 static void
image_build_heuristic_mask(struct frame * f,struct image * img,Lisp_Object how)6118 image_build_heuristic_mask (struct frame *f, struct image *img,
6119 Lisp_Object how)
6120 {
6121 Emacs_Pix_Context ximg;
6122 #ifdef HAVE_NTGUI
6123 HGDIOBJ prev;
6124 char *mask_img;
6125 int row_width;
6126 #elif !defined HAVE_NS
6127 Emacs_Pix_Container mask_img;
6128 #endif
6129 int x, y;
6130 bool use_img_background;
6131 unsigned long bg = 0;
6132
6133 if (img->mask)
6134 image_clear_image_1 (f, img, CLEAR_IMAGE_MASK);
6135
6136 #ifndef HAVE_NTGUI
6137 #ifndef HAVE_NS
6138 /* Create an image and pixmap serving as mask. */
6139 if (! image_create_x_image_and_pixmap (f, img, img->width, img->height, 1,
6140 &mask_img, 1))
6141 return;
6142 #endif /* !HAVE_NS */
6143 #else
6144 /* Create the bit array serving as mask. */
6145 row_width = (img->width + 7) / 8;
6146 mask_img = xzalloc (row_width * img->height);
6147 #endif /* HAVE_NTGUI */
6148
6149 /* Get the X image or create a memory device context for IMG. */
6150 ximg = image_get_x_image_or_dc (f, img, 0, &prev);
6151
6152 /* Determine the background color of ximg. If HOW is `(R G B)'
6153 take that as color. Otherwise, use the image's background color. */
6154 use_img_background = 1;
6155
6156 if (CONSP (how))
6157 {
6158 int rgb[3], i;
6159
6160 for (i = 0; i < 3 && CONSP (how) && FIXNATP (XCAR (how)); ++i)
6161 {
6162 rgb[i] = XFIXNAT (XCAR (how)) & 0xffff;
6163 how = XCDR (how);
6164 }
6165
6166 if (i == 3 && NILP (how))
6167 {
6168 #ifndef USE_CAIRO
6169 char color_name[30];
6170 sprintf (color_name, "#%04x%04x%04x",
6171 rgb[0] + 0u, rgb[1] + 0u, rgb[2] + 0u);
6172 bg = (
6173 #ifdef HAVE_NTGUI
6174 0x00ffffff & /* Filter out palette info. */
6175 #endif /* HAVE_NTGUI */
6176 image_alloc_image_color (f, img, build_string (color_name), 0));
6177 #else /* USE_CAIRO */
6178 bg = lookup_rgb_color (f, rgb[0], rgb[1], rgb[2]);
6179 #endif /* USE_CAIRO */
6180 use_img_background = 0;
6181 }
6182 }
6183
6184 if (use_img_background)
6185 bg = four_corners_best (ximg, img->corners, img->width, img->height);
6186
6187 /* Set all bits in mask_img to 1 whose color in ximg is different
6188 from the background color bg. */
6189 #ifndef HAVE_NTGUI
6190 for (y = 0; y < img->height; ++y)
6191 for (x = 0; x < img->width; ++x)
6192 #ifndef HAVE_NS
6193 PUT_PIXEL (mask_img, x, y, (GET_PIXEL (ximg, x, y) != bg
6194 ? PIX_MASK_DRAW : PIX_MASK_RETAIN));
6195 #else
6196 if (XGetPixel (ximg, x, y) == bg)
6197 ns_set_alpha (ximg, x, y, 0);
6198 #endif /* HAVE_NS */
6199 #ifndef HAVE_NS
6200 /* Fill in the background_transparent field while we have the mask handy. */
6201 image_background_transparent (img, f, mask_img);
6202
6203 /* Put mask_img into the image. */
6204 image_put_x_image (f, img, mask_img, 1);
6205 #endif /* !HAVE_NS */
6206 #else
6207 for (y = 0; y < img->height; ++y)
6208 for (x = 0; x < img->width; ++x)
6209 {
6210 COLORREF p = GetPixel (ximg, x, y);
6211 if (p != bg)
6212 mask_img[y * row_width + x / 8] |= 1 << (x % 8);
6213 }
6214
6215 /* Create the mask image. */
6216 img->mask = w32_create_pixmap_from_bitmap_data (img->width, img->height,
6217 mask_img);
6218 /* Fill in the background_transparent field while we have the mask handy. */
6219 SelectObject (ximg, img->mask);
6220 image_background_transparent (img, f, ximg);
6221
6222 /* Was: image_destroy_x_image ((XImagePtr )mask_img); which seems bogus ++kfs */
6223 xfree (mask_img);
6224 #endif /* HAVE_NTGUI */
6225
6226 image_unget_x_image_or_dc (img, 0, ximg, prev);
6227 }
6228
6229
6230 /***********************************************************************
6231 PBM (mono, gray, color)
6232 ***********************************************************************/
6233
6234 /* Indices of image specification fields in gs_format, below. */
6235
6236 enum pbm_keyword_index
6237 {
6238 PBM_TYPE,
6239 PBM_FILE,
6240 PBM_DATA,
6241 PBM_ASCENT,
6242 PBM_MARGIN,
6243 PBM_RELIEF,
6244 PBM_ALGORITHM,
6245 PBM_HEURISTIC_MASK,
6246 PBM_MASK,
6247 PBM_FOREGROUND,
6248 PBM_BACKGROUND,
6249 PBM_LAST
6250 };
6251
6252 /* Vector of image_keyword structures describing the format
6253 of valid user-defined image specifications. */
6254
6255 static const struct image_keyword pbm_format[PBM_LAST] =
6256 {
6257 {":type", IMAGE_SYMBOL_VALUE, 1},
6258 {":file", IMAGE_STRING_VALUE, 0},
6259 {":data", IMAGE_STRING_VALUE, 0},
6260 {":ascent", IMAGE_ASCENT_VALUE, 0},
6261 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6262 {":relief", IMAGE_INTEGER_VALUE, 0},
6263 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6264 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6265 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6266 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
6267 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6268 };
6269
6270 /* Return true if OBJECT is a valid PBM image specification. */
6271
6272 static bool
pbm_image_p(Lisp_Object object)6273 pbm_image_p (Lisp_Object object)
6274 {
6275 struct image_keyword fmt[PBM_LAST];
6276
6277 memcpy (fmt, pbm_format, sizeof fmt);
6278
6279 if (!parse_image_spec (object, fmt, PBM_LAST, Qpbm))
6280 return 0;
6281
6282 /* Must specify either :data or :file. */
6283 return fmt[PBM_DATA].count + fmt[PBM_FILE].count == 1;
6284 }
6285
6286
6287 /* Get next char skipping comments in Netpbm header. Returns -1 at
6288 end of input. */
6289
6290 static int
pbm_next_char(char ** s,char * end)6291 pbm_next_char (char **s, char *end)
6292 {
6293 while (*s < end)
6294 {
6295 unsigned char c = *(*s)++;
6296 if (c != '#')
6297 return c;
6298 while (*s < end)
6299 {
6300 c = *(*s)++;
6301 if (c == '\n' || c == '\r')
6302 break;
6303 }
6304 }
6305
6306 return -1;
6307 }
6308
6309
6310 /* Scan a decimal number from *S and return it. Advance *S while
6311 reading the number. END is the end of the string. Value is -1 at
6312 end of input. */
6313
6314 static int
pbm_scan_number(char ** s,char * end)6315 pbm_scan_number (char **s, char *end)
6316 {
6317 int c = 0, val = -1;
6318
6319 /* Skip white-space. */
6320 while ((c = pbm_next_char (s, end)) != -1 && c_isspace (c))
6321 ;
6322
6323 if (c_isdigit (c))
6324 {
6325 /* Read decimal number. */
6326 val = c - '0';
6327 while ((c = pbm_next_char (s, end)) != -1 && c_isdigit (c))
6328 val = 10 * val + c - '0';
6329 }
6330
6331 return val;
6332 }
6333
6334 /* Scan an index from *S and return it. It is a one-byte unsigned
6335 index if !TWO_BYTE, and a two-byte big-endian unsigned index if
6336 TWO_BYTE. */
6337
6338 static int
pbm_scan_index(char ** s,bool two_byte)6339 pbm_scan_index (char **s, bool two_byte)
6340 {
6341 char *p = *s;
6342 unsigned char c0 = *p++;
6343 int n = c0;
6344 if (two_byte)
6345 {
6346 unsigned char c1 = *p++;
6347 n = (n << 8) + c1;
6348 }
6349 *s = p;
6350 return n;
6351 }
6352
6353
6354 /* Load PBM image IMG for use on frame F. */
6355
6356 static bool
pbm_load(struct frame * f,struct image * img)6357 pbm_load (struct frame *f, struct image *img)
6358 {
6359 bool raw_p;
6360 int x, y;
6361 int width, height, max_color_idx = 0;
6362 Lisp_Object specified_file;
6363 enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
6364 char *contents = NULL;
6365 char *end, *p;
6366 Emacs_Pix_Container ximg;
6367
6368 specified_file = image_spec_value (img->spec, QCfile, NULL);
6369
6370 if (STRINGP (specified_file))
6371 {
6372 int fd;
6373 Lisp_Object file = image_find_image_fd (specified_file, &fd);
6374 if (!STRINGP (file))
6375 {
6376 image_error ("Cannot find image file `%s'", specified_file);
6377 return 0;
6378 }
6379
6380 ptrdiff_t size;
6381 contents = slurp_file (fd, &size);
6382 if (contents == NULL)
6383 {
6384 image_error ("Error reading `%s'", file);
6385 return 0;
6386 }
6387
6388 p = contents;
6389 end = contents + size;
6390 }
6391 else
6392 {
6393 Lisp_Object data;
6394 data = image_spec_value (img->spec, QCdata, NULL);
6395 if (!STRINGP (data))
6396 {
6397 image_error ("Invalid image data `%s'", data);
6398 return 0;
6399 }
6400 p = SSDATA (data);
6401 end = p + SBYTES (data);
6402 }
6403
6404 /* Check magic number. */
6405 if (end - p < 2 || *p++ != 'P')
6406 {
6407 image_error ("Not a PBM image: `%s'", img->spec);
6408 error:
6409 xfree (contents);
6410 img->pixmap = NO_PIXMAP;
6411 return 0;
6412 }
6413
6414 switch (*p++)
6415 {
6416 case '1':
6417 raw_p = 0, type = PBM_MONO;
6418 break;
6419
6420 case '2':
6421 raw_p = 0, type = PBM_GRAY;
6422 break;
6423
6424 case '3':
6425 raw_p = 0, type = PBM_COLOR;
6426 break;
6427
6428 case '4':
6429 raw_p = 1, type = PBM_MONO;
6430 break;
6431
6432 case '5':
6433 raw_p = 1, type = PBM_GRAY;
6434 break;
6435
6436 case '6':
6437 raw_p = 1, type = PBM_COLOR;
6438 break;
6439
6440 default:
6441 image_error ("Not a PBM image: `%s'", img->spec);
6442 goto error;
6443 }
6444
6445 /* Read width, height, maximum color-component. Characters
6446 starting with `#' up to the end of a line are ignored. */
6447 width = pbm_scan_number (&p, end);
6448 height = pbm_scan_number (&p, end);
6449
6450 if (type != PBM_MONO)
6451 {
6452 max_color_idx = pbm_scan_number (&p, end);
6453 if (max_color_idx > 65535 || max_color_idx < 0)
6454 {
6455 image_error ("Unsupported maximum PBM color value");
6456 goto error;
6457 }
6458 }
6459
6460 if (!check_image_size (f, width, height))
6461 {
6462 image_size_error ();
6463 goto error;
6464 }
6465
6466 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
6467 goto error;
6468
6469 /* Initialize the color hash table. */
6470 init_color_table ();
6471
6472 if (type == PBM_MONO)
6473 {
6474 unsigned char c = 0;
6475 int g;
6476 struct image_keyword fmt[PBM_LAST];
6477 unsigned long fg = img->face_foreground;
6478 unsigned long bg = img->face_background;
6479 /* Parse the image specification. */
6480 memcpy (fmt, pbm_format, sizeof fmt);
6481 parse_image_spec (img->spec, fmt, PBM_LAST, Qpbm);
6482
6483 /* Get foreground and background colors, maybe allocate colors. */
6484 if (fmt[PBM_FOREGROUND].count
6485 && STRINGP (fmt[PBM_FOREGROUND].value))
6486 fg = image_alloc_image_color (f, img, fmt[PBM_FOREGROUND].value, fg);
6487 if (fmt[PBM_BACKGROUND].count
6488 && STRINGP (fmt[PBM_BACKGROUND].value))
6489 {
6490 bg = image_alloc_image_color (f, img, fmt[PBM_BACKGROUND].value, bg);
6491 img->background = bg;
6492 img->background_valid = 1;
6493 }
6494
6495 #ifdef USE_CAIRO
6496 {
6497 Emacs_Color fgbg[] = {{.pixel = fg}, {.pixel = bg}};
6498 FRAME_TERMINAL (f)->query_colors (f, fgbg, ARRAYELTS (fgbg));
6499 fg = lookup_rgb_color (f, fgbg[0].red, fgbg[0].green, fgbg[0].blue);
6500 bg = lookup_rgb_color (f, fgbg[1].red, fgbg[1].green, fgbg[1].blue);
6501 }
6502 #endif
6503 for (y = 0; y < height; ++y)
6504 for (x = 0; x < width; ++x)
6505 {
6506 if (raw_p)
6507 {
6508 if ((x & 7) == 0)
6509 {
6510 if (p >= end)
6511 {
6512 image_destroy_x_image (ximg);
6513 image_clear_image (f, img);
6514 image_error ("Invalid image size in image `%s'",
6515 img->spec);
6516 goto error;
6517 }
6518 c = *p++;
6519 }
6520 g = c & 0x80;
6521 c <<= 1;
6522 }
6523 else
6524 {
6525 int c = 0;
6526 /* Skip white-space and comments. */
6527 while ((c = pbm_next_char (&p, end)) != -1 && c_isspace (c))
6528 ;
6529
6530 if (c == '0' || c == '1')
6531 g = c - '0';
6532 else
6533 g = 0;
6534 }
6535
6536 PUT_PIXEL (ximg, x, y, g ? fg : bg);
6537 }
6538 }
6539 else
6540 {
6541 int expected_size = height * width;
6542 bool two_byte = 255 < max_color_idx;
6543 if (two_byte)
6544 expected_size *= 2;
6545 if (type == PBM_COLOR)
6546 expected_size *= 3;
6547
6548 if (raw_p && p + expected_size > end)
6549 {
6550 image_destroy_x_image (ximg);
6551 image_clear_image (f, img);
6552 image_error ("Invalid image size in image `%s'", img->spec);
6553 goto error;
6554 }
6555
6556 for (y = 0; y < height; ++y)
6557 for (x = 0; x < width; ++x)
6558 {
6559 int r, g, b;
6560
6561 if (type == PBM_GRAY && raw_p)
6562 r = g = b = pbm_scan_index (&p, two_byte);
6563 else if (type == PBM_GRAY)
6564 r = g = b = pbm_scan_number (&p, end);
6565 else if (raw_p)
6566 {
6567 r = pbm_scan_index (&p, two_byte);
6568 g = pbm_scan_index (&p, two_byte);
6569 b = pbm_scan_index (&p, two_byte);
6570 }
6571 else
6572 {
6573 r = pbm_scan_number (&p, end);
6574 g = pbm_scan_number (&p, end);
6575 b = pbm_scan_number (&p, end);
6576 }
6577
6578 if (r < 0 || g < 0 || b < 0)
6579 {
6580 image_destroy_x_image (ximg);
6581 image_error ("Invalid pixel value in image `%s'", img->spec);
6582 goto error;
6583 }
6584
6585 /* RGB values are now in the range 0..max_color_idx.
6586 Scale this to the range 0..0xffff supported by X. */
6587 r = (double) r * 65535 / max_color_idx;
6588 g = (double) g * 65535 / max_color_idx;
6589 b = (double) b * 65535 / max_color_idx;
6590 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
6591 }
6592 }
6593
6594 #ifdef COLOR_TABLE_SUPPORT
6595 /* Store in IMG->colors the colors allocated for the image, and
6596 free the color table. */
6597 img->colors = colors_in_color_table (&img->ncolors);
6598 free_color_table ();
6599 #endif /* COLOR_TABLE_SUPPORT */
6600
6601 img->width = width;
6602 img->height = height;
6603
6604 /* Maybe fill in the background field while we have ximg handy. */
6605
6606 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
6607 /* Casting avoids a GCC warning. */
6608 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
6609
6610 /* Put ximg into the image. */
6611 image_put_x_image (f, img, ximg, 0);
6612
6613 /* X and W32 versions did it here, MAC version above. ++kfs
6614 img->width = width;
6615 img->height = height; */
6616
6617 xfree (contents);
6618 return 1;
6619 }
6620
6621
6622 /***********************************************************************
6623 NATIVE IMAGE HANDLING
6624 ***********************************************************************/
6625
6626 #if HAVE_NATIVE_IMAGE_API
6627 static bool
image_can_use_native_api(Lisp_Object type)6628 image_can_use_native_api (Lisp_Object type)
6629 {
6630 # ifdef HAVE_NTGUI
6631 return w32_can_use_native_image_api (type);
6632 # elif defined HAVE_NS
6633 return ns_can_use_native_image_api (type);
6634 # elif defined HAVE_HAIKU
6635 return haiku_can_use_native_image_api (type);
6636 # else
6637 return false;
6638 # endif
6639 }
6640
6641 /*
6642 * These functions are actually defined in the OS-native implementation file.
6643 * Currently, for Windows GDI+ interface, w32image.c, and nsimage.m for macOS.
6644 */
6645
6646 /* Indices of image specification fields in native format, below. */
6647 enum native_image_keyword_index
6648 {
6649 NATIVE_IMAGE_TYPE,
6650 NATIVE_IMAGE_DATA,
6651 NATIVE_IMAGE_FILE,
6652 NATIVE_IMAGE_ASCENT,
6653 NATIVE_IMAGE_MARGIN,
6654 NATIVE_IMAGE_RELIEF,
6655 NATIVE_IMAGE_ALGORITHM,
6656 NATIVE_IMAGE_HEURISTIC_MASK,
6657 NATIVE_IMAGE_MASK,
6658 NATIVE_IMAGE_BACKGROUND,
6659 NATIVE_IMAGE_INDEX,
6660 NATIVE_IMAGE_LAST
6661 };
6662
6663 /* Vector of image_keyword structures describing the format
6664 of valid user-defined image specifications. */
6665 static const struct image_keyword native_image_format[] =
6666 {
6667 {":type", IMAGE_SYMBOL_VALUE, 1},
6668 {":data", IMAGE_STRING_VALUE, 0},
6669 {":file", IMAGE_STRING_VALUE, 0},
6670 {":ascent", IMAGE_ASCENT_VALUE, 0},
6671 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6672 {":relief", IMAGE_INTEGER_VALUE, 0},
6673 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6674 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6675 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6676 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
6677 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
6678 };
6679
6680 /* Return true if OBJECT is a valid native API image specification. */
6681
6682 static bool
native_image_p(Lisp_Object object)6683 native_image_p (Lisp_Object object)
6684 {
6685 struct image_keyword fmt[NATIVE_IMAGE_LAST];
6686 memcpy (fmt, native_image_format, sizeof fmt);
6687
6688 if (!parse_image_spec (object, fmt, 10, Qnative_image))
6689 return 0;
6690
6691 /* Must specify either the :data or :file keyword. */
6692 return fmt[NATIVE_IMAGE_FILE].count + fmt[NATIVE_IMAGE_DATA].count == 1;
6693 }
6694
6695 static bool
native_image_load(struct frame * f,struct image * img)6696 native_image_load (struct frame *f, struct image *img)
6697 {
6698 Lisp_Object image_file = image_spec_value (img->spec, QCfile, NULL);
6699
6700 if (STRINGP (image_file))
6701 image_file = image_find_image_file (image_file);
6702
6703 # ifdef HAVE_NTGUI
6704 return w32_load_image (f, img, image_file,
6705 image_spec_value (img->spec, QCdata, NULL));
6706 # elif defined HAVE_NS
6707 return ns_load_image (f, img, image_file,
6708 image_spec_value (img->spec, QCdata, NULL));
6709 # elif defined HAVE_HAIKU
6710 return haiku_load_image (f, img, image_file,
6711 image_spec_value (img->spec, QCdata, NULL));
6712 # else
6713 return 0;
6714 # endif
6715 }
6716
6717 #endif /* HAVE_NATIVE_IMAGE_API */
6718
6719
6720 /***********************************************************************
6721 PNG
6722 ***********************************************************************/
6723
6724 #if defined (HAVE_PNG)
6725
6726 /* Indices of image specification fields in png_format, below. */
6727
6728 enum png_keyword_index
6729 {
6730 PNG_TYPE,
6731 PNG_DATA,
6732 PNG_FILE,
6733 PNG_ASCENT,
6734 PNG_MARGIN,
6735 PNG_RELIEF,
6736 PNG_ALGORITHM,
6737 PNG_HEURISTIC_MASK,
6738 PNG_MASK,
6739 PNG_BACKGROUND,
6740 PNG_LAST
6741 };
6742
6743 /* Vector of image_keyword structures describing the format
6744 of valid user-defined image specifications. */
6745
6746 static const struct image_keyword png_format[PNG_LAST] =
6747 {
6748 {":type", IMAGE_SYMBOL_VALUE, 1},
6749 {":data", IMAGE_STRING_VALUE, 0},
6750 {":file", IMAGE_STRING_VALUE, 0},
6751 {":ascent", IMAGE_ASCENT_VALUE, 0},
6752 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
6753 {":relief", IMAGE_INTEGER_VALUE, 0},
6754 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6755 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6756 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
6757 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
6758 };
6759
6760 /* Return true if OBJECT is a valid PNG image specification. */
6761
6762 static bool
png_image_p(Lisp_Object object)6763 png_image_p (Lisp_Object object)
6764 {
6765 struct image_keyword fmt[PNG_LAST];
6766 memcpy (fmt, png_format, sizeof fmt);
6767
6768 if (!parse_image_spec (object, fmt, PNG_LAST, Qpng))
6769 return 0;
6770
6771 /* Must specify either the :data or :file keyword. */
6772 return fmt[PNG_FILE].count + fmt[PNG_DATA].count == 1;
6773 }
6774
6775 #endif /* HAVE_PNG */
6776
6777
6778 #ifdef HAVE_PNG
6779
6780 # ifdef WINDOWSNT
6781 /* PNG library details. */
6782
6783 DEF_DLL_FN (png_voidp, png_get_io_ptr, (png_structp));
6784 DEF_DLL_FN (int, png_sig_cmp, (png_bytep, png_size_t, png_size_t));
6785 DEF_DLL_FN (png_structp, png_create_read_struct,
6786 (png_const_charp, png_voidp, png_error_ptr, png_error_ptr));
6787 DEF_DLL_FN (png_infop, png_create_info_struct, (png_structp));
6788 DEF_DLL_FN (void, png_destroy_read_struct,
6789 (png_structpp, png_infopp, png_infopp));
6790 DEF_DLL_FN (void, png_set_read_fn, (png_structp, png_voidp, png_rw_ptr));
6791 DEF_DLL_FN (void, png_set_sig_bytes, (png_structp, int));
6792 DEF_DLL_FN (void, png_read_info, (png_structp, png_infop));
6793 DEF_DLL_FN (png_uint_32, png_get_IHDR,
6794 (png_structp, png_infop, png_uint_32 *, png_uint_32 *,
6795 int *, int *, int *, int *, int *));
6796 # ifdef PNG_tRNS_SUPPORTED
6797 DEF_DLL_FN (png_uint_32, png_get_tRNS, (png_structp, png_infop, png_bytep *,
6798 int *, png_color_16p *));
6799 # endif
6800 DEF_DLL_FN (void, png_set_strip_16, (png_structp));
6801 DEF_DLL_FN (void, png_set_expand, (png_structp));
6802 DEF_DLL_FN (void, png_set_gray_to_rgb, (png_structp));
6803 DEF_DLL_FN (int, png_set_interlace_handling, (png_structp));
6804 DEF_DLL_FN (void, png_set_background,
6805 (png_structp, png_color_16p, int, int, double));
6806 DEF_DLL_FN (png_uint_32, png_get_bKGD,
6807 (png_structp, png_infop, png_color_16p *));
6808 DEF_DLL_FN (void, png_read_update_info, (png_structp, png_infop));
6809 DEF_DLL_FN (png_byte, png_get_channels, (png_structp, png_infop));
6810 DEF_DLL_FN (png_size_t, png_get_rowbytes, (png_structp, png_infop));
6811 DEF_DLL_FN (void, png_read_image, (png_structp, png_bytepp));
6812 DEF_DLL_FN (void, png_read_end, (png_structp, png_infop));
6813 DEF_DLL_FN (void, png_error, (png_structp, png_const_charp));
6814
6815 # if (PNG_LIBPNG_VER >= 10500)
6816 DEF_DLL_FN (void, png_longjmp, (png_structp, int) PNG_NORETURN);
6817 DEF_DLL_FN (jmp_buf *, png_set_longjmp_fn,
6818 (png_structp, png_longjmp_ptr, size_t));
6819 # endif /* libpng version >= 1.5 */
6820
6821 static bool
init_png_functions(void)6822 init_png_functions (void)
6823 {
6824 HMODULE library;
6825
6826 if (!(library = w32_delayed_load (Qpng)))
6827 return 0;
6828
6829 LOAD_DLL_FN (library, png_get_io_ptr);
6830 LOAD_DLL_FN (library, png_sig_cmp);
6831 LOAD_DLL_FN (library, png_create_read_struct);
6832 LOAD_DLL_FN (library, png_create_info_struct);
6833 LOAD_DLL_FN (library, png_destroy_read_struct);
6834 LOAD_DLL_FN (library, png_set_read_fn);
6835 LOAD_DLL_FN (library, png_set_sig_bytes);
6836 LOAD_DLL_FN (library, png_read_info);
6837 LOAD_DLL_FN (library, png_get_IHDR);
6838 # ifdef PNG_tRNS_SUPPORTED
6839 LOAD_DLL_FN (library, png_get_tRNS);
6840 # endif
6841 LOAD_DLL_FN (library, png_set_strip_16);
6842 LOAD_DLL_FN (library, png_set_expand);
6843 LOAD_DLL_FN (library, png_set_gray_to_rgb);
6844 LOAD_DLL_FN (library, png_set_interlace_handling);
6845 LOAD_DLL_FN (library, png_set_background);
6846 LOAD_DLL_FN (library, png_get_bKGD);
6847 LOAD_DLL_FN (library, png_read_update_info);
6848 LOAD_DLL_FN (library, png_get_channels);
6849 LOAD_DLL_FN (library, png_get_rowbytes);
6850 LOAD_DLL_FN (library, png_read_image);
6851 LOAD_DLL_FN (library, png_read_end);
6852 LOAD_DLL_FN (library, png_error);
6853
6854 # if (PNG_LIBPNG_VER >= 10500)
6855 LOAD_DLL_FN (library, png_longjmp);
6856 LOAD_DLL_FN (library, png_set_longjmp_fn);
6857 # endif /* libpng version >= 1.5 */
6858
6859 return 1;
6860 }
6861
6862 # undef png_create_info_struct
6863 # undef png_create_read_struct
6864 # undef png_destroy_read_struct
6865 # undef png_error
6866 # undef png_get_bKGD
6867 # undef png_get_channels
6868 # undef png_get_IHDR
6869 # undef png_get_io_ptr
6870 # undef png_get_rowbytes
6871 # undef png_get_tRNS
6872 # undef png_longjmp
6873 # undef png_read_end
6874 # undef png_read_image
6875 # undef png_read_info
6876 # undef png_read_update_info
6877 # undef png_set_background
6878 # undef png_set_expand
6879 # undef png_set_gray_to_rgb
6880 # undef png_set_interlace_handling
6881 # undef png_set_longjmp_fn
6882 # undef png_set_read_fn
6883 # undef png_set_sig_bytes
6884 # undef png_set_strip_16
6885 # undef png_sig_cmp
6886
6887 # define png_create_info_struct fn_png_create_info_struct
6888 # define png_create_read_struct fn_png_create_read_struct
6889 # define png_destroy_read_struct fn_png_destroy_read_struct
6890 # define png_error fn_png_error
6891 # define png_get_bKGD fn_png_get_bKGD
6892 # define png_get_channels fn_png_get_channels
6893 # define png_get_IHDR fn_png_get_IHDR
6894 # define png_get_io_ptr fn_png_get_io_ptr
6895 # define png_get_rowbytes fn_png_get_rowbytes
6896 # define png_get_tRNS fn_png_get_tRNS
6897 # define png_longjmp fn_png_longjmp
6898 # define png_read_end fn_png_read_end
6899 # define png_read_image fn_png_read_image
6900 # define png_read_info fn_png_read_info
6901 # define png_read_update_info fn_png_read_update_info
6902 # define png_set_background fn_png_set_background
6903 # define png_set_expand fn_png_set_expand
6904 # define png_set_gray_to_rgb fn_png_set_gray_to_rgb
6905 # define png_set_interlace_handling fn_png_set_interlace_handling
6906 # define png_set_longjmp_fn fn_png_set_longjmp_fn
6907 # define png_set_read_fn fn_png_set_read_fn
6908 # define png_set_sig_bytes fn_png_set_sig_bytes
6909 # define png_set_strip_16 fn_png_set_strip_16
6910 # define png_sig_cmp fn_png_sig_cmp
6911
6912 # endif /* WINDOWSNT */
6913
6914 /* Fast implementations of setjmp and longjmp. Although setjmp and longjmp
6915 will do, POSIX _setjmp and _longjmp (if available) are often faster.
6916 Do not use sys_setjmp, as PNG supports only jmp_buf.
6917 It's OK if the longjmp substitute restores the signal mask. */
6918 # ifdef HAVE__SETJMP
6919 # define FAST_SETJMP(j) _setjmp (j)
6920 # define FAST_LONGJMP _longjmp
6921 # else
6922 # define FAST_SETJMP(j) setjmp (j)
6923 # define FAST_LONGJMP longjmp
6924 # endif
6925
6926 # if PNG_LIBPNG_VER < 10500
6927 # define PNG_LONGJMP(ptr) FAST_LONGJMP ((ptr)->jmpbuf, 1)
6928 # define PNG_JMPBUF(ptr) ((ptr)->jmpbuf)
6929 # else
6930 /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */
6931 # define PNG_LONGJMP(ptr) png_longjmp (ptr, 1)
6932 # define PNG_JMPBUF(ptr) \
6933 (*png_set_longjmp_fn (ptr, FAST_LONGJMP, sizeof (jmp_buf)))
6934 # endif
6935
6936 /* Error and warning handlers installed when the PNG library
6937 is initialized. */
6938
6939 static AVOID
my_png_error(png_struct * png_ptr,const char * msg)6940 my_png_error (png_struct *png_ptr, const char *msg)
6941 {
6942 eassert (png_ptr != NULL);
6943 /* Avoid compiler warning about deprecated direct access to
6944 png_ptr's fields in libpng versions 1.4.x. */
6945 image_error ("PNG error: %s", build_string (msg));
6946 PNG_LONGJMP (png_ptr);
6947 }
6948
6949
6950 static void
my_png_warning(png_struct * png_ptr,const char * msg)6951 my_png_warning (png_struct *png_ptr, const char *msg)
6952 {
6953 eassert (png_ptr != NULL);
6954 image_error ("PNG warning: %s", build_string (msg));
6955 }
6956
6957 /* Memory source for PNG decoding. */
6958
6959 struct png_memory_storage
6960 {
6961 unsigned char *bytes; /* The data */
6962 ptrdiff_t len; /* How big is it? */
6963 ptrdiff_t index; /* Where are we? */
6964 };
6965
6966
6967 /* Function set as reader function when reading PNG image from memory.
6968 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
6969 bytes from the input to DATA. */
6970
6971 static void
png_read_from_memory(png_structp png_ptr,png_bytep data,png_size_t length)6972 png_read_from_memory (png_structp png_ptr, png_bytep data, png_size_t length)
6973 {
6974 struct png_memory_storage *tbr = png_get_io_ptr (png_ptr);
6975
6976 if (length > tbr->len - tbr->index)
6977 png_error (png_ptr, "Read error");
6978
6979 memcpy (data, tbr->bytes + tbr->index, length);
6980 tbr->index = tbr->index + length;
6981 }
6982
6983
6984 /* Function set as reader function when reading PNG image from a file.
6985 PNG_PTR is a pointer to the PNG control structure. Copy LENGTH
6986 bytes from the input to DATA. */
6987
6988 static void
png_read_from_file(png_structp png_ptr,png_bytep data,png_size_t length)6989 png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
6990 {
6991 FILE *fp = png_get_io_ptr (png_ptr);
6992
6993 if (fread (data, 1, length, fp) < length)
6994 png_error (png_ptr, "Read error");
6995 }
6996
6997
6998 /* Load PNG image IMG for use on frame F. Value is true if
6999 successful. */
7000
7001 struct png_load_context
7002 {
7003 /* These are members so that longjmp doesn't munge local variables. */
7004 png_struct *png_ptr;
7005 png_info *info_ptr;
7006 png_info *end_info;
7007 FILE *fp;
7008 png_byte *pixels;
7009 png_byte **rows;
7010 };
7011
7012 static bool
png_load_body(struct frame * f,struct image * img,struct png_load_context * c)7013 png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
7014 {
7015 Lisp_Object specified_file, specified_data;
7016 FILE *fp = NULL;
7017 int x, y;
7018 ptrdiff_t i;
7019 png_struct *png_ptr;
7020 png_info *info_ptr = NULL, *end_info = NULL;
7021 png_byte sig[8];
7022 png_byte *pixels = NULL;
7023 png_byte **rows = NULL;
7024 png_uint_32 width, height;
7025 int bit_depth, color_type, interlace_type;
7026 png_byte channels;
7027 png_uint_32 row_bytes;
7028 bool transparent_p;
7029 struct png_memory_storage tbr; /* Data to be read */
7030 ptrdiff_t nbytes;
7031 Emacs_Pix_Container ximg, mask_img = NULL;
7032
7033 /* Find out what file to load. */
7034 specified_file = image_spec_value (img->spec, QCfile, NULL);
7035 specified_data = image_spec_value (img->spec, QCdata, NULL);
7036
7037 if (NILP (specified_data))
7038 {
7039 int fd;
7040 Lisp_Object file = image_find_image_fd (specified_file, &fd);
7041 if (!STRINGP (file))
7042 {
7043 image_error ("Cannot find image file `%s'", specified_file);
7044 return 0;
7045 }
7046
7047 /* Open the image file. */
7048 fp = fdopen (fd, "rb");
7049 if (!fp)
7050 {
7051 image_error ("Cannot open image file `%s'", file);
7052 return 0;
7053 }
7054
7055 /* Check PNG signature. */
7056 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
7057 || png_sig_cmp (sig, 0, sizeof sig))
7058 {
7059 fclose (fp);
7060 image_error ("Not a PNG file: `%s'", file);
7061 return 0;
7062 }
7063 }
7064 else
7065 {
7066 if (!STRINGP (specified_data))
7067 {
7068 image_error ("Invalid image data `%s'", specified_data);
7069 return 0;
7070 }
7071
7072 /* Read from memory. */
7073 tbr.bytes = SDATA (specified_data);
7074 tbr.len = SBYTES (specified_data);
7075 tbr.index = 0;
7076
7077 /* Check PNG signature. */
7078 if (tbr.len < sizeof sig
7079 || png_sig_cmp (tbr.bytes, 0, sizeof sig))
7080 {
7081 image_error ("Not a PNG image: `%s'", img->spec);
7082 return 0;
7083 }
7084
7085 /* Need to skip past the signature. */
7086 tbr.bytes += sizeof (sig);
7087 }
7088
7089 /* Initialize read and info structs for PNG lib. */
7090 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
7091 NULL, my_png_error,
7092 my_png_warning);
7093 if (png_ptr)
7094 {
7095 info_ptr = png_create_info_struct (png_ptr);
7096 end_info = png_create_info_struct (png_ptr);
7097 }
7098
7099 c->png_ptr = png_ptr;
7100 c->info_ptr = info_ptr;
7101 c->end_info = end_info;
7102 c->fp = fp;
7103 c->pixels = pixels;
7104 c->rows = rows;
7105
7106 if (! (info_ptr && end_info))
7107 {
7108 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
7109 png_ptr = 0;
7110 }
7111 if (! png_ptr)
7112 {
7113 if (fp) fclose (fp);
7114 return 0;
7115 }
7116
7117 /* Set error jump-back. We come back here when the PNG library
7118 detects an error. */
7119 if (FAST_SETJMP (PNG_JMPBUF (png_ptr)))
7120 {
7121 error:
7122 if (c->png_ptr)
7123 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
7124 xfree (c->pixels);
7125 xfree (c->rows);
7126 if (c->fp)
7127 fclose (c->fp);
7128 return 0;
7129 }
7130
7131 /* Read image info. */
7132 if (!NILP (specified_data))
7133 png_set_read_fn (png_ptr, &tbr, png_read_from_memory);
7134 else
7135 png_set_read_fn (png_ptr, fp, png_read_from_file);
7136
7137 png_set_sig_bytes (png_ptr, sizeof sig);
7138 png_read_info (png_ptr, info_ptr);
7139 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
7140 &interlace_type, NULL, NULL);
7141
7142 if (! (width <= INT_MAX && height <= INT_MAX
7143 && check_image_size (f, width, height)))
7144 {
7145 image_size_error ();
7146 goto error;
7147 }
7148
7149 /* Create the X image and pixmap now, so that the work below can be
7150 omitted if the image is too large for X. */
7151 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
7152 goto error;
7153
7154 /* If image contains simply transparency data, we prefer to
7155 construct a clipping mask. */
7156 transparent_p = false;
7157 # ifdef PNG_tRNS_SUPPORTED
7158 png_bytep trans_alpha;
7159 int num_trans;
7160 if (png_get_tRNS (png_ptr, info_ptr, &trans_alpha, &num_trans, NULL))
7161 {
7162 transparent_p = true;
7163 if (trans_alpha)
7164 for (int i = 0; i < num_trans; i++)
7165 if (0 < trans_alpha[i] && trans_alpha[i] < 255)
7166 {
7167 transparent_p = false;
7168 break;
7169 }
7170 }
7171 # endif
7172
7173 /* This function is easier to write if we only have to handle
7174 one data format: RGB or RGBA with 8 bits per channel. Let's
7175 transform other formats into that format. */
7176
7177 /* Strip more than 8 bits per channel. */
7178 if (bit_depth == 16)
7179 png_set_strip_16 (png_ptr);
7180
7181 /* Expand data to 24 bit RGB, or 8 bit grayscale, with alpha channel
7182 if available. */
7183 png_set_expand (png_ptr);
7184
7185 /* Convert grayscale images to RGB. */
7186 if (color_type == PNG_COLOR_TYPE_GRAY
7187 || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
7188 png_set_gray_to_rgb (png_ptr);
7189
7190 /* Handle alpha channel by combining the image with a background
7191 color. Do this only if a real alpha channel is supplied. For
7192 simple transparency, we prefer a clipping mask. */
7193 if (!transparent_p)
7194 {
7195 /* png_color_16 *image_bg; */
7196 Lisp_Object specified_bg
7197 = image_spec_value (img->spec, QCbackground, NULL);
7198 Emacs_Color color;
7199
7200 /* If the user specified a color, try to use it; if not, use the
7201 current frame background, ignoring any default background
7202 color set by the image. */
7203 if (STRINGP (specified_bg)
7204 ? FRAME_TERMINAL (f)->defined_color_hook (f,
7205 SSDATA (specified_bg),
7206 &color,
7207 false,
7208 false)
7209 : (FRAME_TERMINAL (f)->query_frame_background_color (f, &color),
7210 true))
7211 /* The user specified `:background', use that. */
7212 {
7213 int shift = bit_depth == 16 ? 0 : 8;
7214 png_color_16 bg = { 0 };
7215 bg.red = color.red >> shift;
7216 bg.green = color.green >> shift;
7217 bg.blue = color.blue >> shift;
7218
7219 png_set_background (png_ptr, &bg,
7220 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
7221 }
7222 }
7223
7224 png_set_interlace_handling (png_ptr);
7225 png_read_update_info (png_ptr, info_ptr);
7226
7227 /* Get number of channels. Valid values are 1 for grayscale images
7228 and images with a palette, 2 for grayscale images with transparency
7229 information (alpha channel), 3 for RGB images, and 4 for RGB
7230 images with alpha channel, i.e. RGBA. If conversions above were
7231 sufficient we should only have 3 or 4 channels here. */
7232 channels = png_get_channels (png_ptr, info_ptr);
7233 eassert (channels == 3 || channels == 4);
7234
7235 /* Number of bytes needed for one row of the image. */
7236 row_bytes = png_get_rowbytes (png_ptr, info_ptr);
7237
7238 /* Allocate memory for the image. */
7239 if (INT_MULTIPLY_WRAPV (row_bytes, sizeof *pixels, &nbytes)
7240 || INT_MULTIPLY_WRAPV (nbytes, height, &nbytes))
7241 memory_full (SIZE_MAX);
7242 c->pixels = pixels = xmalloc (nbytes);
7243 c->rows = rows = xmalloc (height * sizeof *rows);
7244 for (i = 0; i < height; ++i)
7245 rows[i] = pixels + i * row_bytes;
7246
7247 /* Read the entire image. */
7248 png_read_image (png_ptr, rows);
7249 png_read_end (png_ptr, info_ptr);
7250 if (fp)
7251 {
7252 fclose (fp);
7253 c->fp = NULL;
7254 }
7255
7256 /* Create an image and pixmap serving as mask if the PNG image
7257 contains an alpha channel. */
7258 if (channels == 4
7259 && transparent_p
7260 && !image_create_x_image_and_pixmap (f, img, width, height, 1,
7261 &mask_img, 1))
7262 {
7263 image_destroy_x_image (ximg);
7264 image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
7265 goto error;
7266 }
7267
7268 /* Fill the X image and mask from PNG data. */
7269 init_color_table ();
7270
7271 for (y = 0; y < height; ++y)
7272 {
7273 png_byte *p = rows[y];
7274
7275 for (x = 0; x < width; ++x)
7276 {
7277 int r, g, b;
7278
7279 r = *p++ << 8;
7280 g = *p++ << 8;
7281 b = *p++ << 8;
7282 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
7283 /* An alpha channel, aka mask channel, associates variable
7284 transparency with an image. Where other image formats
7285 support binary transparency---fully transparent or fully
7286 opaque---PNG allows up to 254 levels of partial transparency.
7287 The PNG library implements partial transparency by combining
7288 the image with a specified background color.
7289
7290 I'm not sure how to handle this here nicely: because the
7291 background on which the image is displayed may change, for
7292 real alpha channel support, it would be necessary to create
7293 a new image for each possible background.
7294
7295 What I'm doing now is that a mask is created if we have
7296 boolean transparency information. Otherwise I'm using
7297 the frame's background color to combine the image with. */
7298
7299 if (channels == 4)
7300 {
7301 if (mask_img)
7302 PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
7303 ++p;
7304 }
7305 }
7306 }
7307
7308 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7309 /* Set IMG's background color from the PNG image, unless the user
7310 overrode it. */
7311 {
7312 png_color_16 *bg;
7313 if (png_get_bKGD (png_ptr, info_ptr, &bg))
7314 {
7315 #ifndef USE_CAIRO
7316 img->background = lookup_rgb_color (f, bg->red, bg->green, bg->blue);
7317 #else /* USE_CAIRO */
7318 char color_name[30];
7319 sprintf (color_name, "#%04x%04x%04x", bg->red, bg->green, bg->blue);
7320 img->background
7321 = image_alloc_image_color (f, img, build_string (color_name), 0);
7322 #endif /* USE_CAIRO */
7323 img->background_valid = 1;
7324 }
7325 }
7326
7327 # ifdef COLOR_TABLE_SUPPORT
7328 /* Remember colors allocated for this image. */
7329 img->colors = colors_in_color_table (&img->ncolors);
7330 free_color_table ();
7331 # endif /* COLOR_TABLE_SUPPORT */
7332
7333 /* Clean up. */
7334 png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
7335 xfree (rows);
7336 xfree (pixels);
7337
7338 img->width = width;
7339 img->height = height;
7340
7341 /* Maybe fill in the background field while we have ximg handy.
7342 Casting avoids a GCC warning. */
7343 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
7344
7345 /* Put ximg into the image. */
7346 image_put_x_image (f, img, ximg, 0);
7347
7348 /* Same for the mask. */
7349 if (mask_img)
7350 {
7351 /* Fill in the background_transparent field while we have the
7352 mask handy. Casting avoids a GCC warning. */
7353 image_background_transparent (img, f, (Emacs_Pix_Context)mask_img);
7354
7355 image_put_x_image (f, img, mask_img, 1);
7356 }
7357
7358 return 1;
7359 }
7360
7361 static bool
png_load(struct frame * f,struct image * img)7362 png_load (struct frame *f, struct image *img)
7363 {
7364 struct png_load_context c;
7365 return png_load_body (f, img, &c);
7366 }
7367
7368 #endif /* HAVE_PNG */
7369
7370
7371
7372 /***********************************************************************
7373 JPEG
7374 ***********************************************************************/
7375
7376 #if defined (HAVE_JPEG)
7377
7378 /* Indices of image specification fields in gs_format, below. */
7379
7380 enum jpeg_keyword_index
7381 {
7382 JPEG_TYPE,
7383 JPEG_DATA,
7384 JPEG_FILE,
7385 JPEG_ASCENT,
7386 JPEG_MARGIN,
7387 JPEG_RELIEF,
7388 JPEG_ALGORITHM,
7389 JPEG_HEURISTIC_MASK,
7390 JPEG_MASK,
7391 JPEG_BACKGROUND,
7392 JPEG_LAST
7393 };
7394
7395 /* Vector of image_keyword structures describing the format
7396 of valid user-defined image specifications. */
7397
7398 static const struct image_keyword jpeg_format[JPEG_LAST] =
7399 {
7400 {":type", IMAGE_SYMBOL_VALUE, 1},
7401 {":data", IMAGE_STRING_VALUE, 0},
7402 {":file", IMAGE_STRING_VALUE, 0},
7403 {":ascent", IMAGE_ASCENT_VALUE, 0},
7404 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7405 {":relief", IMAGE_INTEGER_VALUE, 0},
7406 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7407 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7408 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7409 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
7410 };
7411
7412 /* Return true if OBJECT is a valid JPEG image specification. */
7413
7414 static bool
jpeg_image_p(Lisp_Object object)7415 jpeg_image_p (Lisp_Object object)
7416 {
7417 struct image_keyword fmt[JPEG_LAST];
7418
7419 memcpy (fmt, jpeg_format, sizeof fmt);
7420
7421 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg))
7422 return 0;
7423
7424 /* Must specify either the :data or :file keyword. */
7425 return fmt[JPEG_FILE].count + fmt[JPEG_DATA].count == 1;
7426 }
7427
7428 #endif /* HAVE_JPEG */
7429
7430 #ifdef HAVE_JPEG
7431
7432 /* Work around a warning about HAVE_STDLIB_H being redefined in
7433 jconfig.h. */
7434 # ifdef HAVE_STDLIB_H
7435 # undef HAVE_STDLIB_H
7436 # endif
7437
7438 # if defined (HAVE_NTGUI) && !defined (__WIN32__)
7439 /* In older releases of the jpeg library, jpeglib.h will define boolean
7440 differently depending on __WIN32__, so make sure it is defined. */
7441 # define __WIN32__ 1
7442 # endif
7443
7444 /* rpcndr.h (via windows.h) and jpeglib.h both define boolean types.
7445 Some versions of jpeglib try to detect whether rpcndr.h is loaded,
7446 using the Windows boolean type instead of the jpeglib boolean type
7447 if so. Cygwin jpeglib, however, doesn't try to detect whether its
7448 headers are included along with windows.h, so under Cygwin, jpeglib
7449 attempts to define a conflicting boolean type. Worse, forcing
7450 Cygwin jpeglib headers to use the Windows boolean type doesn't work
7451 because it created an ABI incompatibility between the
7452 already-compiled jpeg library and the header interface definition.
7453
7454 The best we can do is to define jpeglib's boolean type to a
7455 different name. This name, jpeg_boolean, remains in effect through
7456 the rest of image.c.
7457 */
7458 # if defined CYGWIN && defined HAVE_NTGUI
7459 # define boolean jpeg_boolean
7460 # endif
7461 # include <jpeglib.h>
7462 # include <jerror.h>
7463
7464 # ifdef WINDOWSNT
7465
7466 /* JPEG library details. */
7467 DEF_DLL_FN (void, jpeg_CreateDecompress, (j_decompress_ptr, int, size_t));
7468 DEF_DLL_FN (boolean, jpeg_start_decompress, (j_decompress_ptr));
7469 DEF_DLL_FN (boolean, jpeg_finish_decompress, (j_decompress_ptr));
7470 DEF_DLL_FN (void, jpeg_destroy_decompress, (j_decompress_ptr));
7471 DEF_DLL_FN (int, jpeg_read_header, (j_decompress_ptr, boolean));
7472 DEF_DLL_FN (JDIMENSION, jpeg_read_scanlines,
7473 (j_decompress_ptr, JSAMPARRAY, JDIMENSION));
7474 DEF_DLL_FN (struct jpeg_error_mgr *, jpeg_std_error,
7475 (struct jpeg_error_mgr *));
7476 DEF_DLL_FN (boolean, jpeg_resync_to_restart, (j_decompress_ptr, int));
7477
7478 static bool
init_jpeg_functions(void)7479 init_jpeg_functions (void)
7480 {
7481 HMODULE library;
7482
7483 if (!(library = w32_delayed_load (Qjpeg)))
7484 return 0;
7485
7486 LOAD_DLL_FN (library, jpeg_finish_decompress);
7487 LOAD_DLL_FN (library, jpeg_read_scanlines);
7488 LOAD_DLL_FN (library, jpeg_start_decompress);
7489 LOAD_DLL_FN (library, jpeg_read_header);
7490 LOAD_DLL_FN (library, jpeg_CreateDecompress);
7491 LOAD_DLL_FN (library, jpeg_destroy_decompress);
7492 LOAD_DLL_FN (library, jpeg_std_error);
7493 LOAD_DLL_FN (library, jpeg_resync_to_restart);
7494 return 1;
7495 }
7496
7497 # undef jpeg_CreateDecompress
7498 # undef jpeg_destroy_decompress
7499 # undef jpeg_finish_decompress
7500 # undef jpeg_read_header
7501 # undef jpeg_read_scanlines
7502 # undef jpeg_resync_to_restart
7503 # undef jpeg_start_decompress
7504 # undef jpeg_std_error
7505
7506 # define jpeg_CreateDecompress fn_jpeg_CreateDecompress
7507 # define jpeg_destroy_decompress fn_jpeg_destroy_decompress
7508 # define jpeg_finish_decompress fn_jpeg_finish_decompress
7509 # define jpeg_read_header fn_jpeg_read_header
7510 # define jpeg_read_scanlines fn_jpeg_read_scanlines
7511 # define jpeg_resync_to_restart fn_jpeg_resync_to_restart
7512 # define jpeg_start_decompress fn_jpeg_start_decompress
7513 # define jpeg_std_error fn_jpeg_std_error
7514
7515 /* Wrapper since we can't directly assign the function pointer
7516 to another function pointer that was declared more completely easily. */
7517 static boolean
jpeg_resync_to_restart_wrapper(j_decompress_ptr cinfo,int desired)7518 jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
7519 {
7520 return jpeg_resync_to_restart (cinfo, desired);
7521 }
7522 # undef jpeg_resync_to_restart
7523 # define jpeg_resync_to_restart jpeg_resync_to_restart_wrapper
7524
7525 # endif /* WINDOWSNT */
7526
7527 struct my_jpeg_error_mgr
7528 {
7529 struct jpeg_error_mgr pub;
7530 sys_jmp_buf setjmp_buffer;
7531
7532 /* The remaining members are so that longjmp doesn't munge local
7533 variables. */
7534 struct jpeg_decompress_struct cinfo;
7535 enum
7536 {
7537 MY_JPEG_ERROR_EXIT,
7538 MY_JPEG_INVALID_IMAGE_SIZE,
7539 MY_JPEG_CANNOT_CREATE_X
7540 } failure_code;
7541 };
7542
7543
7544 static AVOID
my_error_exit(j_common_ptr cinfo)7545 my_error_exit (j_common_ptr cinfo)
7546 {
7547 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
7548 mgr->failure_code = MY_JPEG_ERROR_EXIT;
7549 sys_longjmp (mgr->setjmp_buffer, 1);
7550 }
7551
7552
7553 /* Init source method for JPEG data source manager. Called by
7554 jpeg_read_header before any data is actually read. See
7555 libjpeg.doc from the JPEG lib distribution. */
7556
7557 static void
our_common_init_source(j_decompress_ptr cinfo)7558 our_common_init_source (j_decompress_ptr cinfo)
7559 {
7560 }
7561
7562
7563 /* Method to terminate data source. Called by
7564 jpeg_finish_decompress after all data has been processed. */
7565
7566 static void
our_common_term_source(j_decompress_ptr cinfo)7567 our_common_term_source (j_decompress_ptr cinfo)
7568 {
7569 }
7570
7571
7572 /* Fill input buffer method for JPEG data source manager. Called
7573 whenever more data is needed. We read the whole image in one step,
7574 so this only adds a fake end of input marker at the end. */
7575
7576 static JOCTET our_memory_buffer[2];
7577
7578 static boolean
our_memory_fill_input_buffer(j_decompress_ptr cinfo)7579 our_memory_fill_input_buffer (j_decompress_ptr cinfo)
7580 {
7581 /* Insert a fake EOI marker. */
7582 struct jpeg_source_mgr *src = cinfo->src;
7583
7584 our_memory_buffer[0] = (JOCTET) 0xFF;
7585 our_memory_buffer[1] = (JOCTET) JPEG_EOI;
7586
7587 src->next_input_byte = our_memory_buffer;
7588 src->bytes_in_buffer = 2;
7589 return 1;
7590 }
7591
7592
7593 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7594 is the JPEG data source manager. */
7595
7596 static void
our_memory_skip_input_data(j_decompress_ptr cinfo,long int num_bytes)7597 our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
7598 {
7599 struct jpeg_source_mgr *src = cinfo->src;
7600
7601 if (src)
7602 {
7603 if (num_bytes > src->bytes_in_buffer)
7604 ERREXIT (cinfo, JERR_INPUT_EOF);
7605
7606 src->bytes_in_buffer -= num_bytes;
7607 src->next_input_byte += num_bytes;
7608 }
7609 }
7610
7611
7612 /* Set up the JPEG lib for reading an image from DATA which contains
7613 LEN bytes. CINFO is the decompression info structure created for
7614 reading the image. */
7615
7616 static void
jpeg_memory_src(j_decompress_ptr cinfo,JOCTET * data,ptrdiff_t len)7617 jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len)
7618 {
7619 struct jpeg_source_mgr *src = cinfo->src;
7620
7621 if (! src)
7622 {
7623 /* First time for this JPEG object? */
7624 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
7625 JPOOL_PERMANENT, sizeof *src);
7626 cinfo->src = src;
7627 src->next_input_byte = data;
7628 }
7629
7630 src->init_source = our_common_init_source;
7631 src->fill_input_buffer = our_memory_fill_input_buffer;
7632 src->skip_input_data = our_memory_skip_input_data;
7633 src->resync_to_restart = jpeg_resync_to_restart; /* Use default method. */
7634 src->term_source = our_common_term_source;
7635 src->bytes_in_buffer = len;
7636 src->next_input_byte = data;
7637 }
7638
7639
7640 struct jpeg_stdio_mgr
7641 {
7642 struct jpeg_source_mgr mgr;
7643 boolean finished;
7644 FILE *file;
7645 JOCTET *buffer;
7646 };
7647
7648
7649 /* Size of buffer to read JPEG from file.
7650 Not too big, as we want to use alloc_small. */
7651 #define JPEG_STDIO_BUFFER_SIZE 8192
7652
7653
7654 /* Fill input buffer method for JPEG data source manager. Called
7655 whenever more data is needed. The data is read from a FILE *. */
7656
7657 static boolean
our_stdio_fill_input_buffer(j_decompress_ptr cinfo)7658 our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
7659 {
7660 struct jpeg_stdio_mgr *src;
7661
7662 src = (struct jpeg_stdio_mgr *) cinfo->src;
7663 if (!src->finished)
7664 {
7665 ptrdiff_t bytes;
7666
7667 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
7668 if (bytes > 0)
7669 src->mgr.bytes_in_buffer = bytes;
7670 else
7671 {
7672 WARNMS (cinfo, JWRN_JPEG_EOF);
7673 src->finished = 1;
7674 src->buffer[0] = (JOCTET) 0xFF;
7675 src->buffer[1] = (JOCTET) JPEG_EOI;
7676 src->mgr.bytes_in_buffer = 2;
7677 }
7678 src->mgr.next_input_byte = src->buffer;
7679 }
7680
7681 return 1;
7682 }
7683
7684
7685 /* Method to skip over NUM_BYTES bytes in the image data. CINFO->src
7686 is the JPEG data source manager. */
7687
7688 static void
our_stdio_skip_input_data(j_decompress_ptr cinfo,long int num_bytes)7689 our_stdio_skip_input_data (j_decompress_ptr cinfo, long int num_bytes)
7690 {
7691 struct jpeg_stdio_mgr *src;
7692 src = (struct jpeg_stdio_mgr *) cinfo->src;
7693
7694 while (num_bytes > 0 && !src->finished)
7695 {
7696 if (num_bytes <= src->mgr.bytes_in_buffer)
7697 {
7698 src->mgr.bytes_in_buffer -= num_bytes;
7699 src->mgr.next_input_byte += num_bytes;
7700 break;
7701 }
7702 else
7703 {
7704 num_bytes -= src->mgr.bytes_in_buffer;
7705 src->mgr.bytes_in_buffer = 0;
7706 src->mgr.next_input_byte = NULL;
7707
7708 our_stdio_fill_input_buffer (cinfo);
7709 }
7710 }
7711 }
7712
7713
7714 /* Set up the JPEG lib for reading an image from a FILE *.
7715 CINFO is the decompression info structure created for
7716 reading the image. */
7717
7718 static void
jpeg_file_src(j_decompress_ptr cinfo,FILE * fp)7719 jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
7720 {
7721 struct jpeg_stdio_mgr *src = (struct jpeg_stdio_mgr *) cinfo->src;
7722
7723 if (! src)
7724 {
7725 /* First time for this JPEG object? */
7726 src = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
7727 JPOOL_PERMANENT, sizeof *src);
7728 cinfo->src = (struct jpeg_source_mgr *) src;
7729 src->buffer = cinfo->mem->alloc_small ((j_common_ptr) cinfo,
7730 JPOOL_PERMANENT,
7731 JPEG_STDIO_BUFFER_SIZE);
7732 }
7733
7734 src->file = fp;
7735 src->finished = 0;
7736 src->mgr.init_source = our_common_init_source;
7737 src->mgr.fill_input_buffer = our_stdio_fill_input_buffer;
7738 src->mgr.skip_input_data = our_stdio_skip_input_data;
7739 src->mgr.resync_to_restart = jpeg_resync_to_restart; /* Use default. */
7740 src->mgr.term_source = our_common_term_source;
7741 src->mgr.bytes_in_buffer = 0;
7742 src->mgr.next_input_byte = NULL;
7743 }
7744
7745 /* Load image IMG for use on frame F. Patterned after example.c
7746 from the JPEG lib. */
7747
7748 static bool
jpeg_load_body(struct frame * f,struct image * img,struct my_jpeg_error_mgr * mgr)7749 jpeg_load_body (struct frame *f, struct image *img,
7750 struct my_jpeg_error_mgr *mgr)
7751 {
7752 Lisp_Object specified_file, specified_data;
7753 FILE *volatile fp = NULL;
7754 JSAMPARRAY buffer;
7755 int row_stride, x, y;
7756 int width, height;
7757 int i, ir, ig, ib;
7758 unsigned long *colors;
7759 Emacs_Pix_Container ximg = NULL;
7760
7761 /* Open the JPEG file. */
7762 specified_file = image_spec_value (img->spec, QCfile, NULL);
7763 specified_data = image_spec_value (img->spec, QCdata, NULL);
7764
7765 if (NILP (specified_data))
7766 {
7767 int fd;
7768 Lisp_Object file = image_find_image_fd (specified_file, &fd);
7769 if (!STRINGP (file))
7770 {
7771 image_error ("Cannot find image file `%s'", specified_file);
7772 return 0;
7773 }
7774
7775 fp = fdopen (fd, "rb");
7776 if (fp == NULL)
7777 {
7778 image_error ("Cannot open `%s'", file);
7779 return 0;
7780 }
7781 }
7782 else if (!STRINGP (specified_data))
7783 {
7784 image_error ("Invalid image data `%s'", specified_data);
7785 return 0;
7786 }
7787
7788 /* Customize libjpeg's error handling to call my_error_exit when an
7789 error is detected. This function will perform a longjmp. */
7790 mgr->cinfo.err = jpeg_std_error (&mgr->pub);
7791 mgr->pub.error_exit = my_error_exit;
7792 if (sys_setjmp (mgr->setjmp_buffer))
7793 {
7794 switch (mgr->failure_code)
7795 {
7796 case MY_JPEG_ERROR_EXIT:
7797 {
7798 char buf[JMSG_LENGTH_MAX];
7799 mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf);
7800 image_error ("Error reading JPEG image `%s': %s",
7801 img->spec, build_string (buf));
7802 break;
7803 }
7804
7805 case MY_JPEG_INVALID_IMAGE_SIZE:
7806 image_size_error ();
7807 break;
7808
7809 case MY_JPEG_CANNOT_CREATE_X:
7810 break;
7811 }
7812
7813 /* Close the input file and destroy the JPEG object. */
7814 if (fp)
7815 fclose (fp);
7816 jpeg_destroy_decompress (&mgr->cinfo);
7817
7818 /* If we already have an XImage, free that. */
7819 image_destroy_x_image (ximg);
7820 /* Free pixmap and colors. */
7821 image_clear_image (f, img);
7822 return 0;
7823 }
7824
7825 /* Create the JPEG decompression object. Let it read from fp.
7826 Read the JPEG image header. */
7827 jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
7828
7829 if (NILP (specified_data))
7830 jpeg_file_src (&mgr->cinfo, fp);
7831 else
7832 jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
7833 SBYTES (specified_data));
7834
7835 jpeg_read_header (&mgr->cinfo, 1);
7836
7837 /* Customize decompression so that color quantization will be used.
7838 Start decompression. */
7839 mgr->cinfo.quantize_colors = 1;
7840 jpeg_start_decompress (&mgr->cinfo);
7841 width = img->width = mgr->cinfo.output_width;
7842 height = img->height = mgr->cinfo.output_height;
7843
7844 if (!check_image_size (f, width, height))
7845 {
7846 mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
7847 sys_longjmp (mgr->setjmp_buffer, 1);
7848 }
7849
7850 /* Create X image and pixmap. */
7851 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
7852 {
7853 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
7854 sys_longjmp (mgr->setjmp_buffer, 1);
7855 }
7856
7857 /* Allocate colors. When color quantization is used,
7858 mgr->cinfo.actual_number_of_colors has been set with the number of
7859 colors generated, and mgr->cinfo.colormap is a two-dimensional array
7860 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
7861 No more than 255 colors will be generated. */
7862 USE_SAFE_ALLOCA;
7863 {
7864 if (mgr->cinfo.out_color_components > 2)
7865 ir = 0, ig = 1, ib = 2;
7866 else if (mgr->cinfo.out_color_components > 1)
7867 ir = 0, ig = 1, ib = 0;
7868 else
7869 ir = 0, ig = 0, ib = 0;
7870
7871 /* Use the color table mechanism because it handles colors that
7872 cannot be allocated nicely. Such colors will be replaced with
7873 a default color, and we don't have to care about which colors
7874 can be freed safely, and which can't. */
7875 init_color_table ();
7876 SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors);
7877
7878 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
7879 {
7880 /* Multiply RGB values with 255 because X expects RGB values
7881 in the range 0..0xffff. */
7882 int r = mgr->cinfo.colormap[ir][i] << 8;
7883 int g = mgr->cinfo.colormap[ig][i] << 8;
7884 int b = mgr->cinfo.colormap[ib][i] << 8;
7885 colors[i] = lookup_rgb_color (f, r, g, b);
7886 }
7887
7888 #ifdef COLOR_TABLE_SUPPORT
7889 /* Remember those colors actually allocated. */
7890 img->colors = colors_in_color_table (&img->ncolors);
7891 free_color_table ();
7892 #endif /* COLOR_TABLE_SUPPORT */
7893 }
7894
7895 /* Read pixels. */
7896 row_stride = width * mgr->cinfo.output_components;
7897 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
7898 JPOOL_IMAGE, row_stride, 1);
7899 for (y = 0; y < height; ++y)
7900 {
7901 jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
7902 for (x = 0; x < mgr->cinfo.output_width; ++x)
7903 PUT_PIXEL (ximg, x, y, colors[buffer[0][x]]);
7904 }
7905
7906 /* Clean up. */
7907 jpeg_finish_decompress (&mgr->cinfo);
7908 jpeg_destroy_decompress (&mgr->cinfo);
7909 if (fp)
7910 fclose (fp);
7911
7912 /* Maybe fill in the background field while we have ximg handy. */
7913 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
7914 /* Casting avoids a GCC warning. */
7915 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
7916
7917 /* Put ximg into the image. */
7918 image_put_x_image (f, img, ximg, 0);
7919 SAFE_FREE ();
7920 return 1;
7921 }
7922
7923 static bool
jpeg_load(struct frame * f,struct image * img)7924 jpeg_load (struct frame *f, struct image *img)
7925 {
7926 struct my_jpeg_error_mgr mgr;
7927 return jpeg_load_body (f, img, &mgr);
7928 }
7929
7930 #endif /* !HAVE_JPEG */
7931
7932
7933
7934 /***********************************************************************
7935 TIFF
7936 ***********************************************************************/
7937
7938 #if defined (HAVE_TIFF)
7939
7940 /* Indices of image specification fields in tiff_format, below. */
7941
7942 enum tiff_keyword_index
7943 {
7944 TIFF_TYPE,
7945 TIFF_DATA,
7946 TIFF_FILE,
7947 TIFF_ASCENT,
7948 TIFF_MARGIN,
7949 TIFF_RELIEF,
7950 TIFF_ALGORITHM,
7951 TIFF_HEURISTIC_MASK,
7952 TIFF_MASK,
7953 TIFF_BACKGROUND,
7954 TIFF_INDEX,
7955 TIFF_LAST
7956 };
7957
7958 /* Vector of image_keyword structures describing the format
7959 of valid user-defined image specifications. */
7960
7961 static const struct image_keyword tiff_format[TIFF_LAST] =
7962 {
7963 {":type", IMAGE_SYMBOL_VALUE, 1},
7964 {":data", IMAGE_STRING_VALUE, 0},
7965 {":file", IMAGE_STRING_VALUE, 0},
7966 {":ascent", IMAGE_ASCENT_VALUE, 0},
7967 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
7968 {":relief", IMAGE_INTEGER_VALUE, 0},
7969 {":conversions", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7970 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7971 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
7972 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
7973 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}
7974 };
7975
7976 /* Return true if OBJECT is a valid TIFF image specification. */
7977
7978 static bool
tiff_image_p(Lisp_Object object)7979 tiff_image_p (Lisp_Object object)
7980 {
7981 struct image_keyword fmt[TIFF_LAST];
7982 memcpy (fmt, tiff_format, sizeof fmt);
7983
7984 if (!parse_image_spec (object, fmt, TIFF_LAST, Qtiff))
7985 return 0;
7986
7987 /* Must specify either the :data or :file keyword. */
7988 return fmt[TIFF_FILE].count + fmt[TIFF_DATA].count == 1;
7989 }
7990
7991 #endif /* HAVE_TIFF */
7992
7993 #ifdef HAVE_TIFF
7994
7995 # include <tiffio.h>
7996
7997 /* libtiff version 4.3.0 deprecated uint32 typedef. */
7998 #if TIFFLIB_VERSION >= 20210416
7999 # define UINT32 uint32_t
8000 #else
8001 # define UINT32 uint32
8002 #endif
8003
8004 # ifdef WINDOWSNT
8005
8006 /* TIFF library details. */
8007 DEF_DLL_FN (TIFFErrorHandler, TIFFSetErrorHandler, (TIFFErrorHandler));
8008 DEF_DLL_FN (TIFFErrorHandler, TIFFSetWarningHandler, (TIFFErrorHandler));
8009 DEF_DLL_FN (TIFF *, TIFFOpen, (const char *, const char *));
8010 DEF_DLL_FN (TIFF *, TIFFClientOpen,
8011 (const char *, const char *, thandle_t, TIFFReadWriteProc,
8012 TIFFReadWriteProc, TIFFSeekProc, TIFFCloseProc, TIFFSizeProc,
8013 TIFFMapFileProc, TIFFUnmapFileProc));
8014 DEF_DLL_FN (int, TIFFGetField, (TIFF *, ttag_t, ...));
8015 DEF_DLL_FN (int, TIFFReadRGBAImage, (TIFF *, UINT32, UINT32, UINT32 *, int));
8016 DEF_DLL_FN (void, TIFFClose, (TIFF *));
8017 DEF_DLL_FN (int, TIFFSetDirectory, (TIFF *, tdir_t));
8018
8019 static bool
init_tiff_functions(void)8020 init_tiff_functions (void)
8021 {
8022 HMODULE library;
8023
8024 if (!(library = w32_delayed_load (Qtiff)))
8025 return 0;
8026
8027 LOAD_DLL_FN (library, TIFFSetErrorHandler);
8028 LOAD_DLL_FN (library, TIFFSetWarningHandler);
8029 LOAD_DLL_FN (library, TIFFOpen);
8030 LOAD_DLL_FN (library, TIFFClientOpen);
8031 LOAD_DLL_FN (library, TIFFGetField);
8032 LOAD_DLL_FN (library, TIFFReadRGBAImage);
8033 LOAD_DLL_FN (library, TIFFClose);
8034 LOAD_DLL_FN (library, TIFFSetDirectory);
8035 return 1;
8036 }
8037
8038 # undef TIFFClientOpen
8039 # undef TIFFClose
8040 # undef TIFFGetField
8041 # undef TIFFOpen
8042 # undef TIFFReadRGBAImage
8043 # undef TIFFSetDirectory
8044 # undef TIFFSetErrorHandler
8045 # undef TIFFSetWarningHandler
8046
8047 # define TIFFClientOpen fn_TIFFClientOpen
8048 # define TIFFClose fn_TIFFClose
8049 # define TIFFGetField fn_TIFFGetField
8050 # define TIFFOpen fn_TIFFOpen
8051 # define TIFFReadRGBAImage fn_TIFFReadRGBAImage
8052 # define TIFFSetDirectory fn_TIFFSetDirectory
8053 # define TIFFSetErrorHandler fn_TIFFSetErrorHandler
8054 # define TIFFSetWarningHandler fn_TIFFSetWarningHandler
8055
8056 # endif /* WINDOWSNT */
8057
8058
8059 /* Reading from a memory buffer for TIFF images Based on the PNG
8060 memory source, but we have to provide a lot of extra functions.
8061 Blah.
8062
8063 We really only need to implement read and seek, but I am not
8064 convinced that the TIFF library is smart enough not to destroy
8065 itself if we only hand it the function pointers we need to
8066 override. */
8067
8068 typedef struct
8069 {
8070 unsigned char *bytes;
8071 ptrdiff_t len;
8072 ptrdiff_t index;
8073 }
8074 tiff_memory_source;
8075
8076 static tsize_t
tiff_read_from_memory(thandle_t data,tdata_t buf,tsize_t size)8077 tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
8078 {
8079 tiff_memory_source *src = (tiff_memory_source *) data;
8080
8081 size = min (size, src->len - src->index);
8082 memcpy (buf, src->bytes + src->index, size);
8083 src->index += size;
8084 return size;
8085 }
8086
8087 static tsize_t
tiff_write_from_memory(thandle_t data,tdata_t buf,tsize_t size)8088 tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
8089 {
8090 return -1;
8091 }
8092
8093 static toff_t
tiff_seek_in_memory(thandle_t data,toff_t off,int whence)8094 tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
8095 {
8096 tiff_memory_source *src = (tiff_memory_source *) data;
8097 ptrdiff_t idx;
8098
8099 switch (whence)
8100 {
8101 case SEEK_SET: /* Go from beginning of source. */
8102 idx = off;
8103 break;
8104
8105 case SEEK_END: /* Go from end of source. */
8106 idx = src->len + off;
8107 break;
8108
8109 case SEEK_CUR: /* Go from current position. */
8110 idx = src->index + off;
8111 break;
8112
8113 default: /* Invalid `whence'. */
8114 return -1;
8115 }
8116
8117 if (idx > src->len || idx < 0)
8118 return -1;
8119
8120 src->index = idx;
8121 return src->index;
8122 }
8123
8124 static int
tiff_close_memory(thandle_t data)8125 tiff_close_memory (thandle_t data)
8126 {
8127 /* NOOP */
8128 return 0;
8129 }
8130
8131 static int
tiff_mmap_memory(thandle_t data,tdata_t * pbase,toff_t * psize)8132 tiff_mmap_memory (thandle_t data, tdata_t *pbase, toff_t *psize)
8133 {
8134 /* It is already _IN_ memory. */
8135 return 0;
8136 }
8137
8138 static void
tiff_unmap_memory(thandle_t data,tdata_t base,toff_t size)8139 tiff_unmap_memory (thandle_t data, tdata_t base, toff_t size)
8140 {
8141 /* We don't need to do this. */
8142 }
8143
8144 static toff_t
tiff_size_of_memory(thandle_t data)8145 tiff_size_of_memory (thandle_t data)
8146 {
8147 return ((tiff_memory_source *) data)->len;
8148 }
8149
8150 /* GCC 3.x on x86 Windows targets has a bug that triggers an internal
8151 compiler error compiling tiff_handler, see Bugzilla bug #17406
8152 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=17406). Declaring
8153 this function as external works around that problem. */
8154 # if defined (__MINGW32__) && __GNUC__ == 3
8155 # define MINGW_STATIC
8156 # else
8157 # define MINGW_STATIC static
8158 # endif
8159
8160 MINGW_STATIC void
8161 tiff_handler (const char *, const char *, const char *, va_list)
8162 ATTRIBUTE_FORMAT_PRINTF (3, 0);
8163 MINGW_STATIC void
tiff_handler(const char * log_format,const char * title,const char * format,va_list ap)8164 tiff_handler (const char *log_format, const char *title,
8165 const char *format, va_list ap)
8166 {
8167 /* doprnt is not suitable here, as TIFF handlers are called from
8168 libtiff and are passed arbitrary printf directives. Instead, use
8169 vsnprintf, taking care to be portable to nonstandard environments
8170 where vsnprintf returns -1 on buffer overflow. Since it's just a
8171 log entry, it's OK to truncate it. */
8172 char buf[4000];
8173 int len = vsnprintf (buf, sizeof buf, format, ap);
8174 add_to_log (log_format, build_string (title),
8175 make_string (buf, max (0, min (len, sizeof buf - 1))));
8176 }
8177 # undef MINGW_STATIC
8178
8179 static void tiff_error_handler (const char *, const char *, va_list)
8180 ATTRIBUTE_FORMAT_PRINTF (2, 0);
8181 static void
tiff_error_handler(const char * title,const char * format,va_list ap)8182 tiff_error_handler (const char *title, const char *format, va_list ap)
8183 {
8184 tiff_handler ("TIFF error: %s %s", title, format, ap);
8185 }
8186
8187
8188 static void tiff_warning_handler (const char *, const char *, va_list)
8189 ATTRIBUTE_FORMAT_PRINTF (2, 0);
8190 static void
tiff_warning_handler(const char * title,const char * format,va_list ap)8191 tiff_warning_handler (const char *title, const char *format, va_list ap)
8192 {
8193 tiff_handler ("TIFF warning: %s %s", title, format, ap);
8194 }
8195
8196
8197 /* Load TIFF image IMG for use on frame F. Value is true if
8198 successful. */
8199
8200 static bool
tiff_load(struct frame * f,struct image * img)8201 tiff_load (struct frame *f, struct image *img)
8202 {
8203 Lisp_Object specified_file;
8204 Lisp_Object specified_data;
8205 TIFF *tiff;
8206 int width, height, x, y, count;
8207 UINT32 *buf;
8208 int rc;
8209 Emacs_Pix_Container ximg;
8210 tiff_memory_source memsrc;
8211 Lisp_Object image;
8212
8213 specified_file = image_spec_value (img->spec, QCfile, NULL);
8214 specified_data = image_spec_value (img->spec, QCdata, NULL);
8215
8216 TIFFSetErrorHandler ((TIFFErrorHandler) tiff_error_handler);
8217 TIFFSetWarningHandler ((TIFFErrorHandler) tiff_warning_handler);
8218
8219 if (NILP (specified_data))
8220 {
8221 /* Read from a file */
8222 Lisp_Object file = image_find_image_file (specified_file);
8223 if (!STRINGP (file))
8224 {
8225 image_error ("Cannot find image file `%s'", specified_file);
8226 return 0;
8227 }
8228
8229 Lisp_Object encoded_file = ENCODE_FILE (file);
8230 # ifdef WINDOWSNT
8231 encoded_file = ansi_encode_filename (encoded_file);
8232 # endif
8233
8234 /* Try to open the image file. */
8235 tiff = TIFFOpen (SSDATA (encoded_file), "r");
8236 if (tiff == NULL)
8237 {
8238 image_error ("Cannot open `%s'", file);
8239 return 0;
8240 }
8241 }
8242 else
8243 {
8244 if (!STRINGP (specified_data))
8245 {
8246 image_error ("Invalid image data `%s'", specified_data);
8247 return 0;
8248 }
8249
8250 /* Memory source! */
8251 memsrc.bytes = SDATA (specified_data);
8252 memsrc.len = SBYTES (specified_data);
8253 memsrc.index = 0;
8254
8255 tiff = TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
8256 tiff_read_from_memory,
8257 tiff_write_from_memory,
8258 tiff_seek_in_memory,
8259 tiff_close_memory,
8260 tiff_size_of_memory,
8261 tiff_mmap_memory,
8262 tiff_unmap_memory);
8263
8264 if (!tiff)
8265 {
8266 image_error ("Cannot open memory source for `%s'", img->spec);
8267 return 0;
8268 }
8269 }
8270
8271 image = image_spec_value (img->spec, QCindex, NULL);
8272 if (FIXNUMP (image))
8273 {
8274 EMACS_INT ino = XFIXNAT (image);
8275 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
8276 && TIFFSetDirectory (tiff, ino)))
8277 {
8278 image_error ("Invalid image number `%s' in image `%s'",
8279 image, img->spec);
8280 TIFFClose (tiff);
8281 return 0;
8282 }
8283 }
8284
8285 /* Get width and height of the image, and allocate a raster buffer
8286 of width x height 32-bit values. */
8287 TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
8288 TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
8289
8290 if (!check_image_size (f, width, height))
8291 {
8292 image_size_error ();
8293 TIFFClose (tiff);
8294 return 0;
8295 }
8296
8297 /* Create the X image and pixmap. */
8298 if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
8299 && image_create_x_image_and_pixmap (f, img, width, height, 0,
8300 &ximg, 0)))
8301 {
8302 TIFFClose (tiff);
8303 return 0;
8304 }
8305
8306 buf = xmalloc (sizeof *buf * width * height);
8307
8308 rc = TIFFReadRGBAImage (tiff, width, height, buf, 0);
8309
8310 /* Count the number of images in the file. */
8311 for (count = 1; TIFFSetDirectory (tiff, count); count++)
8312 continue;
8313
8314 if (count > 1)
8315 img->lisp_data = Fcons (Qcount,
8316 Fcons (make_fixnum (count),
8317 img->lisp_data));
8318
8319 TIFFClose (tiff);
8320 if (!rc)
8321 {
8322 image_error ("Error reading TIFF image `%s'", img->spec);
8323 xfree (buf);
8324 return 0;
8325 }
8326
8327 /* Initialize the color table. */
8328 init_color_table ();
8329
8330 /* Process the pixel raster. Origin is in the lower-left corner. */
8331 for (y = 0; y < height; ++y)
8332 {
8333 UINT32 *row = buf + y * width;
8334
8335 for (x = 0; x < width; ++x)
8336 {
8337 UINT32 abgr = row[x];
8338 int r = TIFFGetR (abgr) << 8;
8339 int g = TIFFGetG (abgr) << 8;
8340 int b = TIFFGetB (abgr) << 8;
8341 PUT_PIXEL (ximg, x, height - 1 - y, lookup_rgb_color (f, r, g, b));
8342 }
8343 }
8344
8345 # ifdef COLOR_TABLE_SUPPORT
8346 /* Remember the colors allocated for the image. Free the color table. */
8347 img->colors = colors_in_color_table (&img->ncolors);
8348 free_color_table ();
8349 # endif /* COLOR_TABLE_SUPPORT */
8350
8351 img->width = width;
8352 img->height = height;
8353
8354 /* Maybe fill in the background field while we have ximg handy. */
8355 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8356 /* Casting avoids a GCC warning on W32. */
8357 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
8358
8359 /* Put ximg into the image. */
8360 image_put_x_image (f, img, ximg, 0);
8361
8362 xfree (buf);
8363 return 1;
8364 }
8365
8366 #endif
8367
8368
8369
8370 /***********************************************************************
8371 GIF
8372 ***********************************************************************/
8373
8374 #if defined (HAVE_GIF)
8375
8376 /* Indices of image specification fields in gif_format, below. */
8377
8378 enum gif_keyword_index
8379 {
8380 GIF_TYPE,
8381 GIF_DATA,
8382 GIF_FILE,
8383 GIF_ASCENT,
8384 GIF_MARGIN,
8385 GIF_RELIEF,
8386 GIF_ALGORITHM,
8387 GIF_HEURISTIC_MASK,
8388 GIF_MASK,
8389 GIF_IMAGE,
8390 GIF_BACKGROUND,
8391 GIF_LAST
8392 };
8393
8394 /* Vector of image_keyword structures describing the format
8395 of valid user-defined image specifications. */
8396
8397 static const struct image_keyword gif_format[GIF_LAST] =
8398 {
8399 {":type", IMAGE_SYMBOL_VALUE, 1},
8400 {":data", IMAGE_STRING_VALUE, 0},
8401 {":file", IMAGE_STRING_VALUE, 0},
8402 {":ascent", IMAGE_ASCENT_VALUE, 0},
8403 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
8404 {":relief", IMAGE_INTEGER_VALUE, 0},
8405 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8406 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8407 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
8408 {":index", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
8409 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
8410 };
8411
8412 /* Free X resources of GIF image IMG which is used on frame F. */
8413
8414 static void
gif_clear_image(struct frame * f,struct image * img)8415 gif_clear_image (struct frame *f, struct image *img)
8416 {
8417 img->lisp_data = Qnil;
8418 image_clear_image (f, img);
8419 }
8420
8421 /* Return true if OBJECT is a valid GIF image specification. */
8422
8423 static bool
gif_image_p(Lisp_Object object)8424 gif_image_p (Lisp_Object object)
8425 {
8426 struct image_keyword fmt[GIF_LAST];
8427 memcpy (fmt, gif_format, sizeof fmt);
8428
8429 if (!parse_image_spec (object, fmt, GIF_LAST, Qgif))
8430 return 0;
8431
8432 /* Must specify either the :data or :file keyword. */
8433 return fmt[GIF_FILE].count + fmt[GIF_DATA].count == 1;
8434 }
8435
8436 #endif /* HAVE_GIF */
8437
8438 #ifdef HAVE_GIF
8439
8440 # ifdef HAVE_NTGUI
8441
8442 /* winuser.h might define DrawText to DrawTextA or DrawTextW.
8443 Undefine before redefining to avoid a preprocessor warning. */
8444 # ifdef DrawText
8445 # undef DrawText
8446 # endif
8447 /* avoid conflict with QuickdrawText.h */
8448 # define DrawText gif_DrawText
8449 # include <gif_lib.h>
8450 /* The bogus ifdef below, which is always true, is to avoid a compiler
8451 warning about DrawText being unused. */
8452 # ifdef DrawText
8453 # undef DrawText
8454 # endif
8455
8456 # else /* HAVE_NTGUI */
8457
8458 # include <gif_lib.h>
8459
8460 # endif /* HAVE_NTGUI */
8461
8462 /* Giflib before 4.1.6 didn't define these macros. */
8463 # ifndef GIFLIB_MAJOR
8464 # define GIFLIB_MAJOR 4
8465 # endif
8466 # ifndef GIFLIB_MINOR
8467 # define GIFLIB_MINOR 0
8468 # endif
8469 # ifndef GIFLIB_RELEASE
8470 # define GIFLIB_RELEASE 0
8471 # endif
8472 /* Giflib before 5.0 didn't define these macros. */
8473 # if GIFLIB_MAJOR < 5
8474 # define DISPOSAL_UNSPECIFIED 0 /* No disposal specified. */
8475 # define DISPOSE_DO_NOT 1 /* Leave image in place. */
8476 # define DISPOSE_BACKGROUND 2 /* Set area too background color. */
8477 # define DISPOSE_PREVIOUS 3 /* Restore to previous content. */
8478 # define NO_TRANSPARENT_COLOR -1
8479 # endif
8480
8481 /* GifErrorString is declared to return char const * when GIFLIB_MAJOR
8482 and GIFLIB_MINOR indicate 5.1 or later. Do not bother using it in
8483 earlier releases, where either it returns char * or GIFLIB_MINOR
8484 may be incorrect. */
8485 # define HAVE_GIFERRORSTRING (5 < GIFLIB_MAJOR + (1 <= GIFLIB_MINOR))
8486
8487 # ifdef WINDOWSNT
8488
8489 /* GIF library details. */
8490 # if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
8491 DEF_DLL_FN (int, DGifCloseFile, (GifFileType *, int *));
8492 # else
8493 DEF_DLL_FN (int, DGifCloseFile, (GifFileType *));
8494 # endif
8495 DEF_DLL_FN (int, DGifSlurp, (GifFileType *));
8496 # if GIFLIB_MAJOR < 5
8497 DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc));
8498 DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *));
8499 # else
8500 DEF_DLL_FN (GifFileType *, DGifOpen, (void *, InputFunc, int *));
8501 DEF_DLL_FN (GifFileType *, DGifOpenFileName, (const char *, int *));
8502 DEF_DLL_FN (int, DGifSavedExtensionToGCB,
8503 (GifFileType *, int, GraphicsControlBlock *));
8504 # endif
8505 # if HAVE_GIFERRORSTRING
8506 DEF_DLL_FN (char const *, GifErrorString, (int));
8507 # endif
8508
8509 static bool
init_gif_functions(void)8510 init_gif_functions (void)
8511 {
8512 HMODULE library;
8513
8514 if (!(library = w32_delayed_load (Qgif)))
8515 return 0;
8516
8517 LOAD_DLL_FN (library, DGifCloseFile);
8518 LOAD_DLL_FN (library, DGifSlurp);
8519 LOAD_DLL_FN (library, DGifOpen);
8520 LOAD_DLL_FN (library, DGifOpenFileName);
8521 # if GIFLIB_MAJOR >= 5
8522 LOAD_DLL_FN (library, DGifSavedExtensionToGCB);
8523 # endif
8524 # if HAVE_GIFERRORSTRING
8525 LOAD_DLL_FN (library, GifErrorString);
8526 # endif
8527 return 1;
8528 }
8529
8530 # undef DGifCloseFile
8531 # undef DGifOpen
8532 # undef DGifOpenFileName
8533 # undef DGifSlurp
8534 # if GIFLIB_MAJOR >= 5
8535 # undef DGifSavedExtensionToGCB
8536 # endif
8537 # undef GifErrorString
8538
8539 # define DGifCloseFile fn_DGifCloseFile
8540 # define DGifOpen fn_DGifOpen
8541 # define DGifOpenFileName fn_DGifOpenFileName
8542 # define DGifSlurp fn_DGifSlurp
8543 # if GIFLIB_MAJOR >= 5
8544 # define DGifSavedExtensionToGCB fn_DGifSavedExtensionToGCB
8545 # endif
8546 # define GifErrorString fn_GifErrorString
8547
8548 # endif /* WINDOWSNT */
8549
8550 /* Reading a GIF image from memory
8551 Based on the PNG memory stuff to a certain extent. */
8552
8553 typedef struct
8554 {
8555 unsigned char *bytes;
8556 ptrdiff_t len;
8557 ptrdiff_t index;
8558 }
8559 gif_memory_source;
8560
8561 /* Make the current memory source available to gif_read_from_memory.
8562 It's done this way because not all versions of libungif support
8563 a UserData field in the GifFileType structure. */
8564 static gif_memory_source *current_gif_memory_src;
8565
8566 static int
gif_read_from_memory(GifFileType * file,GifByteType * buf,int len)8567 gif_read_from_memory (GifFileType *file, GifByteType *buf, int len)
8568 {
8569 gif_memory_source *src = current_gif_memory_src;
8570
8571 if (len > src->len - src->index)
8572 return -1;
8573
8574 memcpy (buf, src->bytes + src->index, len);
8575 src->index += len;
8576 return len;
8577 }
8578
8579 static int
gif_close(GifFileType * gif,int * err)8580 gif_close (GifFileType *gif, int *err)
8581 {
8582 int retval;
8583
8584 #if GIFLIB_MAJOR + (GIFLIB_MINOR >= 1) > 5
8585 retval = DGifCloseFile (gif, err);
8586 #else
8587 retval = DGifCloseFile (gif);
8588 #if GIFLIB_MAJOR >= 5
8589 if (err)
8590 *err = gif->Error;
8591 #endif
8592 #endif
8593 return retval;
8594 }
8595
8596 /* Load GIF image IMG for use on frame F. Value is true if
8597 successful. */
8598
8599 static const int interlace_start[] = {0, 4, 2, 1};
8600 static const int interlace_increment[] = {8, 8, 4, 2};
8601
8602 #define GIF_LOCAL_DESCRIPTOR_EXTENSION 249
8603
8604 static bool
gif_load(struct frame * f,struct image * img)8605 gif_load (struct frame *f, struct image *img)
8606 {
8607 int rc, width, height, x, y, i, j;
8608 ColorMapObject *gif_color_map;
8609 GifFileType *gif;
8610 gif_memory_source memsrc;
8611 Lisp_Object specified_bg = image_spec_value (img->spec, QCbackground, NULL);
8612 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
8613 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
8614 EMACS_INT idx;
8615 int gif_err;
8616
8617 if (NILP (specified_data))
8618 {
8619 Lisp_Object file = image_find_image_file (specified_file);
8620 if (!STRINGP (file))
8621 {
8622 image_error ("Cannot find image file `%s'", specified_file);
8623 return false;
8624 }
8625
8626 Lisp_Object encoded_file = ENCODE_FILE (file);
8627 #ifdef WINDOWSNT
8628 encoded_file = ansi_encode_filename (encoded_file);
8629 #endif
8630
8631 /* Open the GIF file. */
8632 #if GIFLIB_MAJOR < 5
8633 gif = DGifOpenFileName (SSDATA (encoded_file));
8634 #else
8635 gif = DGifOpenFileName (SSDATA (encoded_file), &gif_err);
8636 #endif
8637 if (gif == NULL)
8638 {
8639 #if HAVE_GIFERRORSTRING
8640 const char *errstr = GifErrorString (gif_err);
8641 if (errstr)
8642 image_error ("Cannot open `%s': %s", file, build_string (errstr));
8643 else
8644 #endif
8645 image_error ("Cannot open `%s'", file);
8646 return false;
8647 }
8648 }
8649 else
8650 {
8651 if (!STRINGP (specified_data))
8652 {
8653 image_error ("Invalid image data `%s'", specified_data);
8654 return false;
8655 }
8656
8657 /* Read from memory! */
8658 current_gif_memory_src = &memsrc;
8659 memsrc.bytes = SDATA (specified_data);
8660 memsrc.len = SBYTES (specified_data);
8661 memsrc.index = 0;
8662
8663 #if GIFLIB_MAJOR < 5
8664 gif = DGifOpen (&memsrc, gif_read_from_memory);
8665 #else
8666 gif = DGifOpen (&memsrc, gif_read_from_memory, &gif_err);
8667 #endif
8668 if (!gif)
8669 {
8670 #if HAVE_GIFERRORSTRING
8671 const char *errstr = GifErrorString (gif_err);
8672 if (errstr)
8673 image_error ("Cannot open memory source `%s': %s",
8674 img->spec, build_string (errstr));
8675 else
8676 #endif
8677 image_error ("Cannot open memory source `%s'", img->spec);
8678 return false;
8679 }
8680 }
8681
8682 /* Before reading entire contents, check the declared image size. */
8683 if (!check_image_size (f, gif->SWidth, gif->SHeight))
8684 {
8685 image_size_error ();
8686 goto gif_error;
8687 }
8688
8689 /* Read entire contents. */
8690 rc = DGifSlurp (gif);
8691 if (rc == GIF_ERROR || gif->ImageCount <= 0)
8692 {
8693 if (NILP (specified_data))
8694 image_error ("Error reading `%s'", img->spec);
8695 else
8696 image_error ("Error reading GIF data");
8697 goto gif_error;
8698 }
8699
8700 /* Which sub-image are we to display? */
8701 {
8702 Lisp_Object image_number = image_spec_value (img->spec, QCindex, NULL);
8703 idx = FIXNUMP (image_number) ? XFIXNAT (image_number) : 0;
8704 if (idx < 0 || idx >= gif->ImageCount)
8705 {
8706 image_error ("Invalid image number `%s' in image `%s'",
8707 image_number, img->spec);
8708 goto gif_error;
8709 }
8710 }
8711
8712 width = img->width = gif->SWidth;
8713 height = img->height = gif->SHeight;
8714
8715 img->corners[TOP_CORNER] = gif->SavedImages[0].ImageDesc.Top;
8716 img->corners[LEFT_CORNER] = gif->SavedImages[0].ImageDesc.Left;
8717 img->corners[BOT_CORNER]
8718 = img->corners[TOP_CORNER] + gif->SavedImages[0].ImageDesc.Height;
8719 img->corners[RIGHT_CORNER]
8720 = img->corners[LEFT_CORNER] + gif->SavedImages[0].ImageDesc.Width;
8721
8722 if (!check_image_size (f, width, height))
8723 {
8724 image_size_error ();
8725 goto gif_error;
8726 }
8727
8728 /* Check that the selected subimages fit. It's not clear whether
8729 the GIF spec requires this, but Emacs can crash if they don't fit. */
8730 for (j = 0; j <= idx; ++j)
8731 {
8732 struct SavedImage *subimage = gif->SavedImages + j;
8733 int subimg_width = subimage->ImageDesc.Width;
8734 int subimg_height = subimage->ImageDesc.Height;
8735 int subimg_top = subimage->ImageDesc.Top;
8736 int subimg_left = subimage->ImageDesc.Left;
8737 if (! (subimg_width >= 0 && subimg_height >= 0
8738 && 0 <= subimg_top && subimg_top <= height - subimg_height
8739 && 0 <= subimg_left && subimg_left <= width - subimg_width))
8740 {
8741 image_error ("Subimage does not fit in image");
8742 goto gif_error;
8743 }
8744 }
8745
8746 /* Create the X image and pixmap. */
8747 Emacs_Pix_Container ximg;
8748 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
8749 goto gif_error;
8750
8751 /* Clear the part of the screen image not covered by the image.
8752 Full animated GIF support requires more here (see the gif89 spec,
8753 disposal methods). Let's simply assume that the part not covered
8754 by a sub-image is in the frame's background color. */
8755 unsigned long frame_bg;
8756 #ifndef USE_CAIRO
8757 frame_bg = FRAME_BACKGROUND_PIXEL (f);
8758 #else /* USE_CAIRO */
8759 {
8760 Emacs_Color color;
8761 FRAME_TERMINAL (f)->query_frame_background_color (f, &color);
8762 frame_bg = lookup_rgb_color (f, color.red, color.green, color.blue);
8763 }
8764 #endif /* USE_CAIRO */
8765 for (y = 0; y < img->corners[TOP_CORNER]; ++y)
8766 for (x = 0; x < width; ++x)
8767 PUT_PIXEL (ximg, x, y, frame_bg);
8768
8769 for (y = img->corners[BOT_CORNER]; y < height; ++y)
8770 for (x = 0; x < width; ++x)
8771 PUT_PIXEL (ximg, x, y, frame_bg);
8772
8773 for (y = img->corners[TOP_CORNER]; y < img->corners[BOT_CORNER]; ++y)
8774 {
8775 for (x = 0; x < img->corners[LEFT_CORNER]; ++x)
8776 PUT_PIXEL (ximg, x, y, frame_bg);
8777 for (x = img->corners[RIGHT_CORNER]; x < width; ++x)
8778 PUT_PIXEL (ximg, x, y, frame_bg);
8779 }
8780
8781 /* Read the GIF image into the X image. */
8782
8783 /* FIXME: With the current implementation, loading an animated gif
8784 is quadratic in the number of animation frames, since each frame
8785 is a separate struct image. We must provide a way for a single
8786 gif_load call to construct and save all animation frames. */
8787
8788 init_color_table ();
8789
8790 unsigned long bgcolor UNINIT;
8791 if (STRINGP (specified_bg))
8792 {
8793 bgcolor = image_alloc_image_color (f, img, specified_bg,
8794 FRAME_BACKGROUND_PIXEL (f));
8795 #ifdef USE_CAIRO
8796 Emacs_Color color = {.pixel = bgcolor};
8797 FRAME_TERMINAL (f)->query_colors (f, &color, 1);
8798 bgcolor = lookup_rgb_color (f, color.red, color.green, color.blue);
8799 #endif
8800 }
8801
8802 for (j = 0; j <= idx; ++j)
8803 {
8804 /* We use a local variable `raster' here because RasterBits is a
8805 char *, which invites problems with bytes >= 0x80. */
8806 struct SavedImage *subimage = gif->SavedImages + j;
8807 unsigned char *raster = (unsigned char *) subimage->RasterBits;
8808 int subimg_width = subimage->ImageDesc.Width;
8809 int subimg_height = subimage->ImageDesc.Height;
8810 int subimg_top = subimage->ImageDesc.Top;
8811 int subimg_left = subimage->ImageDesc.Left;
8812
8813 /* From gif89a spec: 1 = "keep in place", 2 = "restore
8814 to background". Treat any other value like 2. */
8815 int disposal = DISPOSAL_UNSPECIFIED;
8816 int transparency_color_index = NO_TRANSPARENT_COLOR;
8817
8818 #if GIFLIB_MAJOR < 5
8819 /* Find the Graphic Control Extension block for this sub-image.
8820 Extract the disposal method and transparency color. */
8821 for (i = 0; i < subimage->ExtensionBlockCount; i++)
8822 {
8823 ExtensionBlock *extblock = subimage->ExtensionBlocks + i;
8824
8825 if ((extblock->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION)
8826 && extblock->ByteCount == 4
8827 && extblock->Bytes[0] & 1)
8828 {
8829 disposal = (extblock->Bytes[0] >> 2) & 7;
8830 transparency_color_index = (unsigned char) extblock->Bytes[3];
8831 break;
8832 }
8833 }
8834 #else
8835 GraphicsControlBlock gcb;
8836 DGifSavedExtensionToGCB (gif, j, &gcb);
8837 disposal = gcb.DisposalMode;
8838 transparency_color_index = gcb.TransparentColor;
8839 #endif
8840
8841 /* We can't "keep in place" the first subimage. */
8842 if (j == 0)
8843 disposal = DISPOSE_BACKGROUND;
8844
8845 /* For disposal == 0 (DISPOSAL_UNSPECIFIED), the spec says
8846 "No disposal specified. The decoder is not required to take
8847 any action." In practice, it seems we need to treat this
8848 like "keep in place" (DISPOSE_DO_NOT), see e.g.
8849 https://upload.wikimedia.org/wikipedia/commons/3/37/Clock.gif */
8850 if (disposal == DISPOSAL_UNSPECIFIED)
8851 disposal = DISPOSE_DO_NOT;
8852
8853 gif_color_map = subimage->ImageDesc.ColorMap;
8854 if (!gif_color_map)
8855 gif_color_map = gif->SColorMap;
8856
8857 /* Allocate subimage colors. */
8858 unsigned long pixel_colors[256] = { 0, };
8859
8860 if (gif_color_map)
8861 for (i = 0; i < gif_color_map->ColorCount; ++i)
8862 {
8863 if (transparency_color_index == i)
8864 pixel_colors[i] = STRINGP (specified_bg)
8865 ? bgcolor : frame_bg;
8866 else
8867 {
8868 int r = gif_color_map->Colors[i].Red << 8;
8869 int g = gif_color_map->Colors[i].Green << 8;
8870 int b = gif_color_map->Colors[i].Blue << 8;
8871 pixel_colors[i] = lookup_rgb_color (f, r, g, b);
8872 }
8873 }
8874
8875 /* Apply the pixel values. */
8876 if (GIFLIB_MAJOR < 5 && gif->SavedImages[j].ImageDesc.Interlace)
8877 {
8878 int row, pass;
8879
8880 for (y = 0, row = interlace_start[0], pass = 0;
8881 y < subimg_height;
8882 y++, row += interlace_increment[pass])
8883 {
8884 while (subimg_height <= row)
8885 row = interlace_start[++pass];
8886
8887 for (x = 0; x < subimg_width; x++)
8888 {
8889 int c = raster[y * subimg_width + x];
8890 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
8891 {
8892 PUT_PIXEL (ximg, x + subimg_left, row + subimg_top,
8893 pixel_colors[c]);
8894 }
8895 }
8896 }
8897 }
8898 else
8899 {
8900 for (y = 0; y < subimg_height; ++y)
8901 for (x = 0; x < subimg_width; ++x)
8902 {
8903 int c = raster[y * subimg_width + x];
8904 if (transparency_color_index != c || disposal != DISPOSE_DO_NOT)
8905 {
8906 PUT_PIXEL (ximg, x + subimg_left, y + subimg_top,
8907 pixel_colors[c]);
8908 }
8909 }
8910 }
8911 }
8912
8913 #ifdef COLOR_TABLE_SUPPORT
8914 img->colors = colors_in_color_table (&img->ncolors);
8915 free_color_table ();
8916 #endif /* COLOR_TABLE_SUPPORT */
8917
8918 /* Save GIF image extension data for `image-metadata'.
8919 Format is (count IMAGES extension-data (FUNCTION "BYTES" ...)). */
8920 img->lisp_data = Qnil;
8921 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
8922 {
8923 int delay = 0;
8924 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
8925 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
8926 /* Append (... FUNCTION "BYTES") */
8927 {
8928 img->lisp_data
8929 = Fcons (make_fixnum (ext->Function),
8930 Fcons (make_unibyte_string ((char *) ext->Bytes,
8931 ext->ByteCount),
8932 img->lisp_data));
8933 if (ext->Function == GIF_LOCAL_DESCRIPTOR_EXTENSION
8934 && ext->ByteCount == 4)
8935 {
8936 delay = ext->Bytes[2] << CHAR_BIT;
8937 delay |= ext->Bytes[1];
8938 }
8939 }
8940 img->lisp_data = list2 (Qextension_data, img->lisp_data);
8941 if (delay)
8942 img->lisp_data
8943 = Fcons (Qdelay,
8944 Fcons (make_float (delay / 100.0),
8945 img->lisp_data));
8946 }
8947
8948 if (gif->ImageCount > 1)
8949 img->lisp_data = Fcons (Qcount,
8950 Fcons (make_fixnum (gif->ImageCount),
8951 img->lisp_data));
8952
8953 if (gif_close (gif, &gif_err) == GIF_ERROR)
8954 {
8955 #if HAVE_GIFERRORSTRING
8956 char const *error_text = GifErrorString (gif_err);
8957
8958 if (error_text)
8959 image_error ("Error closing `%s': %s",
8960 img->spec, build_string (error_text));
8961 else
8962 #endif
8963 image_error ("Error closing `%s'", img->spec);
8964 }
8965
8966 /* Maybe fill in the background field while we have ximg handy. */
8967 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
8968 /* Casting avoids a GCC warning. */
8969 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
8970
8971 /* Put ximg into the image. */
8972 image_put_x_image (f, img, ximg, 0);
8973
8974 return true;
8975
8976 gif_error:
8977 gif_close (gif, NULL);
8978 return false;
8979 }
8980
8981 #endif /* HAVE_GIF */
8982
8983
8984 #ifdef HAVE_WEBP
8985
8986
8987 /***********************************************************************
8988 WebP
8989 ***********************************************************************/
8990
8991 #include "webp/decode.h"
8992
8993 /* Indices of image specification fields in webp_format, below. */
8994
8995 enum webp_keyword_index
8996 {
8997 WEBP_TYPE,
8998 WEBP_DATA,
8999 WEBP_FILE,
9000 WEBP_ASCENT,
9001 WEBP_MARGIN,
9002 WEBP_RELIEF,
9003 WEBP_ALGORITHM,
9004 WEBP_HEURISTIC_MASK,
9005 WEBP_MASK,
9006 WEBP_BACKGROUND,
9007 WEBP_LAST
9008 };
9009
9010 /* Vector of image_keyword structures describing the format
9011 of valid user-defined image specifications. */
9012
9013 static const struct image_keyword webp_format[WEBP_LAST] =
9014 {
9015 {":type", IMAGE_SYMBOL_VALUE, 1},
9016 {":data", IMAGE_STRING_VALUE, 0},
9017 {":file", IMAGE_STRING_VALUE, 0},
9018 {":ascent", IMAGE_ASCENT_VALUE, 0},
9019 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9020 {":relief", IMAGE_INTEGER_VALUE, 0},
9021 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9022 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9023 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9024 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
9025 };
9026
9027 /* Return true if OBJECT is a valid WebP image specification. */
9028
9029 static bool
webp_image_p(Lisp_Object object)9030 webp_image_p (Lisp_Object object)
9031 {
9032 struct image_keyword fmt[WEBP_LAST];
9033 memcpy (fmt, webp_format, sizeof fmt);
9034
9035 if (!parse_image_spec (object, fmt, WEBP_LAST, Qwebp))
9036 return false;
9037
9038 /* Must specify either the :data or :file keyword. */
9039 return fmt[WEBP_FILE].count + fmt[WEBP_DATA].count == 1;
9040 }
9041
9042 #ifdef WINDOWSNT
9043
9044 /* WebP library details. */
9045
9046 DEF_DLL_FN (int, WebPGetInfo, (const uint8_t *, size_t, int *, int *));
9047 /* WebPGetFeatures is a static inline function defined in WebP's
9048 decode.h. Since we cannot use that with dynamically-loaded libwebp
9049 DLL, we instead load the internal function it calls and redirect to
9050 that through a macro. */
9051 DEF_DLL_FN (VP8StatusCode, WebPGetFeaturesInternal,
9052 (const uint8_t *, size_t, WebPBitstreamFeatures *, int));
9053 DEF_DLL_FN (uint8_t *, WebPDecodeRGBA, (const uint8_t *, size_t, int *, int *));
9054 DEF_DLL_FN (uint8_t *, WebPDecodeRGB, (const uint8_t *, size_t, int *, int *));
9055 DEF_DLL_FN (void, WebPFree, (void *));
9056
9057 static bool
init_webp_functions(void)9058 init_webp_functions (void)
9059 {
9060 HMODULE library;
9061
9062 if (!(library = w32_delayed_load (Qwebp)))
9063 return false;
9064
9065 LOAD_DLL_FN (library, WebPGetInfo);
9066 LOAD_DLL_FN (library, WebPGetFeaturesInternal);
9067 LOAD_DLL_FN (library, WebPDecodeRGBA);
9068 LOAD_DLL_FN (library, WebPDecodeRGB);
9069 LOAD_DLL_FN (library, WebPFree);
9070 return true;
9071 }
9072
9073 #undef WebPGetInfo
9074 #undef WebPGetFeatures
9075 #undef WebPDecodeRGBA
9076 #undef WebPDecodeRGB
9077 #undef WebPFree
9078
9079 #define WebPGetInfo fn_WebPGetInfo
9080 #define WebPGetFeatures(d,s,f) \
9081 fn_WebPGetFeaturesInternal(d,s,f,WEBP_DECODER_ABI_VERSION)
9082 #define WebPDecodeRGBA fn_WebPDecodeRGBA
9083 #define WebPDecodeRGB fn_WebPDecodeRGB
9084 #define WebPFree fn_WebPFree
9085
9086 #endif /* WINDOWSNT */
9087
9088 /* Load WebP image IMG for use on frame F. Value is true if
9089 successful. */
9090
9091 static bool
webp_load(struct frame * f,struct image * img)9092 webp_load (struct frame *f, struct image *img)
9093 {
9094 ptrdiff_t size = 0;
9095 uint8_t *contents;
9096 Lisp_Object file = Qnil;
9097
9098 /* Open the WebP file. */
9099 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
9100 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
9101
9102 if (NILP (specified_data))
9103 {
9104 int fd;
9105 file = image_find_image_fd (specified_file, &fd);
9106 if (!STRINGP (file))
9107 {
9108 image_error ("Cannot find image file `%s'", specified_file);
9109 return false;
9110 }
9111
9112 contents = (uint8_t *) slurp_file (fd, &size);
9113 if (contents == NULL)
9114 {
9115 image_error ("Error loading WebP image `%s'", file);
9116 return false;
9117 }
9118 }
9119 else
9120 {
9121 if (!STRINGP (specified_data))
9122 {
9123 image_error ("Invalid image data `%s'", specified_data);
9124 return false;
9125 }
9126 contents = SDATA (specified_data);
9127 size = SBYTES (specified_data);
9128 }
9129
9130 /* Validate the WebP image header. */
9131 if (!WebPGetInfo (contents, size, NULL, NULL))
9132 {
9133 if (!NILP (file))
9134 image_error ("Not a WebP file: `%s'", file);
9135 else
9136 image_error ("Invalid header in WebP image data");
9137 goto webp_error1;
9138 }
9139
9140 /* Get WebP features. */
9141 WebPBitstreamFeatures features;
9142 VP8StatusCode result = WebPGetFeatures (contents, size, &features);
9143 switch (result)
9144 {
9145 case VP8_STATUS_OK:
9146 break;
9147 case VP8_STATUS_NOT_ENOUGH_DATA:
9148 case VP8_STATUS_OUT_OF_MEMORY:
9149 case VP8_STATUS_INVALID_PARAM:
9150 case VP8_STATUS_BITSTREAM_ERROR:
9151 case VP8_STATUS_UNSUPPORTED_FEATURE:
9152 case VP8_STATUS_SUSPENDED:
9153 case VP8_STATUS_USER_ABORT:
9154 default:
9155 /* Error out in all other cases. */
9156 if (!NILP (file))
9157 image_error ("Error when interpreting WebP image data: `%s'", file);
9158 else
9159 image_error ("Error when interpreting WebP image data");
9160 goto webp_error1;
9161 }
9162
9163 /* Decode WebP data. */
9164 uint8_t *decoded;
9165 int width, height;
9166 if (features.has_alpha)
9167 /* Linear [r0, g0, b0, a0, r1, g1, b1, a1, ...] order. */
9168 decoded = WebPDecodeRGBA (contents, size, &width, &height);
9169 else
9170 /* Linear [r0, g0, b0, r1, g1, b1, ...] order. */
9171 decoded = WebPDecodeRGB (contents, size, &width, &height);
9172
9173 if (!decoded)
9174 {
9175 image_error ("Error when interpreting WebP image data");
9176 goto webp_error1;
9177 }
9178
9179 if (!(width <= INT_MAX && height <= INT_MAX
9180 && check_image_size (f, width, height)))
9181 {
9182 image_size_error ();
9183 goto webp_error2;
9184 }
9185
9186 /* Create the x image and pixmap. */
9187 Emacs_Pix_Container ximg, mask_img = NULL;
9188 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, false))
9189 goto webp_error2;
9190
9191 /* Create an image and pixmap serving as mask if the WebP image
9192 contains an alpha channel. */
9193 if (features.has_alpha
9194 && !image_create_x_image_and_pixmap (f, img, width, height, 1, &mask_img, true))
9195 {
9196 image_destroy_x_image (ximg);
9197 image_clear_image_1 (f, img, CLEAR_IMAGE_PIXMAP);
9198 goto webp_error2;
9199 }
9200
9201 /* Fill the X image and mask from WebP data. */
9202 init_color_table ();
9203
9204 uint8_t *p = decoded;
9205 for (int y = 0; y < height; ++y)
9206 {
9207 for (int x = 0; x < width; ++x)
9208 {
9209 int r = *p++ << 8;
9210 int g = *p++ << 8;
9211 int b = *p++ << 8;
9212 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, r, g, b));
9213
9214 /* An alpha channel associates variable transparency with an
9215 image. WebP allows up to 256 levels of partial transparency.
9216 We handle this like with PNG (which see), using the frame's
9217 background color to combine the image with. */
9218 if (features.has_alpha)
9219 {
9220 if (mask_img)
9221 PUT_PIXEL (mask_img, x, y, *p > 0 ? PIX_MASK_DRAW : PIX_MASK_RETAIN);
9222 ++p;
9223 }
9224 }
9225 }
9226
9227 #ifdef COLOR_TABLE_SUPPORT
9228 /* Remember colors allocated for this image. */
9229 img->colors = colors_in_color_table (&img->ncolors);
9230 free_color_table ();
9231 #endif /* COLOR_TABLE_SUPPORT */
9232
9233 /* Put ximg into the image. */
9234 image_put_x_image (f, img, ximg, 0);
9235
9236 /* Same for the mask. */
9237 if (mask_img)
9238 {
9239 /* Fill in the background_transparent field while we have the
9240 mask handy. Casting avoids a GCC warning. */
9241 image_background_transparent (img, f, (Emacs_Pix_Context)mask_img);
9242
9243 image_put_x_image (f, img, mask_img, 1);
9244 }
9245
9246 img->width = width;
9247 img->height = height;
9248
9249 /* Clean up. */
9250 WebPFree (decoded);
9251 if (NILP (specified_data))
9252 xfree (contents);
9253 return true;
9254
9255 webp_error2:
9256 WebPFree (decoded);
9257
9258 webp_error1:
9259 if (NILP (specified_data))
9260 xfree (contents);
9261 return false;
9262 }
9263
9264 #endif /* HAVE_WEBP */
9265
9266
9267 #ifdef HAVE_IMAGEMAGICK
9268
9269
9270 /***********************************************************************
9271 ImageMagick
9272 ***********************************************************************/
9273
9274 /* Indices of image specification fields in imagemagick_format. */
9275
9276 enum imagemagick_keyword_index
9277 {
9278 IMAGEMAGICK_TYPE,
9279 IMAGEMAGICK_DATA,
9280 IMAGEMAGICK_FILE,
9281 IMAGEMAGICK_ASCENT,
9282 IMAGEMAGICK_MARGIN,
9283 IMAGEMAGICK_RELIEF,
9284 IMAGEMAGICK_ALGORITHM,
9285 IMAGEMAGICK_HEURISTIC_MASK,
9286 IMAGEMAGICK_MASK,
9287 IMAGEMAGICK_BACKGROUND,
9288 IMAGEMAGICK_HEIGHT,
9289 IMAGEMAGICK_WIDTH,
9290 IMAGEMAGICK_MAX_HEIGHT,
9291 IMAGEMAGICK_MAX_WIDTH,
9292 IMAGEMAGICK_FORMAT,
9293 IMAGEMAGICK_ROTATION,
9294 IMAGEMAGICK_CROP,
9295 IMAGEMAGICK_LAST
9296 };
9297
9298 /* Vector of image_keyword structures describing the format
9299 of valid user-defined image specifications. */
9300
9301 static struct image_keyword imagemagick_format[IMAGEMAGICK_LAST] =
9302 {
9303 {":type", IMAGE_SYMBOL_VALUE, 1},
9304 {":data", IMAGE_STRING_VALUE, 0},
9305 {":file", IMAGE_STRING_VALUE, 0},
9306 {":ascent", IMAGE_ASCENT_VALUE, 0},
9307 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
9308 {":relief", IMAGE_INTEGER_VALUE, 0},
9309 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9310 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9311 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
9312 {":background", IMAGE_STRING_OR_NIL_VALUE, 0},
9313 {":height", IMAGE_INTEGER_VALUE, 0},
9314 {":width", IMAGE_INTEGER_VALUE, 0},
9315 {":max-height", IMAGE_INTEGER_VALUE, 0},
9316 {":max-width", IMAGE_INTEGER_VALUE, 0},
9317 {":format", IMAGE_SYMBOL_VALUE, 0},
9318 {":rotation", IMAGE_NUMBER_VALUE, 0},
9319 {":crop", IMAGE_DONT_CHECK_VALUE_TYPE, 0}
9320 };
9321
9322 /* Free X resources of imagemagick image IMG which is used on frame F. */
9323
9324 static void
imagemagick_clear_image(struct frame * f,struct image * img)9325 imagemagick_clear_image (struct frame *f,
9326 struct image *img)
9327 {
9328 image_clear_image (f, img);
9329 }
9330
9331 /* Return true if OBJECT is a valid IMAGEMAGICK image specification. Do
9332 this by calling parse_image_spec and supplying the keywords that
9333 identify the IMAGEMAGICK format. */
9334
9335 static bool
imagemagick_image_p(Lisp_Object object)9336 imagemagick_image_p (Lisp_Object object)
9337 {
9338 struct image_keyword fmt[IMAGEMAGICK_LAST];
9339 memcpy (fmt, imagemagick_format, sizeof fmt);
9340
9341 if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
9342 return 0;
9343
9344 /* Must specify either the :data or :file keyword. */
9345 return fmt[IMAGEMAGICK_FILE].count + fmt[IMAGEMAGICK_DATA].count == 1;
9346 }
9347
9348 /* The GIF library also defines DrawRectangle, but its never used in Emacs.
9349 Therefore rename the function so it doesn't collide with ImageMagick. */
9350 #define DrawRectangle DrawRectangleGif
9351
9352 #ifdef HAVE_IMAGEMAGICK7
9353 # include <MagickWand/MagickWand.h>
9354 # include <MagickCore/version.h>
9355 /* ImageMagick 7 compatibility definitions. */
9356 # define PixelSetMagickColor PixelSetPixelColor
9357 typedef PixelInfo MagickPixelPacket;
9358 #else
9359 # include <wand/MagickWand.h>
9360 # include <magick/version.h>
9361 #endif
9362
9363 /* ImageMagick 6.5.3 through 6.6.5 hid PixelGetMagickColor for some reason.
9364 Emacs seems to work fine with the hidden version, so unhide it. */
9365 #if 0x653 <= MagickLibVersion && MagickLibVersion <= 0x665
9366 extern WandExport void PixelGetMagickColor (const PixelWand *,
9367 MagickPixelPacket *);
9368 #endif
9369
9370 static void
imagemagick_initialize(void)9371 imagemagick_initialize (void)
9372 {
9373 static bool imagemagick_initialized;
9374 if (!imagemagick_initialized)
9375 {
9376 imagemagick_initialized = true;
9377 MagickWandGenesis ();
9378 }
9379 }
9380
9381 /* Log ImageMagick error message.
9382 Useful when an ImageMagick function returns the status `MagickFalse'. */
9383
9384 static void
imagemagick_error(MagickWand * wand)9385 imagemagick_error (MagickWand *wand)
9386 {
9387 char *description;
9388 ExceptionType severity;
9389
9390 description = MagickGetException (wand, &severity);
9391 image_error ("ImageMagick error: %s", build_string (description));
9392 MagickRelinquishMemory (description);
9393 }
9394
9395 /* Possibly give ImageMagick some extra help to determine the image
9396 type by supplying a "dummy" filename based on the Content-Type. */
9397
9398 static char *
imagemagick_filename_hint(Lisp_Object spec,char hint_buffer[MaxTextExtent])9399 imagemagick_filename_hint (Lisp_Object spec, char hint_buffer[MaxTextExtent])
9400 {
9401 Lisp_Object symbol = intern ("image-format-suffixes");
9402 Lisp_Object val = find_symbol_value (symbol);
9403 Lisp_Object format;
9404
9405 if (! CONSP (val))
9406 return NULL;
9407
9408 format = image_spec_value (spec, intern (":format"), NULL);
9409 val = Fcar_safe (Fcdr_safe (Fassq (format, val)));
9410 if (! STRINGP (val))
9411 return NULL;
9412
9413 /* It's OK to truncate the hint if it has MaxTextExtent or more bytes,
9414 as ImageMagick would ignore the extra bytes anyway. */
9415 snprintf (hint_buffer, MaxTextExtent, "/tmp/foo.%s", SSDATA (val));
9416 return hint_buffer;
9417 }
9418
9419 /* Animated images (e.g., GIF89a) are composed from one "master image"
9420 (which is the first one, and then there's a number of images that
9421 follow. If following images have non-transparent colors, these are
9422 composed "on top" of the master image. So, in general, one has to
9423 compute ann the preceding images to be able to display a particular
9424 sub-image.
9425
9426 Computing all the preceding images is too slow, so we maintain a
9427 cache of previously computed images. We have to maintain a cache
9428 separate from the image cache, because the images may be scaled
9429 before display. */
9430
9431 struct animation_cache
9432 {
9433 MagickWand *wand;
9434 int index;
9435 struct timespec update_time;
9436 struct animation_cache *next;
9437 char signature[FLEXIBLE_ARRAY_MEMBER];
9438 };
9439
9440 static struct animation_cache *animation_cache = NULL;
9441
9442 static struct animation_cache *
imagemagick_create_cache(char * signature)9443 imagemagick_create_cache (char *signature)
9444 {
9445 struct animation_cache *cache
9446 = xmalloc (FLEXSIZEOF (struct animation_cache, signature,
9447 strlen (signature) + 1));
9448 cache->wand = 0;
9449 cache->index = 0;
9450 cache->next = 0;
9451 strcpy (cache->signature, signature);
9452 return cache;
9453 }
9454
9455 /* Discard cached images that haven't been used for a minute. */
9456 static void
imagemagick_prune_animation_cache(void)9457 imagemagick_prune_animation_cache (void)
9458 {
9459 struct animation_cache **pcache = &animation_cache;
9460 struct timespec old = timespec_sub (current_timespec (),
9461 make_timespec (60, 0));
9462
9463 while (*pcache)
9464 {
9465 struct animation_cache *cache = *pcache;
9466 if (timespec_cmp (old, cache->update_time) <= 0)
9467 pcache = &cache->next;
9468 else
9469 {
9470 if (cache->wand)
9471 DestroyMagickWand (cache->wand);
9472 *pcache = cache->next;
9473 xfree (cache);
9474 }
9475 }
9476 }
9477
9478 static struct animation_cache *
imagemagick_get_animation_cache(MagickWand * wand)9479 imagemagick_get_animation_cache (MagickWand *wand)
9480 {
9481 char *signature = MagickGetImageSignature (wand);
9482 struct animation_cache *cache;
9483 struct animation_cache **pcache = &animation_cache;
9484
9485 imagemagick_prune_animation_cache ();
9486
9487 while (1)
9488 {
9489 cache = *pcache;
9490 if (! cache)
9491 {
9492 *pcache = cache = imagemagick_create_cache (signature);
9493 break;
9494 }
9495 if (strcmp (signature, cache->signature) == 0)
9496 break;
9497 pcache = &cache->next;
9498 }
9499
9500 DestroyString (signature);
9501 cache->update_time = current_timespec ();
9502 return cache;
9503 }
9504
9505 static MagickWand *
imagemagick_compute_animated_image(MagickWand * super_wand,int ino)9506 imagemagick_compute_animated_image (MagickWand *super_wand, int ino)
9507 {
9508 int i;
9509 MagickWand *composite_wand;
9510 size_t dest_width, dest_height;
9511 struct animation_cache *cache = imagemagick_get_animation_cache (super_wand);
9512
9513 MagickSetIteratorIndex (super_wand, 0);
9514
9515 if (ino == 0 || cache->wand == NULL || cache->index > ino)
9516 {
9517 composite_wand = MagickGetImage (super_wand);
9518 if (cache->wand)
9519 DestroyMagickWand (cache->wand);
9520 }
9521 else
9522 composite_wand = cache->wand;
9523
9524 dest_height = MagickGetImageHeight (composite_wand);
9525
9526 for (i = max (1, cache->index + 1); i <= ino; i++)
9527 {
9528 MagickWand *sub_wand;
9529 PixelIterator *source_iterator, *dest_iterator;
9530 PixelWand **source, **dest;
9531 size_t source_width, source_height;
9532 ssize_t source_left, source_top;
9533 MagickPixelPacket pixel;
9534 DisposeType dispose;
9535 ptrdiff_t lines = 0;
9536
9537 MagickSetIteratorIndex (super_wand, i);
9538 sub_wand = MagickGetImage (super_wand);
9539
9540 MagickGetImagePage (sub_wand, &source_width, &source_height,
9541 &source_left, &source_top);
9542
9543 /* This flag says how to handle transparent pixels. */
9544 dispose = MagickGetImageDispose (sub_wand);
9545
9546 source_iterator = NewPixelIterator (sub_wand);
9547 if (! source_iterator)
9548 {
9549 DestroyMagickWand (composite_wand);
9550 DestroyMagickWand (sub_wand);
9551 cache->wand = NULL;
9552 image_error ("Imagemagick pixel iterator creation failed");
9553 return NULL;
9554 }
9555
9556 dest_iterator = NewPixelIterator (composite_wand);
9557 if (! dest_iterator)
9558 {
9559 DestroyMagickWand (composite_wand);
9560 DestroyMagickWand (sub_wand);
9561 DestroyPixelIterator (source_iterator);
9562 cache->wand = NULL;
9563 image_error ("Imagemagick pixel iterator creation failed");
9564 return NULL;
9565 }
9566
9567 /* The sub-image may not start at origin, so move the destination
9568 iterator to where the sub-image should start. */
9569 if (source_top > 0)
9570 {
9571 PixelSetIteratorRow (dest_iterator, source_top);
9572 lines = source_top;
9573 }
9574
9575 while ((source = PixelGetNextIteratorRow (source_iterator, &source_width))
9576 != NULL)
9577 {
9578 ptrdiff_t x;
9579
9580 /* Sanity check. This shouldn't happen, but apparently
9581 does in some pictures. */
9582 if (++lines >= dest_height)
9583 break;
9584
9585 dest = PixelGetNextIteratorRow (dest_iterator, &dest_width);
9586 for (x = 0; x < source_width; x++)
9587 {
9588 /* Sanity check. This shouldn't happen, but apparently
9589 also does in some pictures. */
9590 if (x + source_left >= dest_width)
9591 break;
9592 /* Normally we only copy over non-transparent pixels,
9593 but if the disposal method is "Background", then we
9594 copy over all pixels. */
9595 if (dispose == BackgroundDispose || PixelGetAlpha (source[x]))
9596 {
9597 PixelGetMagickColor (source[x], &pixel);
9598 PixelSetMagickColor (dest[x + source_left], &pixel);
9599 }
9600 }
9601 PixelSyncIterator (dest_iterator);
9602 }
9603
9604 DestroyPixelIterator (source_iterator);
9605 DestroyPixelIterator (dest_iterator);
9606 DestroyMagickWand (sub_wand);
9607 }
9608
9609 /* Cache a copy for the next iteration. The current wand will be
9610 destroyed by the caller. */
9611 cache->wand = CloneMagickWand (composite_wand);
9612 cache->index = ino;
9613
9614 return composite_wand;
9615 }
9616
9617
9618 /* Helper function for imagemagick_load, which does the actual loading
9619 given contents and size, apart from frame and image structures,
9620 passed from imagemagick_load. Uses librimagemagick to do most of
9621 the image processing.
9622
9623 F is a pointer to the Emacs frame; IMG to the image structure to
9624 prepare; CONTENTS is the string containing the IMAGEMAGICK data to
9625 be parsed; SIZE is the number of bytes of data; and FILENAME is
9626 either the file name or the image data.
9627
9628 Return true if successful. */
9629
9630 static bool
imagemagick_load_image(struct frame * f,struct image * img,unsigned char * contents,unsigned int size,char * filename)9631 imagemagick_load_image (struct frame *f, struct image *img,
9632 unsigned char *contents, unsigned int size,
9633 char *filename)
9634 {
9635 int width, height;
9636 size_t image_width, image_height;
9637 MagickBooleanType status;
9638 Emacs_Pix_Container ximg;
9639 int x, y;
9640 MagickWand *image_wand;
9641 PixelIterator *iterator;
9642 PixelWand **pixels, *bg_wand = NULL;
9643 MagickPixelPacket pixel;
9644 Lisp_Object image;
9645 #ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
9646 Lisp_Object value;
9647 #endif
9648 Lisp_Object crop;
9649 EMACS_INT ino;
9650 int desired_width, desired_height;
9651 #ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
9652 double rotation;
9653 #endif
9654 char hint_buffer[MaxTextExtent];
9655 char *filename_hint = NULL;
9656 imagemagick_initialize ();
9657
9658 /* Handle image index for image types who can contain more than one image.
9659 Interface :index is same as for GIF. First we "ping" the image to see how
9660 many sub-images it contains. Pinging is faster than loading the image to
9661 find out things about it. */
9662
9663 image = image_spec_value (img->spec, QCindex, NULL);
9664 ino = FIXNUMP (image) ? XFIXNAT (image) : 0;
9665 image_wand = NewMagickWand ();
9666
9667 if (filename)
9668 status = MagickReadImage (image_wand, filename);
9669 else
9670 {
9671 Lisp_Object lwidth = image_spec_value (img->spec, QCwidth, NULL);
9672 Lisp_Object lheight = image_spec_value (img->spec, QCheight, NULL);
9673
9674 if (FIXNATP (lwidth) && FIXNATP (lheight))
9675 {
9676 MagickSetSize (image_wand, XFIXNAT (lwidth), XFIXNAT (lheight));
9677 MagickSetDepth (image_wand, 8);
9678 }
9679 filename_hint = imagemagick_filename_hint (img->spec, hint_buffer);
9680 MagickSetFilename (image_wand, filename_hint);
9681 status = MagickReadImageBlob (image_wand, contents, size);
9682 }
9683
9684 if (status == MagickFalse)
9685 {
9686 imagemagick_error (image_wand);
9687 DestroyMagickWand (image_wand);
9688 return 0;
9689 }
9690
9691 #ifdef HAVE_MAGICKAUTOORIENTIMAGE
9692 /* If no :rotation is explicitly specified, apply the automatic
9693 rotation from EXIF. */
9694 if (NILP (image_spec_value (img->spec, QCrotation, NULL)))
9695 if (MagickAutoOrientImage (image_wand) == MagickFalse)
9696 {
9697 image_error ("Error applying automatic orientation in image `%s'", img->spec);
9698 DestroyMagickWand (image_wand);
9699 return 0;
9700 }
9701 #endif
9702
9703 if (ino < 0 || ino >= MagickGetNumberImages (image_wand))
9704 {
9705 image_error ("Invalid image number `%s' in image `%s'", image, img->spec);
9706 DestroyMagickWand (image_wand);
9707 return 0;
9708 }
9709
9710 if (MagickGetImageDelay (image_wand) > 0)
9711 img->lisp_data =
9712 Fcons (Qdelay,
9713 Fcons (make_float (MagickGetImageDelay (image_wand) / 100.0),
9714 img->lisp_data));
9715
9716 if (MagickGetNumberImages (image_wand) > 1)
9717 img->lisp_data =
9718 Fcons (Qcount,
9719 Fcons (make_fixnum (MagickGetNumberImages (image_wand)),
9720 img->lisp_data));
9721
9722 /* If we have an animated image, get the new wand based on the
9723 "super-wand". */
9724 if (MagickGetNumberImages (image_wand) > 1)
9725 {
9726 /* This is an animated image (it has a delay), so compute the
9727 composite image etc. */
9728 if (MagickGetImageDelay (image_wand) > 0)
9729 {
9730 MagickWand *super_wand = image_wand;
9731 image_wand = imagemagick_compute_animated_image (super_wand, ino);
9732 if (! image_wand)
9733 image_wand = super_wand;
9734 else
9735 DestroyMagickWand (super_wand);
9736 }
9737 else
9738 /* This is not an animated image: It's just a multi-image file
9739 (like an .ico file). Just return the correct
9740 sub-image. */
9741 {
9742 MagickWand *super_wand = image_wand;
9743
9744 MagickSetIteratorIndex (super_wand, ino);
9745 image_wand = MagickGetImage (super_wand);
9746 DestroyMagickWand (super_wand);
9747 }
9748 }
9749
9750 /* Retrieve the frame's background color, for use later. */
9751 {
9752 Emacs_Color bgcolor;
9753 Lisp_Object specified_bg;
9754
9755 specified_bg = image_spec_value (img->spec, QCbackground, NULL);
9756 if (!STRINGP (specified_bg)
9757 || !FRAME_TERMINAL (f)->defined_color_hook (f,
9758 SSDATA (specified_bg),
9759 &bgcolor,
9760 false,
9761 false))
9762 FRAME_TERMINAL (f)->query_frame_background_color (f, &bgcolor);
9763
9764 bg_wand = NewPixelWand ();
9765 PixelSetRed (bg_wand, (double) bgcolor.red / 65535);
9766 PixelSetGreen (bg_wand, (double) bgcolor.green / 65535);
9767 PixelSetBlue (bg_wand, (double) bgcolor.blue / 65535);
9768 }
9769
9770 #ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
9771 compute_image_size (MagickGetImageWidth (image_wand),
9772 MagickGetImageHeight (image_wand),
9773 img, &desired_width, &desired_height);
9774 #else
9775 desired_width = desired_height = -1;
9776 #endif
9777
9778 if (desired_width != -1 && desired_height != -1)
9779 {
9780 status = MagickScaleImage (image_wand, desired_width, desired_height);
9781 if (status == MagickFalse)
9782 {
9783 image_error ("Imagemagick scale failed");
9784 imagemagick_error (image_wand);
9785 goto imagemagick_error;
9786 }
9787 }
9788
9789 /* crop behaves similar to image slicing in Emacs but is more memory
9790 efficient. */
9791 crop = image_spec_value (img->spec, QCcrop, NULL);
9792
9793 if (CONSP (crop) && TYPE_RANGED_FIXNUMP (size_t, XCAR (crop)))
9794 {
9795 /* After some testing, it seems MagickCropImage is the fastest crop
9796 function in ImageMagick. This crop function seems to do less copying
9797 than the alternatives, but it still reads the entire image into memory
9798 before cropping, which is apparently difficult to avoid when using
9799 imagemagick. */
9800 size_t crop_width = XFIXNUM (XCAR (crop));
9801 crop = XCDR (crop);
9802 if (CONSP (crop) && TYPE_RANGED_FIXNUMP (size_t, XCAR (crop)))
9803 {
9804 size_t crop_height = XFIXNUM (XCAR (crop));
9805 crop = XCDR (crop);
9806 if (CONSP (crop) && TYPE_RANGED_FIXNUMP (ssize_t, XCAR (crop)))
9807 {
9808 ssize_t crop_x = XFIXNUM (XCAR (crop));
9809 crop = XCDR (crop);
9810 if (CONSP (crop) && TYPE_RANGED_FIXNUMP (ssize_t, XCAR (crop)))
9811 {
9812 ssize_t crop_y = XFIXNUM (XCAR (crop));
9813 MagickCropImage (image_wand, crop_width, crop_height,
9814 crop_x, crop_y);
9815 }
9816 }
9817 }
9818 }
9819
9820 #ifndef DONT_CREATE_TRANSFORMED_IMAGEMAGICK_IMAGE
9821 /* Furthermore :rotation. we need background color and angle for
9822 rotation. */
9823 /*
9824 TODO background handling for rotation specified_bg =
9825 image_spec_value (img->spec, QCbackground, NULL); if (!STRINGP
9826 (specified_bg). */
9827 value = image_spec_value (img->spec, QCrotation, NULL);
9828 if (FLOATP (value))
9829 {
9830 rotation = XFLOAT_DATA (value);
9831 status = MagickRotateImage (image_wand, bg_wand, rotation);
9832 if (status == MagickFalse)
9833 {
9834 image_error ("Imagemagick image rotate failed");
9835 imagemagick_error (image_wand);
9836 goto imagemagick_error;
9837 }
9838 }
9839 #endif
9840
9841 /* Set the canvas background color to the frame or specified
9842 background, and flatten the image. Note: as of ImageMagick
9843 6.6.0, SVG image transparency is not handled properly
9844 (e.g. etc/images/splash.svg shows a white background always). */
9845 {
9846 MagickWand *new_wand;
9847 MagickSetImageBackgroundColor (image_wand, bg_wand);
9848 #ifdef HAVE_MAGICKMERGEIMAGELAYERS
9849 new_wand = MagickMergeImageLayers (image_wand, MergeLayer);
9850 #else
9851 new_wand = MagickFlattenImages (image_wand);
9852 #endif
9853 DestroyMagickWand (image_wand);
9854 image_wand = new_wand;
9855 }
9856
9857 /* Finally we are done manipulating the image. Figure out the
9858 resulting width/height and transfer ownership to Emacs. */
9859 image_height = MagickGetImageHeight (image_wand);
9860 image_width = MagickGetImageWidth (image_wand);
9861
9862 if (! (image_width <= INT_MAX && image_height <= INT_MAX
9863 && check_image_size (f, image_width, image_height)))
9864 {
9865 image_size_error ();
9866 goto imagemagick_error;
9867 }
9868
9869 width = image_width;
9870 height = image_height;
9871
9872 /* We can now get a valid pixel buffer from the imagemagick file, if all
9873 went ok. */
9874
9875 init_color_table ();
9876
9877 #if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && \
9878 ! defined (HAVE_NS) && ! defined (HAVE_HAIKU)
9879 if (imagemagick_render_type != 0)
9880 {
9881 /* Magicexportimage is normally faster than pixelpushing. This
9882 method is also well tested. Some aspects of this method are
9883 ad-hoc and needs to be more researched. */
9884 void *dataptr;
9885 int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/
9886 const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/
9887 /* Try to create a x pixmap to hold the imagemagick pixmap. */
9888 if (!image_create_x_image_and_pixmap (f, img, width, height, imagedepth,
9889 &ximg, 0))
9890 {
9891 #ifdef COLOR_TABLE_SUPPORT
9892 free_color_table ();
9893 #endif
9894 image_error ("Imagemagick X bitmap allocation failure");
9895 goto imagemagick_error;
9896 }
9897 dataptr = ximg->data;
9898
9899 /* Oddly, the below code doesn't seem to work:*/
9900 /* switch(ximg->bitmap_unit){ */
9901 /* case 8: */
9902 /* pixelwidth=CharPixel; */
9903 /* break; */
9904 /* case 16: */
9905 /* pixelwidth=ShortPixel; */
9906 /* break; */
9907 /* case 32: */
9908 /* pixelwidth=LongPixel; */
9909 /* break; */
9910 /* } */
9911 /*
9912 Here im just guessing the format of the bitmap.
9913 happens to work fine for:
9914 - bw djvu images
9915 on rgb display.
9916 seems about 3 times as fast as pixel pushing(not carefully measured)
9917 */
9918 int pixelwidth = CharPixel; /*??? TODO figure out*/
9919 MagickExportImagePixels (image_wand, 0, 0, width, height,
9920 exportdepth, pixelwidth, dataptr);
9921 }
9922 else
9923 #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */
9924 {
9925 size_t image_height;
9926 double quantum_range = QuantumRange;
9927 MagickRealType color_scale = 65535.0 / quantum_range;
9928 /* Try to create a x pixmap to hold the imagemagick pixmap. */
9929 if (!image_create_x_image_and_pixmap (f, img, width, height, 0,
9930 &ximg, 0))
9931 {
9932 #ifdef COLOR_TABLE_SUPPORT
9933 free_color_table ();
9934 #endif
9935 image_error ("Imagemagick X bitmap allocation failure");
9936 goto imagemagick_error;
9937 }
9938
9939 /* Copy imagemagick image to x with primitive yet robust pixel
9940 pusher loop. This has been tested a lot with many different
9941 images. */
9942
9943 /* Copy pixels from the imagemagick image structure to the x image map. */
9944 iterator = NewPixelIterator (image_wand);
9945 if (! iterator)
9946 {
9947 #ifdef COLOR_TABLE_SUPPORT
9948 free_color_table ();
9949 #endif
9950 image_destroy_x_image (ximg);
9951 image_error ("Imagemagick pixel iterator creation failed");
9952 goto imagemagick_error;
9953 }
9954
9955 image_height = MagickGetImageHeight (image_wand);
9956 for (y = 0; y < image_height; y++)
9957 {
9958 size_t row_width;
9959 pixels = PixelGetNextIteratorRow (iterator, &row_width);
9960 if (! pixels)
9961 break;
9962 int xlim = min (row_width, width);
9963 for (x = 0; x < xlim; x++)
9964 {
9965 PixelGetMagickColor (pixels[x], &pixel);
9966 PUT_PIXEL (ximg, x, y,
9967 lookup_rgb_color (f,
9968 color_scale * pixel.red,
9969 color_scale * pixel.green,
9970 color_scale * pixel.blue));
9971 }
9972 }
9973 DestroyPixelIterator (iterator);
9974 }
9975
9976 #ifdef COLOR_TABLE_SUPPORT
9977 /* Remember colors allocated for this image. */
9978 img->colors = colors_in_color_table (&img->ncolors);
9979 free_color_table ();
9980 #endif /* COLOR_TABLE_SUPPORT */
9981
9982 img->width = width;
9983 img->height = height;
9984
9985 /* Put ximg into the image. */
9986 image_put_x_image (f, img, ximg, 0);
9987
9988 /* Final cleanup. image_wand should be the only resource left. */
9989 DestroyMagickWand (image_wand);
9990 if (bg_wand) DestroyPixelWand (bg_wand);
9991
9992 /* Do not call MagickWandTerminus, to work around ImageMagick bug 825. See:
9993 https://github.com/ImageMagick/ImageMagick/issues/825
9994 Although this bug was introduced in ImageMagick 6.9.9-14 and
9995 fixed in 6.9.9-18, it's simpler to work around it in all versions. */
9996
9997 return 1;
9998
9999 imagemagick_error:
10000 DestroyMagickWand (image_wand);
10001 if (bg_wand) DestroyPixelWand (bg_wand);
10002
10003 /* TODO more cleanup. */
10004 image_error ("Error parsing IMAGEMAGICK image `%s'", img->spec);
10005 return 0;
10006 }
10007
10008
10009 /* Load IMAGEMAGICK image IMG for use on frame F. Value is true if
10010 successful. this function will go into the imagemagick_type structure, and
10011 the prototype thus needs to be compatible with that structure. */
10012
10013 static bool
imagemagick_load(struct frame * f,struct image * img)10014 imagemagick_load (struct frame *f, struct image *img)
10015 {
10016 bool success_p = 0;
10017 Lisp_Object file_name;
10018
10019 /* If IMG->spec specifies a file name, create a non-file spec from it. */
10020 file_name = image_spec_value (img->spec, QCfile, NULL);
10021 if (STRINGP (file_name))
10022 {
10023 Lisp_Object file = image_find_image_file (file_name);
10024 if (!STRINGP (file))
10025 {
10026 image_error ("Cannot find image file `%s'", file_name);
10027 return 0;
10028 }
10029 file = ENCODE_FILE (file);
10030 #ifdef WINDOWSNT
10031 file = ansi_encode_filename (file);
10032 #endif
10033 success_p = imagemagick_load_image (f, img, 0, 0, SSDATA (file));
10034 }
10035 /* Else it's not a file, it's a Lisp object. Load the image from a
10036 Lisp object rather than a file. */
10037 else
10038 {
10039 Lisp_Object data;
10040
10041 data = image_spec_value (img->spec, QCdata, NULL);
10042 if (!STRINGP (data))
10043 {
10044 image_error ("Invalid image data `%s'", data);
10045 return 0;
10046 }
10047 success_p = imagemagick_load_image (f, img, SDATA (data),
10048 SBYTES (data), NULL);
10049 }
10050
10051 return success_p;
10052 }
10053
10054 DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
10055 doc: /* Return a list of image types supported by ImageMagick.
10056 Each entry in this list is a symbol named after an ImageMagick format
10057 tag. See the ImageMagick manual for a list of ImageMagick formats and
10058 their descriptions (https://www.imagemagick.org/script/formats.php).
10059 You can also try the shell command: `identify -list format'.
10060
10061 Note that ImageMagick recognizes many file-types that Emacs does not
10062 recognize as images, such as C. See `imagemagick-enabled-types'
10063 and `imagemagick-types-inhibit'. */)
10064 (void)
10065 {
10066 Lisp_Object typelist = Qnil;
10067 size_t numf = 0;
10068 ExceptionInfo *ex;
10069 char **imtypes;
10070 size_t i;
10071
10072 imagemagick_initialize ();
10073 ex = AcquireExceptionInfo ();
10074 imtypes = GetMagickList ("*", &numf, ex);
10075 DestroyExceptionInfo (ex);
10076
10077 for (i = 0; i < numf; i++)
10078 {
10079 Lisp_Object imagemagicktype = intern (imtypes[i]);
10080 typelist = Fcons (imagemagicktype, typelist);
10081 imtypes[i] = MagickRelinquishMemory (imtypes[i]);
10082 }
10083
10084 MagickRelinquishMemory (imtypes);
10085 return Fnreverse (typelist);
10086 }
10087
10088 #endif /* defined (HAVE_IMAGEMAGICK) */
10089
10090
10091
10092 /***********************************************************************
10093 SVG
10094 ***********************************************************************/
10095
10096 #ifdef HAVE_RSVG
10097
10098 /* Function prototypes. */
10099
10100 static bool svg_load_image (struct frame *, struct image *,
10101 char *, ptrdiff_t, char *);
10102
10103 /* Indices of image specification fields in svg_format, below. */
10104
10105 enum svg_keyword_index
10106 {
10107 SVG_TYPE,
10108 SVG_DATA,
10109 SVG_FILE,
10110 SVG_BASE_URI,
10111 SVG_CSS,
10112 SVG_ASCENT,
10113 SVG_MARGIN,
10114 SVG_RELIEF,
10115 SVG_ALGORITHM,
10116 SVG_HEURISTIC_MASK,
10117 SVG_MASK,
10118 SVG_FOREGROUND,
10119 SVG_BACKGROUND,
10120 SVG_LAST
10121 };
10122
10123 /* Vector of image_keyword structures describing the format
10124 of valid user-defined image specifications. */
10125
10126 static const struct image_keyword svg_format[SVG_LAST] =
10127 {
10128 {":type", IMAGE_SYMBOL_VALUE, 1},
10129 {":data", IMAGE_STRING_VALUE, 0},
10130 {":file", IMAGE_STRING_VALUE, 0},
10131 {":base-uri", IMAGE_STRING_VALUE, 0},
10132 {":css", IMAGE_STRING_VALUE, 0},
10133 {":ascent", IMAGE_ASCENT_VALUE, 0},
10134 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
10135 {":relief", IMAGE_INTEGER_VALUE, 0},
10136 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10137 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10138 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10139 {":foreground", IMAGE_STRING_OR_NIL_VALUE, 0},
10140 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
10141 };
10142
10143 /* Return true if OBJECT is a valid SVG image specification. Do
10144 this by calling parse_image_spec and supplying the keywords that
10145 identify the SVG format. */
10146
10147 static bool
svg_image_p(Lisp_Object object)10148 svg_image_p (Lisp_Object object)
10149 {
10150 struct image_keyword fmt[SVG_LAST];
10151 memcpy (fmt, svg_format, sizeof fmt);
10152
10153 if (!parse_image_spec (object, fmt, SVG_LAST, Qsvg))
10154 return 0;
10155
10156 /* Must specify either the :data or :file keyword. */
10157 return fmt[SVG_FILE].count + fmt[SVG_DATA].count == 1;
10158 }
10159
10160 /* Some versions of glib's gatomic.h define MemoryBarrier, but MinGW
10161 w32api 3.18 and later has its own definition. The following gross
10162 hack avoids the clash. */
10163 # ifdef WINDOWSNT
10164 # if (__W32API_MAJOR_VERSION + (__W32API_MINOR_VERSION >= 18)) >= 4
10165 # define W32_SAVE_MINGW_VERSION __MINGW_MAJOR_VERSION
10166 # undef __MINGW_MAJOR_VERSION
10167 # define __MINGW_MAJOR_VERSION 4
10168 # endif
10169 # endif
10170
10171 # include <librsvg/rsvg.h>
10172
10173 /* librsvg is too old for us if it doesn't define this macro. */
10174 # ifndef LIBRSVG_CHECK_VERSION
10175 # define LIBRSVG_CHECK_VERSION(v, w, x) false
10176 # endif
10177
10178 # ifdef WINDOWSNT
10179
10180 /* Restore the original definition of __MINGW_MAJOR_VERSION. */
10181 # if defined W32_SAVE_MINGW_VERSION && defined __MINGW_MAJOR_VERSION
10182 # undef __MINGW_MAJOR_VERSION
10183 # define __MINGW_MAJOR_VERSION W32_SAVE_MINGW_VERSION
10184 # ifdef __MINGW_MAJOR_VERSION
10185 # undef W32_SAVE_MINGW_VERSION
10186 # endif
10187 # endif
10188
10189 /* SVG library functions. */
10190 # if LIBRSVG_CHECK_VERSION (2, 32, 0)
10191 DEF_DLL_FN (GFile *, g_file_new_for_path, (char const *));
10192 DEF_DLL_FN (GInputStream *, g_memory_input_stream_new_from_data,
10193 (void const *, gssize, GDestroyNotify));
10194 DEF_DLL_FN (RsvgHandle *, rsvg_handle_new_from_stream_sync,
10195 (GInputStream *, GFile *, RsvgHandleFlags, GCancellable *,
10196 GError **error));
10197 # else
10198 DEF_DLL_FN (RsvgHandle *, rsvg_handle_new, (void));
10199 DEF_DLL_FN (void, rsvg_handle_set_base_uri, (RsvgHandle *, const char *));
10200 DEF_DLL_FN (gboolean, rsvg_handle_write,
10201 (RsvgHandle *, const guchar *, gsize, GError **));
10202 DEF_DLL_FN (gboolean, rsvg_handle_close, (RsvgHandle *, GError **));
10203 # endif
10204
10205 DEF_DLL_FN (void, rsvg_handle_set_dpi_x_y,
10206 (RsvgHandle * handle, double dpi_x, double dpi_y));
10207
10208 # if LIBRSVG_CHECK_VERSION (2, 52, 1)
10209 DEF_DLL_FN (gboolean, rsvg_handle_get_intrinsic_size_in_pixels,
10210 (RsvgHandle *, gdouble *, gdouble *));
10211 # endif
10212 # if LIBRSVG_CHECK_VERSION (2, 46, 0)
10213 DEF_DLL_FN (void, rsvg_handle_get_intrinsic_dimensions,
10214 (RsvgHandle *, gboolean *, RsvgLength *, gboolean *,
10215 RsvgLength *, gboolean *, RsvgRectangle *));
10216 DEF_DLL_FN (gboolean, rsvg_handle_get_geometry_for_layer,
10217 (RsvgHandle *, const char *, const RsvgRectangle *,
10218 RsvgRectangle *, RsvgRectangle *, GError **));
10219 # else
10220 DEF_DLL_FN (void, rsvg_handle_get_dimensions,
10221 (RsvgHandle *, RsvgDimensionData *));
10222 # endif
10223
10224 # if LIBRSVG_CHECK_VERSION (2, 48, 0)
10225 DEF_DLL_FN (gboolean, rsvg_handle_set_stylesheet,
10226 (RsvgHandle *, const guint8 *, gsize, GError **));
10227 # endif
10228 DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
10229 DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
10230 DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
10231 DEF_DLL_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
10232 DEF_DLL_FN (int, gdk_pixbuf_get_rowstride, (const GdkPixbuf *));
10233 DEF_DLL_FN (GdkColorspace, gdk_pixbuf_get_colorspace, (const GdkPixbuf *));
10234 DEF_DLL_FN (int, gdk_pixbuf_get_n_channels, (const GdkPixbuf *));
10235 DEF_DLL_FN (gboolean, gdk_pixbuf_get_has_alpha, (const GdkPixbuf *));
10236 DEF_DLL_FN (int, gdk_pixbuf_get_bits_per_sample, (const GdkPixbuf *));
10237
10238 # if ! GLIB_CHECK_VERSION (2, 36, 0)
10239 DEF_DLL_FN (void, g_type_init, (void));
10240 # endif
10241 DEF_DLL_FN (void, g_object_unref, (gpointer));
10242 DEF_DLL_FN (void, g_clear_error, (GError **));
10243
10244 static bool
init_svg_functions(void)10245 init_svg_functions (void)
10246 {
10247 HMODULE library, gdklib = NULL, glib = NULL, gobject = NULL, giolib = NULL;
10248
10249 if (!(glib = w32_delayed_load (Qglib))
10250 || !(gobject = w32_delayed_load (Qgobject))
10251 # if LIBRSVG_CHECK_VERSION (2, 32, 0)
10252 || !(giolib = w32_delayed_load (Qgio))
10253 # endif
10254 || !(gdklib = w32_delayed_load (Qgdk_pixbuf))
10255 || !(library = w32_delayed_load (Qsvg)))
10256 {
10257 if (gdklib) FreeLibrary (gdklib);
10258 if (giolib) FreeLibrary (giolib);
10259 if (gobject) FreeLibrary (gobject);
10260 if (glib) FreeLibrary (glib);
10261 return 0;
10262 }
10263
10264 #if LIBRSVG_CHECK_VERSION (2, 32, 0)
10265 LOAD_DLL_FN (giolib, g_file_new_for_path);
10266 LOAD_DLL_FN (giolib, g_memory_input_stream_new_from_data);
10267 LOAD_DLL_FN (library, rsvg_handle_new_from_stream_sync);
10268 #else
10269 LOAD_DLL_FN (library, rsvg_handle_new);
10270 LOAD_DLL_FN (library, rsvg_handle_set_base_uri);
10271 LOAD_DLL_FN (library, rsvg_handle_write);
10272 LOAD_DLL_FN (library, rsvg_handle_close);
10273 #endif
10274 LOAD_DLL_FN (library, rsvg_handle_set_dpi_x_y);
10275 #if LIBRSVG_CHECK_VERSION (2, 52, 1)
10276 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_size_in_pixels);
10277 #endif
10278 #if LIBRSVG_CHECK_VERSION (2, 46, 0)
10279 LOAD_DLL_FN (library, rsvg_handle_get_intrinsic_dimensions);
10280 LOAD_DLL_FN (library, rsvg_handle_get_geometry_for_layer);
10281 #else
10282 LOAD_DLL_FN (library, rsvg_handle_get_dimensions);
10283 #endif
10284 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10285 LOAD_DLL_FN (library, rsvg_handle_set_stylesheet);
10286 #endif
10287 LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
10288
10289 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_width);
10290 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_height);
10291 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_pixels);
10292 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_rowstride);
10293 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_colorspace);
10294 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_n_channels);
10295 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_has_alpha);
10296 LOAD_DLL_FN (gdklib, gdk_pixbuf_get_bits_per_sample);
10297
10298 # if ! GLIB_CHECK_VERSION (2, 36, 0)
10299 LOAD_DLL_FN (gobject, g_type_init);
10300 # endif
10301 LOAD_DLL_FN (gobject, g_object_unref);
10302 LOAD_DLL_FN (glib, g_clear_error);
10303
10304 return 1;
10305 }
10306
10307 /* The following aliases for library functions allow dynamic loading
10308 to be used on some platforms. */
10309
10310 # undef gdk_pixbuf_get_bits_per_sample
10311 # undef gdk_pixbuf_get_colorspace
10312 # undef gdk_pixbuf_get_has_alpha
10313 # undef gdk_pixbuf_get_height
10314 # undef gdk_pixbuf_get_n_channels
10315 # undef gdk_pixbuf_get_pixels
10316 # undef gdk_pixbuf_get_rowstride
10317 # undef gdk_pixbuf_get_width
10318 # undef g_clear_error
10319 # undef g_object_unref
10320 # undef g_type_init
10321 # if LIBRSVG_CHECK_VERSION (2, 52, 1)
10322 # undef rsvg_handle_get_intrinsic_size_in_pixels
10323 # endif
10324 # if LIBRSVG_CHECK_VERSION (2, 46, 0)
10325 # undef rsvg_handle_get_intrinsic_dimensions
10326 # undef rsvg_handle_get_geometry_for_layer
10327 # else
10328 # undef rsvg_handle_get_dimensions
10329 # endif
10330 # if LIBRSVG_CHECK_VERSION (2, 48, 0)
10331 # undef rsvg_handle_set_stylesheet
10332 # endif
10333 # undef rsvg_handle_get_pixbuf
10334 # if LIBRSVG_CHECK_VERSION (2, 32, 0)
10335 # undef g_file_new_for_path
10336 # undef g_memory_input_stream_new_from_data
10337 # undef rsvg_handle_new_from_stream_sync
10338 # else
10339 # undef rsvg_handle_close
10340 # undef rsvg_handle_new
10341 # undef rsvg_handle_set_base_uri
10342 # undef rsvg_handle_write
10343 # endif
10344 # undef rsvg_handle_set_dpi_x_y
10345
10346 # define gdk_pixbuf_get_bits_per_sample fn_gdk_pixbuf_get_bits_per_sample
10347 # define gdk_pixbuf_get_colorspace fn_gdk_pixbuf_get_colorspace
10348 # define gdk_pixbuf_get_has_alpha fn_gdk_pixbuf_get_has_alpha
10349 # define gdk_pixbuf_get_height fn_gdk_pixbuf_get_height
10350 # define gdk_pixbuf_get_n_channels fn_gdk_pixbuf_get_n_channels
10351 # define gdk_pixbuf_get_pixels fn_gdk_pixbuf_get_pixels
10352 # define gdk_pixbuf_get_rowstride fn_gdk_pixbuf_get_rowstride
10353 # define gdk_pixbuf_get_width fn_gdk_pixbuf_get_width
10354 # define g_clear_error fn_g_clear_error
10355 # define g_object_unref fn_g_object_unref
10356 # if ! GLIB_CHECK_VERSION (2, 36, 0)
10357 # define g_type_init fn_g_type_init
10358 # endif
10359 # if LIBRSVG_CHECK_VERSION (2, 52, 1)
10360 # define rsvg_handle_get_intrinsic_size_in_pixels \
10361 fn_rsvg_handle_get_intrinsic_size_in_pixels
10362 # endif
10363 # if LIBRSVG_CHECK_VERSION (2, 46, 0)
10364 # define rsvg_handle_get_intrinsic_dimensions \
10365 fn_rsvg_handle_get_intrinsic_dimensions
10366 # define rsvg_handle_get_geometry_for_layer \
10367 fn_rsvg_handle_get_geometry_for_layer
10368 # else
10369 # define rsvg_handle_get_dimensions fn_rsvg_handle_get_dimensions
10370 # endif
10371 # if LIBRSVG_CHECK_VERSION (2, 48, 0)
10372 # define rsvg_handle_set_stylesheet fn_rsvg_handle_set_stylesheet
10373 # endif
10374 # define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
10375 # if LIBRSVG_CHECK_VERSION (2, 32, 0)
10376 # define g_file_new_for_path fn_g_file_new_for_path
10377 # define g_memory_input_stream_new_from_data \
10378 fn_g_memory_input_stream_new_from_data
10379 # define rsvg_handle_new_from_stream_sync fn_rsvg_handle_new_from_stream_sync
10380 # else
10381 # define rsvg_handle_close fn_rsvg_handle_close
10382 # define rsvg_handle_new fn_rsvg_handle_new
10383 # define rsvg_handle_set_base_uri fn_rsvg_handle_set_base_uri
10384 # define rsvg_handle_write fn_rsvg_handle_write
10385 # endif
10386 # define rsvg_handle_set_dpi_x_y fn_rsvg_handle_set_dpi_x_y
10387
10388 # endif /* !WINDOWSNT */
10389
10390 /* Load SVG image IMG for use on frame F. Value is true if
10391 successful. */
10392
10393 static bool
svg_load(struct frame * f,struct image * img)10394 svg_load (struct frame *f, struct image *img)
10395 {
10396 bool success_p = 0;
10397 Lisp_Object file_name, base_uri;
10398
10399 /* If IMG->spec specifies a file name, create a non-file spec from it. */
10400 file_name = image_spec_value (img->spec, QCfile, NULL);
10401 base_uri = image_spec_value (img->spec, QCbase_uri, NULL);
10402 if (STRINGP (file_name))
10403 {
10404 int fd;
10405 Lisp_Object file = image_find_image_fd (file_name, &fd);
10406 if (!STRINGP (file))
10407 {
10408 image_error ("Cannot find image file `%s'", file_name);
10409 return 0;
10410 }
10411
10412 /* Read the entire file into memory. */
10413 ptrdiff_t size;
10414 char *contents = slurp_file (fd, &size);
10415 if (contents == NULL)
10416 {
10417 image_error ("Error loading SVG image `%s'", file);
10418 return 0;
10419 }
10420 /* If the file was slurped into memory properly, parse it. */
10421 if (!STRINGP (base_uri))
10422 base_uri = file;
10423 success_p = svg_load_image (f, img, contents, size,
10424 SSDATA (ENCODE_FILE (base_uri)));
10425 xfree (contents);
10426 }
10427 /* Else it's not a file, it's a Lisp object. Load the image from a
10428 Lisp object rather than a file. */
10429 else
10430 {
10431 Lisp_Object data;
10432
10433 data = image_spec_value (img->spec, QCdata, NULL);
10434 if (!STRINGP (data))
10435 {
10436 image_error ("Invalid image data `%s'", data);
10437 return 0;
10438 }
10439 if (!STRINGP (base_uri))
10440 base_uri = BVAR (current_buffer, filename);
10441 success_p = svg_load_image (f, img, SSDATA (data), SBYTES (data),
10442 (STRINGP (base_uri) ?
10443 SSDATA (ENCODE_FILE (base_uri)) : NULL));
10444 }
10445
10446 return success_p;
10447 }
10448
10449 #if LIBRSVG_CHECK_VERSION (2, 46, 0)
10450 static double
svg_css_length_to_pixels(RsvgLength length,double dpi,int font_size)10451 svg_css_length_to_pixels (RsvgLength length, double dpi, int font_size)
10452 {
10453 double value = length.length;
10454
10455 switch (length.unit)
10456 {
10457 case RSVG_UNIT_PX:
10458 /* Already a pixel value. */
10459 break;
10460 case RSVG_UNIT_CM:
10461 /* 2.54 cm in an inch. */
10462 value = dpi * value / 2.54;
10463 break;
10464 case RSVG_UNIT_MM:
10465 /* 25.4 mm in an inch. */
10466 value = dpi * value / 25.4;
10467 break;
10468 case RSVG_UNIT_PT:
10469 /* 72 points in an inch. */
10470 value = dpi * value / 72;
10471 break;
10472 case RSVG_UNIT_PC:
10473 /* 6 picas in an inch. */
10474 value = dpi * value / 6;
10475 break;
10476 case RSVG_UNIT_IN:
10477 value *= dpi;
10478 break;
10479 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10480 /* We don't know exactly what font size is used on older librsvg
10481 versions. */
10482 case RSVG_UNIT_EM:
10483 value *= font_size;
10484 break;
10485 #endif
10486 default:
10487 /* Probably ex or %. We can't know what the pixel value is
10488 without more information. */
10489 value = 0;
10490 }
10491
10492 return value;
10493 }
10494 #endif
10495
10496 /* Load frame F and image IMG. CONTENTS contains the SVG XML data to
10497 be parsed, SIZE is its size, and FILENAME is the name of the SVG
10498 file being loaded.
10499
10500 Use librsvg to do most of the image processing.
10501
10502 Return true when successful. */
10503 static bool
svg_load_image(struct frame * f,struct image * img,char * contents,ptrdiff_t size,char * filename)10504 svg_load_image (struct frame *f, struct image *img, char *contents,
10505 ptrdiff_t size, char *filename)
10506 {
10507 RsvgHandle *rsvg_handle;
10508 double viewbox_width, viewbox_height;
10509 GError *err = NULL;
10510 GdkPixbuf *pixbuf;
10511 int width;
10512 int height;
10513 const guint8 *pixels;
10514 int rowstride;
10515 char *wrapped_contents = NULL;
10516 ptrdiff_t wrapped_size;
10517
10518 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10519 char *css = NULL;
10520 #endif
10521
10522 #if ! GLIB_CHECK_VERSION (2, 36, 0)
10523 /* g_type_init is a glib function that must be called prior to
10524 using gnome type library functions (obsolete since 2.36.0). */
10525 g_type_init ();
10526 #endif
10527
10528 /* Parse the unmodified SVG data so we can get its initial size. */
10529
10530 #if LIBRSVG_CHECK_VERSION (2, 32, 0)
10531 GInputStream *input_stream
10532 = g_memory_input_stream_new_from_data (contents, size, NULL);
10533 GFile *base_file = filename ? g_file_new_for_path (filename) : NULL;
10534 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
10535 RSVG_HANDLE_FLAGS_NONE,
10536 NULL, &err);
10537
10538 if (base_file)
10539 g_object_unref (base_file);
10540 g_object_unref (input_stream);
10541
10542 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */
10543 if (!rsvg_handle || err) goto rsvg_error;
10544
10545 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10546 FRAME_DISPLAY_INFO (f)->resy);
10547
10548 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10549 Lisp_Object lcss = image_spec_value (img->spec, QCcss, NULL);
10550 if (!STRINGP (lcss))
10551 {
10552 /* Generate the CSS for the SVG image. */
10553 /* FIXME: The below calculations leave enough space for a font
10554 size up to 9999, if it overflows we just throw an error but
10555 should probably increase the buffer size. */
10556 const char *css_spec = "svg{font-family:\"%s\";font-size:%dpx}";
10557 int css_len = strlen (css_spec) + strlen (img->face_font_family) + 1;
10558 css = xmalloc (css_len);
10559 if (css_len <= snprintf (css, css_len, css_spec,
10560 img->face_font_family, img->face_font_size))
10561 goto rsvg_error;
10562
10563 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
10564 }
10565 else
10566 {
10567 css = xmalloc (SBYTES (lcss) + 1);
10568 strncpy (css, SSDATA (lcss), SBYTES (lcss));
10569 *(css + SBYTES (lcss) + 1) = 0;
10570 }
10571 #endif
10572
10573 #else
10574 /* Make a handle to a new rsvg object. */
10575 rsvg_handle = rsvg_handle_new ();
10576 eassume (rsvg_handle);
10577
10578 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10579 FRAME_DISPLAY_INFO (f)->resy);
10580
10581 /* Set base_uri for properly handling referenced images (via 'href').
10582 Can be explicitly specified using `:base_uri' image property.
10583 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
10584 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
10585 if (filename)
10586 rsvg_handle_set_base_uri (rsvg_handle, filename);
10587
10588 /* Parse the contents argument and fill in the rsvg_handle. */
10589 rsvg_handle_write (rsvg_handle, (unsigned char *) contents, size, &err);
10590 if (err) goto rsvg_error;
10591
10592 /* The parsing is complete, rsvg_handle is ready to be used, close
10593 it for further writes. */
10594 rsvg_handle_close (rsvg_handle, &err);
10595 if (err) goto rsvg_error;
10596 #endif
10597
10598 /* Get the image dimensions. */
10599 #if LIBRSVG_CHECK_VERSION (2, 46, 0)
10600 gdouble gviewbox_width = 0, gviewbox_height = 0;
10601 gboolean has_viewbox = FALSE;
10602 # if LIBRSVG_CHECK_VERSION (2, 52, 1)
10603 has_viewbox = rsvg_handle_get_intrinsic_size_in_pixels (rsvg_handle,
10604 &gviewbox_width,
10605 &gviewbox_height);
10606 # endif
10607
10608 if (has_viewbox)
10609 {
10610 viewbox_width = gviewbox_width;
10611 viewbox_height = gviewbox_height;
10612 }
10613 else
10614 {
10615 RsvgRectangle zero_rect, viewbox, out_logical_rect;
10616
10617 /* Try the intrinsic dimensions first. */
10618 gboolean has_width, has_height;
10619 RsvgLength iwidth, iheight;
10620 double dpi = FRAME_DISPLAY_INFO (f)->resx;
10621
10622 rsvg_handle_get_intrinsic_dimensions (rsvg_handle,
10623 &has_width, &iwidth,
10624 &has_height, &iheight,
10625 &has_viewbox, &viewbox);
10626
10627 if (has_width && has_height)
10628 {
10629 /* Success! We can use these values directly. */
10630 viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
10631 img->face_font_size);
10632 viewbox_height = svg_css_length_to_pixels (iheight, dpi,
10633 img->face_font_size);
10634 }
10635 else if (has_width && has_viewbox)
10636 {
10637 viewbox_width = svg_css_length_to_pixels (iwidth, dpi,
10638 img->face_font_size);
10639 viewbox_height = viewbox_width * viewbox.height / viewbox.width;
10640 }
10641 else if (has_height && has_viewbox)
10642 {
10643 viewbox_height = svg_css_length_to_pixels (iheight, dpi,
10644 img->face_font_size);
10645 viewbox_width = viewbox_height * viewbox.width / viewbox.height;
10646 }
10647 else if (has_viewbox)
10648 {
10649 viewbox_width = viewbox.width;
10650 viewbox_height = viewbox.height;
10651 }
10652 else
10653 viewbox_width = viewbox_height = 0;
10654
10655 if (! (0 < viewbox_width && 0 < viewbox_height))
10656 {
10657 /* We haven't found a usable set of sizes, so try working out
10658 the visible area. */
10659 rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL,
10660 &zero_rect, &viewbox,
10661 &out_logical_rect, NULL);
10662 viewbox_width = viewbox.x + viewbox.width;
10663 viewbox_height = viewbox.y + viewbox.height;
10664 }
10665 }
10666 #else
10667 /* In librsvg before 2.46.0, guess the viewbox from the image dimensions. */
10668 RsvgDimensionData dimension_data;
10669 rsvg_handle_get_dimensions (rsvg_handle, &dimension_data);
10670 viewbox_width = dimension_data.width;
10671 viewbox_height = dimension_data.height;
10672 #endif
10673
10674 compute_image_size (viewbox_width, viewbox_height, img,
10675 &width, &height);
10676
10677 width = scale_image_size (width, 1, FRAME_SCALE_FACTOR (f));
10678 height = scale_image_size (height, 1, FRAME_SCALE_FACTOR (f));
10679
10680 if (! check_image_size (f, width, height))
10681 {
10682 image_size_error ();
10683 goto rsvg_error;
10684 }
10685
10686 /* We are now done with the unmodified data. */
10687 g_object_unref (rsvg_handle);
10688
10689 /* Wrap the SVG data in another SVG. This allows us to set the
10690 width and height, as well as modify the foreground and background
10691 colors. */
10692 {
10693 Lisp_Object value;
10694 unsigned long foreground = img->face_foreground;
10695 unsigned long background = img->face_background;
10696
10697 Lisp_Object encoded_contents
10698 = Fbase64_encode_string (make_unibyte_string (contents, size), Qt);
10699
10700 /* The wrapper sets the foreground color, width and height, and
10701 viewBox must contain the dimensions of the original image. It
10702 also draws a rectangle over the whole space, set to the
10703 background color, before including the original image. This
10704 acts to set the background color, instead of leaving it
10705 transparent. */
10706 const char *wrapper =
10707 "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
10708 "xmlns:xi=\"http://www.w3.org/2001/XInclude\" "
10709 "style=\"color: #%06X; fill: currentColor;\" "
10710 "width=\"%d\" height=\"%d\" preserveAspectRatio=\"none\" "
10711 "viewBox=\"0 0 %f %f\">"
10712 "<rect width=\"100%%\" height=\"100%%\" fill=\"#%06X\"/>"
10713 "<xi:include href=\"data:image/svg+xml;base64,%s\"></xi:include>"
10714 "</svg>";
10715
10716 /* FIXME: I've added 64 in the hope it will cover the size of the
10717 width and height strings and things. */
10718 int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64;
10719
10720 value = image_spec_value (img->spec, QCforeground, NULL);
10721 if (!NILP (value))
10722 foreground = image_alloc_image_color (f, img, value, img->face_foreground);
10723 value = image_spec_value (img->spec, QCbackground, NULL);
10724 if (!NILP (value))
10725 {
10726 background = image_alloc_image_color (f, img, value, img->face_background);
10727 img->background = background;
10728 img->background_valid = 1;
10729 }
10730
10731 wrapped_contents = xmalloc (buffer_size);
10732
10733 if (buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper,
10734 foreground & 0xFFFFFF, width, height,
10735 viewbox_width, viewbox_height,
10736 background & 0xFFFFFF,
10737 SSDATA (encoded_contents)))
10738 goto rsvg_error;
10739
10740 wrapped_size = strlen (wrapped_contents);
10741 }
10742
10743 /* Now we parse the wrapped version. */
10744
10745 #if LIBRSVG_CHECK_VERSION (2, 32, 0)
10746 input_stream = g_memory_input_stream_new_from_data (wrapped_contents, wrapped_size, NULL);
10747 base_file = filename ? g_file_new_for_path (filename) : NULL;
10748 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
10749 RSVG_HANDLE_FLAGS_NONE,
10750 NULL, &err);
10751
10752 if (base_file)
10753 g_object_unref (base_file);
10754 g_object_unref (input_stream);
10755
10756 /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26). */
10757 if (!rsvg_handle || err) goto rsvg_error;
10758
10759 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10760 FRAME_DISPLAY_INFO (f)->resy);
10761
10762 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10763 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
10764 #endif
10765 #else
10766 /* Make a handle to a new rsvg object. */
10767 rsvg_handle = rsvg_handle_new ();
10768 eassume (rsvg_handle);
10769
10770 rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
10771 FRAME_DISPLAY_INFO (f)->resy);
10772
10773 /* Set base_uri for properly handling referenced images (via 'href').
10774 Can be explicitly specified using `:base_uri' image property.
10775 See rsvg bug 596114 - "image refs are relative to curdir, not .svg file"
10776 <https://gitlab.gnome.org/GNOME/librsvg/issues/33>. */
10777 if (filename)
10778 rsvg_handle_set_base_uri (rsvg_handle, filename);
10779
10780 /* Parse the contents argument and fill in the rsvg_handle. */
10781 rsvg_handle_write (rsvg_handle, (unsigned char *) wrapped_contents, wrapped_size, &err);
10782 if (err) goto rsvg_error;
10783
10784 /* The parsing is complete, rsvg_handle is ready to used, close it
10785 for further writes. */
10786 rsvg_handle_close (rsvg_handle, &err);
10787 if (err) goto rsvg_error;
10788 #endif
10789
10790
10791 /* We can now get a valid pixel buffer from the svg file, if all
10792 went ok. */
10793 pixbuf = rsvg_handle_get_pixbuf (rsvg_handle);
10794 if (!pixbuf) goto rsvg_error;
10795 g_object_unref (rsvg_handle);
10796 xfree (wrapped_contents);
10797
10798 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10799 if (!STRINGP (lcss))
10800 xfree (css);
10801 #endif
10802
10803 /* Extract some meta data from the svg handle. */
10804 width = gdk_pixbuf_get_width (pixbuf);
10805 height = gdk_pixbuf_get_height (pixbuf);
10806 pixels = gdk_pixbuf_get_pixels (pixbuf);
10807 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
10808
10809 /* Validate the svg meta data. */
10810 eassert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
10811 eassert (gdk_pixbuf_get_n_channels (pixbuf) == 4);
10812 eassert (gdk_pixbuf_get_has_alpha (pixbuf));
10813 eassert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
10814
10815 {
10816 /* Try to create a x pixmap to hold the svg pixmap. */
10817 Emacs_Pix_Container ximg;
10818 if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0))
10819 {
10820 g_object_unref (pixbuf);
10821 return 0;
10822 }
10823
10824 init_color_table ();
10825
10826 /* This loop handles opacity values, since Emacs assumes
10827 non-transparent images. Each pixel must be "flattened" by
10828 calculating the resulting color, given the transparency of the
10829 pixel, and the image background color. */
10830 for (int y = 0; y < height; ++y)
10831 {
10832 for (int x = 0; x < width; ++x)
10833 {
10834 int red = *pixels++;
10835 int green = *pixels++;
10836 int blue = *pixels++;
10837
10838 /* Skip opacity. */
10839 pixels++;
10840
10841 PUT_PIXEL (ximg, x, y, lookup_rgb_color (f, red << 8, green << 8, blue << 8));
10842 }
10843
10844 pixels += rowstride - 4 * width;
10845 }
10846
10847 #ifdef COLOR_TABLE_SUPPORT
10848 /* Remember colors allocated for this image. */
10849 img->colors = colors_in_color_table (&img->ncolors);
10850 free_color_table ();
10851 #endif /* COLOR_TABLE_SUPPORT */
10852
10853 g_object_unref (pixbuf);
10854
10855 img->width = width;
10856 img->height = height;
10857
10858 /* Maybe fill in the background field while we have ximg handy.
10859 Casting avoids a GCC warning. */
10860 IMAGE_BACKGROUND (img, f, (Emacs_Pix_Context)ximg);
10861
10862 /* Put ximg into the image. */
10863 image_put_x_image (f, img, ximg, 0);
10864 }
10865
10866 return 1;
10867
10868 rsvg_error:
10869 if (rsvg_handle)
10870 g_object_unref (rsvg_handle);
10871 if (wrapped_contents)
10872 xfree (wrapped_contents);
10873 #if LIBRSVG_CHECK_VERSION (2, 48, 0)
10874 if (css && !STRINGP (lcss))
10875 xfree (css);
10876 #endif
10877 /* FIXME: Use error->message so the user knows what is the actual
10878 problem with the image. */
10879 image_error ("Error parsing SVG image `%s'", img->spec);
10880 g_clear_error (&err);
10881 return 0;
10882 }
10883
10884 #endif /* defined (HAVE_RSVG) */
10885
10886
10887
10888
10889 /***********************************************************************
10890 Ghostscript
10891 ***********************************************************************/
10892
10893 #if defined HAVE_X_WINDOWS && !defined USE_CAIRO
10894 #define HAVE_GHOSTSCRIPT 1
10895 #endif /* HAVE_X_WINDOWS && !USE_CAIRO */
10896
10897 #ifdef HAVE_GHOSTSCRIPT
10898
10899 /* Indices of image specification fields in gs_format, below. */
10900
10901 enum gs_keyword_index
10902 {
10903 GS_TYPE,
10904 GS_PT_WIDTH,
10905 GS_PT_HEIGHT,
10906 GS_FILE,
10907 GS_LOADER,
10908 GS_BOUNDING_BOX,
10909 GS_ASCENT,
10910 GS_MARGIN,
10911 GS_RELIEF,
10912 GS_ALGORITHM,
10913 GS_HEURISTIC_MASK,
10914 GS_MASK,
10915 GS_BACKGROUND,
10916 GS_LAST
10917 };
10918
10919 /* Vector of image_keyword structures describing the format
10920 of valid user-defined image specifications. */
10921
10922 static const struct image_keyword gs_format[GS_LAST] =
10923 {
10924 {":type", IMAGE_SYMBOL_VALUE, 1},
10925 {":pt-width", IMAGE_POSITIVE_INTEGER_VALUE, 1},
10926 {":pt-height", IMAGE_POSITIVE_INTEGER_VALUE, 1},
10927 {":file", IMAGE_STRING_VALUE, 1},
10928 {":loader", IMAGE_FUNCTION_VALUE, 0},
10929 {":bounding-box", IMAGE_DONT_CHECK_VALUE_TYPE, 1},
10930 {":ascent", IMAGE_ASCENT_VALUE, 0},
10931 {":margin", IMAGE_NON_NEGATIVE_INTEGER_VALUE_OR_PAIR, 0},
10932 {":relief", IMAGE_INTEGER_VALUE, 0},
10933 {":conversion", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10934 {":heuristic-mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10935 {":mask", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
10936 {":background", IMAGE_STRING_OR_NIL_VALUE, 0}
10937 };
10938
10939 /* Return true if OBJECT is a valid Ghostscript image
10940 specification. */
10941
10942 static bool
gs_image_p(Lisp_Object object)10943 gs_image_p (Lisp_Object object)
10944 {
10945 struct image_keyword fmt[GS_LAST];
10946 Lisp_Object tem;
10947 int i;
10948
10949 memcpy (fmt, gs_format, sizeof fmt);
10950
10951 if (!parse_image_spec (object, fmt, GS_LAST, Qpostscript))
10952 return 0;
10953
10954 /* Bounding box must be a list or vector containing 4 integers. */
10955 tem = fmt[GS_BOUNDING_BOX].value;
10956 if (CONSP (tem))
10957 {
10958 for (i = 0; i < 4; ++i, tem = XCDR (tem))
10959 if (!CONSP (tem) || !FIXNUMP (XCAR (tem)))
10960 return 0;
10961 if (!NILP (tem))
10962 return 0;
10963 }
10964 else if (VECTORP (tem))
10965 {
10966 if (ASIZE (tem) != 4)
10967 return 0;
10968 for (i = 0; i < 4; ++i)
10969 if (!FIXNUMP (AREF (tem, i)))
10970 return 0;
10971 }
10972 else
10973 return 0;
10974
10975 return 1;
10976 }
10977
10978
10979 /* Load Ghostscript image IMG for use on frame F. Value is true
10980 if successful. */
10981
10982 static bool
gs_load(struct frame * f,struct image * img)10983 gs_load (struct frame *f, struct image *img)
10984 {
10985 uintmax_t printnum1, printnum2;
10986 char buffer[sizeof " " + 2 * INT_STRLEN_BOUND (intmax_t)];
10987 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
10988 Lisp_Object frame;
10989 double in_width, in_height;
10990 Lisp_Object pixel_colors = Qnil;
10991
10992 /* Compute pixel size of pixmap needed from the given size in the
10993 image specification. Sizes in the specification are in pt. 1 pt
10994 = 1/72 in, xdpi and ydpi are stored in the frame's X display
10995 info. */
10996 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
10997 in_width = FIXNUMP (pt_width) ? XFIXNAT (pt_width) / 72.0 : 0;
10998 in_width *= FRAME_RES_X (f);
10999 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
11000 in_height = FIXNUMP (pt_height) ? XFIXNAT (pt_height) / 72.0 : 0;
11001 in_height *= FRAME_RES_Y (f);
11002
11003 if (! (in_width <= INT_MAX && in_height <= INT_MAX
11004 && check_image_size (f, in_width, in_height)))
11005 {
11006 image_size_error ();
11007 return 0;
11008 }
11009 img->width = in_width;
11010 img->height = in_height;
11011
11012 /* Create the pixmap. */
11013 eassert (img->pixmap == NO_PIXMAP);
11014
11015 if (image_check_image_size (0, img->width, img->height))
11016 {
11017 /* Only W32 version did BLOCK_INPUT here. ++kfs */
11018 block_input ();
11019 img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
11020 img->width, img->height,
11021 DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
11022 unblock_input ();
11023 }
11024
11025 if (!img->pixmap)
11026 {
11027 image_error ("Unable to create pixmap for `%s'" , img->spec);
11028 return 0;
11029 }
11030
11031 /* Call the loader to fill the pixmap. It returns a process object
11032 if successful. We do not record_unwind_protect here because
11033 other places in redisplay like calling window scroll functions
11034 don't either. Let the Lisp loader use `unwind-protect' instead. */
11035 printnum1 = FRAME_X_DRAWABLE (f);
11036 printnum2 = img->pixmap;
11037 window_and_pixmap_id
11038 = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX,
11039 printnum1, printnum2);
11040
11041 printnum1 = FRAME_FOREGROUND_PIXEL (f);
11042 printnum2 = FRAME_BACKGROUND_PIXEL (f);
11043 pixel_colors
11044 = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX,
11045 printnum1, printnum2);
11046
11047 XSETFRAME (frame, f);
11048 loader = image_spec_value (img->spec, QCloader, NULL);
11049 if (NILP (loader))
11050 loader = intern ("gs-load-image");
11051
11052 img->lisp_data = call6 (loader, frame, img->spec,
11053 make_fixnum (img->width),
11054 make_fixnum (img->height),
11055 window_and_pixmap_id,
11056 pixel_colors);
11057 return PROCESSP (img->lisp_data);
11058 }
11059
11060
11061 /* Kill the Ghostscript process that was started to fill PIXMAP on
11062 frame F. Called from XTread_socket when receiving an event
11063 telling Emacs that Ghostscript has finished drawing. */
11064
11065 void
x_kill_gs_process(Pixmap pixmap,struct frame * f)11066 x_kill_gs_process (Pixmap pixmap, struct frame *f)
11067 {
11068 struct image_cache *c = FRAME_IMAGE_CACHE (f);
11069 ptrdiff_t i;
11070 struct image *img;
11071
11072 /* Find the image containing PIXMAP. */
11073 for (i = 0; i < c->used; ++i)
11074 if (c->images[i]->pixmap == pixmap)
11075 break;
11076
11077 /* Should someone in between have cleared the image cache, for
11078 instance, give up. */
11079 if (i == c->used)
11080 return;
11081
11082 /* Kill the GS process. We should have found PIXMAP in the image
11083 cache and its image should contain a process object. */
11084 img = c->images[i];
11085 eassert (PROCESSP (img->lisp_data));
11086 Fkill_process (img->lisp_data, Qnil);
11087 img->lisp_data = Qnil;
11088
11089 #if defined (HAVE_X_WINDOWS)
11090
11091 /* On displays with a mutable colormap, figure out the colors
11092 allocated for the image by looking at the pixels of an XImage for
11093 img->pixmap. */
11094 if (x_mutable_colormap (FRAME_X_VISUAL (f)))
11095 {
11096 XImage *ximg;
11097
11098 block_input ();
11099
11100 /* Try to get an XImage for img->pixmep. */
11101 ximg = XGetImage (FRAME_X_DISPLAY (f), img->pixmap,
11102 0, 0, img->width, img->height, ~0, ZPixmap);
11103 if (ximg)
11104 {
11105 /* Initialize the color table. */
11106 init_color_table ();
11107
11108 /* For each pixel of the image, look its color up in the
11109 color table. After having done so, the color table will
11110 contain an entry for each color used by the image. */
11111 #ifdef COLOR_TABLE_SUPPORT
11112 for (int y = 0; y < img->height; ++y)
11113 for (int x = 0; x < img->width; ++x)
11114 {
11115 unsigned long pixel = XGetPixel (ximg, x, y);
11116
11117 lookup_pixel_color (f, pixel);
11118 }
11119
11120 /* Record colors in the image. Free color table and XImage. */
11121 img->colors = colors_in_color_table (&img->ncolors);
11122 free_color_table ();
11123 #endif
11124 XDestroyImage (ximg);
11125 }
11126 else
11127 image_error ("Cannot get X image of `%s'; colors will not be freed",
11128 img->spec);
11129
11130 unblock_input ();
11131 }
11132 #endif /* HAVE_X_WINDOWS */
11133
11134 /* Now that we have the pixmap, compute mask and transform the
11135 image if requested. */
11136 block_input ();
11137 postprocess_image (f, img);
11138 unblock_input ();
11139 }
11140
11141 #endif /* HAVE_GHOSTSCRIPT */
11142
11143
11144 /***********************************************************************
11145 Tests
11146 ***********************************************************************/
11147
11148 #ifdef GLYPH_DEBUG
11149
11150 DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
11151 doc: /* Value is non-nil if SPEC is a valid image specification. */)
11152 (Lisp_Object spec)
11153 {
11154 return valid_image_p (spec) ? Qt : Qnil;
11155 }
11156
11157
11158 DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0,
11159 doc: /* */)
11160 (Lisp_Object spec)
11161 {
11162 ptrdiff_t id = -1;
11163
11164 if (valid_image_p (spec))
11165 id = lookup_image (SELECTED_FRAME (), spec, -1);
11166
11167 debug_print (spec);
11168 return make_fixnum (id);
11169 }
11170
11171 #endif /* GLYPH_DEBUG */
11172
11173
11174 /***********************************************************************
11175 Initialization
11176 ***********************************************************************/
11177
11178 DEFUN ("image-transforms-p", Fimage_transforms_p, Simage_transforms_p, 0, 1, 0,
11179 doc: /* Test whether FRAME supports image transformation.
11180 Return list of capabilities if FRAME supports native transforms, nil otherwise.
11181 FRAME defaults to the selected frame.
11182 The list of capabilities can include one or more of the following:
11183
11184 - the symbol `scale' if FRAME supports image scaling
11185 - the symbol `rotate90' if FRAME supports image rotation only by angles
11186 that are integral multiples of 90 degrees. */)
11187 (Lisp_Object frame)
11188 {
11189 struct frame *f = decode_live_frame (frame);
11190 if (FRAME_WINDOW_P (f))
11191 {
11192 #ifdef HAVE_NATIVE_TRANSFORMS
11193 # if defined HAVE_IMAGEMAGICK || defined (USE_CAIRO) || defined (HAVE_NS) \
11194 || defined (HAVE_HAIKU)
11195 return list2 (Qscale, Qrotate90);
11196 # elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
11197 int event_basep, error_basep;
11198
11199 if (XRenderQueryExtension (FRAME_X_DISPLAY (f),
11200 &event_basep, &error_basep))
11201 return list2 (Qscale, Qrotate90);
11202 # elif defined (HAVE_NTGUI)
11203 return (w32_image_rotations_p ()
11204 ? list2 (Qscale, Qrotate90)
11205 : list1 (Qscale));
11206 # endif
11207 #endif
11208 }
11209
11210 return Qnil;
11211 }
11212
11213 DEFUN ("init-image-library", Finit_image_library, Sinit_image_library, 1, 1, 0,
11214 doc: /* Initialize image library implementing image type TYPE.
11215 Return t if TYPE is a supported image type.
11216
11217 If image libraries are loaded dynamically (currently the case only on
11218 MS-Windows), load the library for TYPE if it is not yet loaded, using
11219 the library file(s) specified by `dynamic-library-alist'. */)
11220 (Lisp_Object type)
11221 {
11222 return lookup_image_type (type) ? Qt : Qnil;
11223 }
11224
11225 static bool
initialize_image_type(struct image_type const * type)11226 initialize_image_type (struct image_type const *type)
11227 {
11228 #ifdef WINDOWSNT
11229 Lisp_Object typesym = builtin_lisp_symbol (type->type);
11230
11231 # if HAVE_NATIVE_IMAGE_API
11232 if (image_can_use_native_api (typesym))
11233 return true;
11234 # endif
11235
11236 Lisp_Object tested = Fassq (typesym, Vlibrary_cache);
11237 /* If we failed to load the library before, don't try again. */
11238 if (CONSP (tested))
11239 return !NILP (XCDR (tested)) ? true : false;
11240
11241 bool (*init) (void) = type->init;
11242 if (init)
11243 {
11244 bool type_valid = init ();
11245 Vlibrary_cache = Fcons (Fcons (typesym, type_valid ? Qt : Qnil),
11246 Vlibrary_cache);
11247 return type_valid;
11248 }
11249 #endif
11250 return true;
11251 }
11252
11253 /* Array of supported image types. */
11254
11255 static struct image_type const image_types[] =
11256 {
11257 #ifdef HAVE_GHOSTSCRIPT
11258 { SYMBOL_INDEX (Qpostscript), gs_image_p, gs_load, image_clear_image },
11259 #endif
11260 #ifdef HAVE_IMAGEMAGICK
11261 { SYMBOL_INDEX (Qimagemagick), imagemagick_image_p, imagemagick_load,
11262 imagemagick_clear_image },
11263 #endif
11264 #ifdef HAVE_RSVG
11265 { SYMBOL_INDEX (Qsvg), svg_image_p, svg_load, image_clear_image,
11266 IMAGE_TYPE_INIT (init_svg_functions) },
11267 #endif
11268 #if defined HAVE_PNG
11269 { SYMBOL_INDEX (Qpng), png_image_p, png_load, image_clear_image,
11270 IMAGE_TYPE_INIT (init_png_functions) },
11271 #endif
11272 #if defined HAVE_GIF
11273 { SYMBOL_INDEX (Qgif), gif_image_p, gif_load, gif_clear_image,
11274 IMAGE_TYPE_INIT (init_gif_functions) },
11275 #endif
11276 #if defined HAVE_TIFF
11277 { SYMBOL_INDEX (Qtiff), tiff_image_p, tiff_load, image_clear_image,
11278 IMAGE_TYPE_INIT (init_tiff_functions) },
11279 #endif
11280 #if defined HAVE_JPEG
11281 { SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
11282 IMAGE_TYPE_INIT (init_jpeg_functions) },
11283 #endif
11284 #if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU || defined HAVE_PGTK
11285 { SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
11286 IMAGE_TYPE_INIT (init_xpm_functions) },
11287 #endif
11288 #if defined HAVE_WEBP
11289 { SYMBOL_INDEX (Qwebp), webp_image_p, webp_load, image_clear_image,
11290 IMAGE_TYPE_INIT (init_webp_functions) },
11291 #endif
11292 { SYMBOL_INDEX (Qxbm), xbm_image_p, xbm_load, image_clear_image },
11293 { SYMBOL_INDEX (Qpbm), pbm_image_p, pbm_load, image_clear_image },
11294 };
11295
11296 #if HAVE_NATIVE_IMAGE_API
11297 struct image_type native_image_type =
11298 { SYMBOL_INDEX (Qnative_image), native_image_p, native_image_load,
11299 image_clear_image };
11300 #endif
11301
11302 /* Look up image type TYPE, and return a pointer to its image_type
11303 structure. Return 0 if TYPE is not a known image type. */
11304
11305 static struct image_type const *
lookup_image_type(Lisp_Object type)11306 lookup_image_type (Lisp_Object type)
11307 {
11308 #if HAVE_NATIVE_IMAGE_API
11309 if (image_can_use_native_api (type))
11310 return &native_image_type;
11311 #endif
11312
11313 for (int i = 0; i < ARRAYELTS (image_types); i++)
11314 {
11315 struct image_type const *r = &image_types[i];
11316 if (EQ (type, builtin_lisp_symbol (r->type)))
11317 return initialize_image_type (r) ? r : NULL;
11318 }
11319 return NULL;
11320 }
11321
11322
11323 void
syms_of_image(void)11324 syms_of_image (void)
11325 {
11326 /* Must be defined now because we're going to update it below, while
11327 defining the supported image types. */
11328 DEFVAR_LISP ("image-types", Vimage_types,
11329 doc: /* List of potentially supported image types.
11330 Each element of the list is a symbol for an image type, like `jpeg' or `png'.
11331 To check whether it is really supported, use `image-type-available-p'. */);
11332 Vimage_types = Qnil;
11333
11334 DEFVAR_LISP ("max-image-size", Vmax_image_size,
11335 doc: /* Maximum size of images.
11336 Emacs will not load an image into memory if its pixel width or
11337 pixel height exceeds this limit.
11338
11339 If the value is an integer, it directly specifies the maximum
11340 image height and width, measured in pixels. If it is a floating
11341 point number, it specifies the maximum image height and width
11342 as a ratio to the frame height and width. If the value is
11343 non-numeric, there is no explicit limit on the size of images. */);
11344 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
11345
11346 /* Other symbols. */
11347 DEFSYM (Qcount, "count");
11348 DEFSYM (Qextension_data, "extension-data");
11349 DEFSYM (Qdelay, "delay");
11350
11351 /* Keywords. */
11352 DEFSYM (QCascent, ":ascent");
11353 DEFSYM (QCmargin, ":margin");
11354 DEFSYM (QCrelief, ":relief");
11355 DEFSYM (QCconversion, ":conversion");
11356 DEFSYM (QCcolor_symbols, ":color-symbols");
11357 DEFSYM (QCheuristic_mask, ":heuristic-mask");
11358 DEFSYM (QCindex, ":index");
11359 DEFSYM (QCcrop, ":crop");
11360 DEFSYM (QCrotation, ":rotation");
11361 DEFSYM (QCmatrix, ":matrix");
11362 DEFSYM (QCscale, ":scale");
11363 DEFSYM (QCtransform_smoothing, ":transform-smoothing");
11364 DEFSYM (QCcolor_adjustment, ":color-adjustment");
11365 DEFSYM (QCmask, ":mask");
11366
11367 /* Other symbols. */
11368 DEFSYM (Qlaplace, "laplace");
11369 DEFSYM (Qemboss, "emboss");
11370 DEFSYM (Qedge_detection, "edge-detection");
11371 DEFSYM (Qheuristic, "heuristic");
11372
11373 DEFSYM (Qpostscript, "postscript");
11374 DEFSYM (QCmax_width, ":max-width");
11375 DEFSYM (QCmax_height, ":max-height");
11376
11377 DEFSYM (Qem, "em");
11378
11379 #ifdef HAVE_NATIVE_TRANSFORMS
11380 DEFSYM (Qscale, "scale");
11381 DEFSYM (Qrotate, "rotate");
11382 DEFSYM (Qrotate90, "rotate90");
11383 DEFSYM (Qcrop, "crop");
11384 #endif
11385
11386 #ifdef HAVE_GHOSTSCRIPT
11387 add_image_type (Qpostscript);
11388 DEFSYM (QCloader, ":loader");
11389 DEFSYM (QCpt_width, ":pt-width");
11390 DEFSYM (QCpt_height, ":pt-height");
11391 #endif /* HAVE_GHOSTSCRIPT */
11392
11393 #ifdef HAVE_NTGUI
11394 /* Versions of libpng, libgif, and libjpeg that we were compiled with,
11395 or -1 if no PNG/GIF support was compiled in. This is tested by
11396 w32-win.el to correctly set up the alist used to search for the
11397 respective image libraries. */
11398 DEFSYM (Qlibpng_version, "libpng-version");
11399 Fset (Qlibpng_version,
11400 #if HAVE_PNG
11401 make_fixnum (PNG_LIBPNG_VER)
11402 #else
11403 make_fixnum (-1)
11404 #endif
11405 );
11406 DEFSYM (Qlibgif_version, "libgif-version");
11407 Fset (Qlibgif_version,
11408 #ifdef HAVE_GIF
11409 make_fixnum (GIFLIB_MAJOR * 10000
11410 + GIFLIB_MINOR * 100
11411 + GIFLIB_RELEASE)
11412 #else
11413 make_fixnum (-1)
11414 #endif
11415 );
11416 DEFSYM (Qlibjpeg_version, "libjpeg-version");
11417 Fset (Qlibjpeg_version,
11418 #if HAVE_JPEG
11419 make_fixnum (JPEG_LIB_VERSION)
11420 #else
11421 make_fixnum (-1)
11422 #endif
11423 );
11424 #endif
11425
11426 DEFSYM (Qpbm, "pbm");
11427 add_image_type (Qpbm);
11428
11429 DEFSYM (Qxbm, "xbm");
11430 add_image_type (Qxbm);
11431
11432 #if defined (HAVE_XPM) || defined (HAVE_NS) \
11433 || defined (HAVE_HAIKU) || defined (HAVE_PGTK)
11434 DEFSYM (Qxpm, "xpm");
11435 add_image_type (Qxpm);
11436 #endif
11437
11438 #if defined (HAVE_JPEG) || defined (HAVE_NATIVE_IMAGE_API)
11439 DEFSYM (Qjpeg, "jpeg");
11440 add_image_type (Qjpeg);
11441 #endif
11442
11443 #if defined (HAVE_TIFF) || defined (HAVE_NATIVE_IMAGE_API)
11444 DEFSYM (Qtiff, "tiff");
11445 add_image_type (Qtiff);
11446 #endif
11447
11448 #if defined (HAVE_GIF) || defined (HAVE_NATIVE_IMAGE_API)
11449 DEFSYM (Qgif, "gif");
11450 add_image_type (Qgif);
11451 #endif
11452
11453 #if defined (HAVE_PNG) || defined (HAVE_NATIVE_IMAGE_API)
11454 DEFSYM (Qpng, "png");
11455 add_image_type (Qpng);
11456 #endif
11457
11458 #if defined (HAVE_WEBP)
11459 DEFSYM (Qwebp, "webp");
11460 add_image_type (Qwebp);
11461 #endif
11462
11463 #if defined (HAVE_IMAGEMAGICK)
11464 DEFSYM (Qimagemagick, "imagemagick");
11465 add_image_type (Qimagemagick);
11466 #endif
11467
11468 #if defined (HAVE_RSVG)
11469 DEFSYM (Qsvg, "svg");
11470 DEFSYM (QCbase_uri, ":base-uri");
11471 DEFSYM (QCcss, ":css");
11472 add_image_type (Qsvg);
11473 #ifdef HAVE_NTGUI
11474 /* Other libraries used directly by svg code. */
11475 DEFSYM (Qgdk_pixbuf, "gdk-pixbuf");
11476 DEFSYM (Qglib, "glib");
11477 # if LIBRSVG_CHECK_VERSION (2, 32, 0)
11478 DEFSYM (Qgio, "gio");
11479 # endif
11480 DEFSYM (Qgobject, "gobject");
11481 #endif /* HAVE_NTGUI */
11482 #endif /* HAVE_RSVG */
11483
11484 #ifdef HAVE_NS
11485 DEFSYM (Qheic, "heic");
11486 add_image_type (Qheic);
11487 #endif
11488
11489 #if HAVE_NATIVE_IMAGE_API
11490 DEFSYM (Qnative_image, "native-image");
11491 # ifdef HAVE_NTGUI
11492 DEFSYM (Qgdiplus, "gdiplus");
11493 DEFSYM (Qshlwapi, "shlwapi");
11494 # endif
11495 #endif
11496
11497 defsubr (&Sinit_image_library);
11498 #ifdef HAVE_IMAGEMAGICK
11499 defsubr (&Simagemagick_types);
11500 #endif
11501 defsubr (&Sclear_image_cache);
11502 defsubr (&Simage_flush);
11503 defsubr (&Simage_size);
11504 defsubr (&Simage_mask_p);
11505 defsubr (&Simage_metadata);
11506 defsubr (&Simage_cache_size);
11507
11508 #ifdef GLYPH_DEBUG
11509 defsubr (&Simagep);
11510 defsubr (&Slookup_image);
11511 #endif
11512
11513 defsubr (&Simage_transforms_p);
11514
11515 DEFVAR_BOOL ("cross-disabled-images", cross_disabled_images,
11516 doc: /* Non-nil means always draw a cross over disabled images.
11517 Disabled images are those having a `:conversion disabled' property.
11518 A cross is always drawn on black & white displays. */);
11519 cross_disabled_images = 0;
11520
11521 DEFVAR_LISP ("x-bitmap-file-path", Vx_bitmap_file_path,
11522 doc: /* List of directories to search for window system bitmap files. */);
11523 Vx_bitmap_file_path = decode_env_path (0, PATH_BITMAPS, 0);
11524
11525 DEFVAR_LISP ("image-cache-eviction-delay", Vimage_cache_eviction_delay,
11526 doc: /* Maximum time after which images are removed from the cache.
11527 When an image has not been displayed this many seconds, Emacs
11528 automatically removes it from the image cache. If the cache contains
11529 a large number of images, the actual eviction time may be shorter.
11530 The value can also be nil, meaning the cache is never cleared.
11531
11532 The function `clear-image-cache' disregards this variable. */);
11533 Vimage_cache_eviction_delay = make_fixnum (300);
11534 #ifdef HAVE_IMAGEMAGICK
11535 DEFVAR_INT ("imagemagick-render-type", imagemagick_render_type,
11536 doc: /* Integer indicating which ImageMagick rendering method to use.
11537 The options are:
11538 0 -- the default method (pixel pushing)
11539 1 -- a newer method ("MagickExportImagePixels") that may perform
11540 better (speed etc) in some cases, but has not been as thoroughly
11541 tested with Emacs as the default method. This method requires
11542 ImageMagick version 6.4.6 (approximately) or later.
11543 */);
11544 /* MagickExportImagePixels is in 6.4.6-9, but not 6.4.4-10. */
11545 imagemagick_render_type = 0;
11546 #endif
11547
11548 }
11549