1 /*
2 * FIG : Facility for Interactive Generation of figures
3 * Copyright (c) 1985-1988 by Supoj Sutanthavibul
4 * Parts Copyright (c) 1989-2015 by Brian V. Smith
5 * Parts Copyright (c) 1991 by Paul King
6 * Parts Copyright (c) 2016-2020 by Thomas Loimer
7 *
8 * Any party obtaining a copy of these files is granted, free of charge, a
9 * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
10 * nonexclusive right and license to deal in this software and documentation
11 * files (the "Software"), including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense and/or sell copies of
13 * the Software, and to permit persons who receive copies from any such
14 * party to do so, with the only requirement being that the above copyright
15 * and this permission notice remain intact.
16 *
17 */
18
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h" /* restrict */
22 #endif
23
24 #include <stdlib.h>
25
26 #include <X11/X.h> /* None */
27 #include <X11/Xlib.h> /* XColor, XParseColor */
28 #include <X11/xpm.h>
29
30 #include "resources.h"
31 #include "object.h"
32 #include "f_picobj.h"
33 #include "f_util.h"
34 #include "w_color.h"
35 #include "w_msgpanel.h"
36 #include "w_setup.h"
37
38 /* attempt to read a XPM (color pixmap) file */
39 /* the filename is passed since XpmReadFileToXpmImage needs a name
40 instead of a FILE pointer. This is fine because it handles compressed files */
41
42 /* return codes: PicSuccess (1) : success
43 FileInvalid (-2) : invalid file
44 */
45
46 int
read_xpm(F_pic * pic,struct xfig_stream * restrict pic_stream)47 read_xpm(F_pic *pic, struct xfig_stream *restrict pic_stream)
48 {
49 int status;
50 XpmImage image;
51 unsigned int i;
52 char *c;
53 XColor exact_def;
54
55 /* make scale factor smaller for metric */
56 float scale = (appres.INCHES ?
57 (float)PIX_PER_INCH :
58 2.54*PIX_PER_CM)/(float)DISPLAY_PIX_PER_INCH;
59
60 if (uncompressed_content(pic_stream))
61 return FileInvalid;
62
63 status = XpmReadFileToXpmImage(pic_stream->content, &image, NULL);
64 /* if out of colors, try switching colormaps and reading again */
65 if (status == XpmColorFailed) {
66 if (!switch_colormap())
67 return PicSuccess;
68 status = XpmReadFileToXpmImage(pic_stream->content, &image,
69 NULL);
70 }
71 if (status == XpmSuccess) {
72 /* now look up the colors in the image and put them
73 in the pic colormap */
74 for (i = 0; i < image.ncolors; ++i) {
75 c = (image.colorTable + i)->c_color;
76 if (c == NULL || *c == '\0') {
77 /* use white for null color */
78 c = "white";
79 file_msg("white used for *NULL color");
80 }
81 if (XParseColor(tool_d, tool_cm, c, &exact_def) == 0) {
82 file_msg("Error parsing color %s",c);
83 exact_def.red = exact_def.green =
84 exact_def.blue = 65535;
85 }
86 pic->pic_cache->cmap[i].red = exact_def.red >> 8;
87 pic->pic_cache->cmap[i].green = exact_def.green >> 8;
88 pic->pic_cache->cmap[i].blue = exact_def.blue >> 8;
89 }
90 pic->pic_cache->subtype = T_PIC_XPM;
91 pic->pic_cache->numcols = image.ncolors;
92 pic->pixmap = None;
93 pic->pic_cache->bitmap = malloc(image.width * image.height *
94 sizeof(unsigned char));
95 if (pic->pic_cache->bitmap == NULL) {
96 file_msg("cannot allocate space for XPM image");
97 return PicSuccess;
98 }
99 for (i=0; i<image.width*image.height; i++)
100 pic->pic_cache->bitmap[i] =(unsigned char)image.data[i];
101 pic->hw_ratio = (float)image.height / image.width;
102 pic->pic_cache->bit_size.x = image.width;
103 pic->pic_cache->bit_size.y = image.height;
104 pic->pic_cache->size_x = image.width * scale;
105 pic->pic_cache->size_y = image.height * scale;
106 XpmFreeXpmImage(&image); /* get rid of the image */
107 /* if monochrome display map bitmap */
108 if (tool_cells <= 2 || appres.monochrome)
109 map_to_mono(pic);
110
111 return PicSuccess;
112 }
113 return FileInvalid;
114 }
115