Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /* 2013apr13, added mono + grey Jose Da Silva */
3 : /*
4 : * Redistribution and use in source and binary forms, with or without
5 : * modification, are permitted provided that the following conditions are met:
6 :
7 : * Redistributions of source code must retain the above copyright notice, this
8 : * list of conditions and the following disclaimer.
9 :
10 : * Redistributions in binary form must reproduce the above copyright notice,
11 : * this list of conditions and the following disclaimer in the documentation
12 : * and/or other materials provided with the distribution.
13 :
14 : * The name of the author may not be used to endorse or promote products
15 : * derived from this software without specific prior written permission.
16 :
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : */
28 : #include "gimage.h"
29 : #include "string.h"
30 :
31 0 : static char *pixname(int i, int ncol) {
32 : static char one[2], two[3];
33 0 : char *usable = "!#$%&'()*+,-./0123456789;:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~ ";
34 : static int len=0;
35 :
36 0 : if ( len==0 ) len = strlen(usable);
37 0 : if ( ncol<len ) {
38 0 : one[0]=usable[i];
39 0 : return( one );
40 : } else {
41 0 : two[0] = usable[i/len];
42 0 : two[1] = usable[i%len];
43 0 : return( two );
44 : }
45 : }
46 :
47 0 : int GImageWriteXpm(GImage *gi, char *filename) {
48 : /* Export an *.xpm image. Return 0 if all done okay */
49 0 : struct _GImage *base = gi->list_len==0?gi->u.image:gi->u.images[0];
50 : FILE *file;
51 : char stem[256];
52 : char *pt,*color_type; uint8 *scanline;
53 : int i,j;
54 :
55 : /* This routine only exports mono or color-indexed type images */
56 0 : if ( base->image_type==it_mono )
57 0 : color_type = "m";
58 0 : else if ( base->image_type==it_index ) {
59 0 : color_type = "c";
60 0 : if ( base->clut->is_grey ) {
61 0 : color_type = "g";
62 0 : if ( base->clut->clut_len<=4 )
63 0 : color_type = "g4";
64 : }
65 : } else {
66 0 : fprintf(stderr,"Image must be mono or color-indexed.\n");
67 0 : return( -1 );
68 : }
69 :
70 : /* get filename stem (255chars max) */
71 0 : if ( (pt=strrchr(filename,'/'))!=NULL )
72 0 : ++pt;
73 : else
74 0 : pt=filename;
75 0 : strncpy(stem,pt,sizeof(stem)); stem[255]='\0';
76 0 : if ( (pt=strrchr(stem,'.'))!=NULL && pt!=stem )
77 0 : *pt = '\0';
78 :
79 0 : if ( (file=fopen(filename,"w"))==NULL ) {
80 0 : fprintf(stderr,"Can't open \"%s\"\n", filename);
81 0 : return( -1 );
82 : }
83 :
84 0 : fprintf(file,"/* XPM */\n" );
85 0 : fprintf(file,"static char *%s[] = {\n",stem);
86 0 : fprintf(file,"/* width height ncolors chars_per_pixel */\n");
87 0 : if ( base->image_type==it_mono )
88 0 : fprintf(file,"\"%d %d 2 1\"\n", (int) base->width, (int) base->height );
89 : else
90 0 : fprintf(file,"\"%d %d %d %d\"\n", (int) base->width, (int) base->height, base->clut->clut_len,
91 0 : base->clut->clut_len>95?2:1 );
92 0 : fprintf(file,"/* colors */\n");
93 0 : if ( base->image_type==it_mono ) {
94 0 : fprintf(file,"\"%s m #%06x\"\n", pixname(0,2),0);
95 0 : fprintf(file,"\"%s m #%06x\"\n", pixname(1,2),0xffffff);
96 : } else {
97 0 : for ( i=0; i<base->clut->clut_len; ++i )
98 0 : fprintf(file,"\"%s %s #%06x\"\n", pixname(i,base->clut->clut_len),color_type,
99 0 : (int) base->clut->clut[i]);
100 : }
101 0 : fprintf(file,"/* image */\n");
102 0 : for ( i=0; i<base->height; ++i ) {
103 0 : fprintf(file,"\"" );
104 0 : scanline = base->data + i*base->bytes_per_line;
105 0 : if ( base->image_type==it_mono )
106 0 : for ( j=0; j<base->width; ++j )
107 0 : fprintf(file,"%s", pixname((scanline[j>>3]>>(7-(j&7)))&1,2));
108 : else
109 0 : for ( j=0; j<base->width; ++j )
110 0 : fprintf(file,"%s", pixname(*scanline++,base->clut->clut_len));
111 0 : fprintf(file,"\"%s\n", i==base->height-1?"":"," );
112 : }
113 0 : fprintf(file,"};\n" );
114 0 : fflush(file);
115 :
116 0 : i=ferror(file);
117 0 : fclose(file);
118 0 : return( i );
119 : }
|