Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /* 2013feb15, fileread and mem error checks, plus test for short, 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 :
30 0 : static int ConvertXbmByte(int pixels) {
31 0 : int i,val=0;
32 :
33 0 : for ( i=0; i<8; ++i )
34 0 : if ( pixels&(1<<i) )
35 0 : val |= (0x80>>i);
36 0 : return( val^0xff ); /* I default black the other way */
37 : }
38 :
39 0 : GImage *GImageReadXbm(char * filename) {
40 : /* Import an *.xbm image, else return NULL if error */
41 : FILE *file;
42 : int width, height;
43 0 : GImage *gi=NULL;
44 : struct _GImage *base;
45 0 : int ch,i,j,l = 0;
46 : long pixels;
47 : uint8 *scanline;
48 :
49 0 : if ( (file=fopen(filename,"r"))==NULL ) {
50 0 : fprintf(stderr,"Can't open \"%s\"\n", filename);
51 0 : return( NULL );
52 : }
53 :
54 : /* Get width and height */
55 0 : if ( fscanf(file,"#define %*s %d\n",&width)!=1 || \
56 0 : fscanf(file,"#define %*s %d\n",&height)!=1 )
57 : goto errorGImageReadXbm;
58 :
59 : /* Check for, and skip past hotspot */
60 0 : if ( (ch=getc(file))<0 )
61 0 : goto errorGImageReadXbm;
62 0 : if ( ch=='#' ) {
63 0 : if ( fscanf(file,"define %*s %*d\n")<0 || /* x hotspot */ \
64 0 : fscanf(file,"#define %*s %*d\n")<0 ) /* y hotspot */
65 : goto errorGImageReadXbm;
66 : } else
67 0 : if ( ungetc(ch,file)<0 )
68 0 : goto errorGImageReadXbm;
69 :
70 : /* Data starts after finding "static unsigned " or "static " */
71 0 : if ( fscanf(file,"static ")<0 || (ch=getc(file))<0 )
72 : goto errorGImageReadXbm;
73 0 : if ( ch=='u' ) {
74 0 : if ( fscanf(file,"nsigned ")<0 || (ch=getc(file))<0 )
75 : goto errorGImageReadXbm;
76 : /* TODO: Do we want to track signed/unsigned data? */
77 : }
78 :
79 : /* Data may be in char,short or long formats */
80 0 : if ( ch=='c' ) {
81 0 : if ( fscanf(file,"har %*s = {")<0 )
82 0 : goto errorGImageReadXbm;
83 0 : l=8;
84 0 : } else if ( ch=='s' ) {
85 0 : if ( fscanf(file,"hort %*s = {")<0 )
86 0 : goto errorGImageReadXbm;
87 0 : l=16;
88 0 : } else if ( ch=='l' ) {
89 0 : if ( fscanf(file,"ong %*s = {")<0 )
90 0 : goto errorGImageReadXbm;
91 0 : l=32;
92 : }
93 :
94 : /* Create memory to hold image, exit with NULL if not enough memory */
95 0 : if ( (gi=GImageCreate(it_mono,width,height))==NULL )
96 0 : goto errorGImageReadXbmMem;
97 :
98 : /* Convert *.xbm graphic into one that FF can use */
99 0 : base = gi->u.image;
100 0 : for ( i=0; i<height; ++i ) {
101 0 : scanline = base->data + i*base->bytes_per_line;
102 0 : for ( j=0; j<base->bytes_per_line; ++j ) {
103 0 : if ( fscanf(file," 0x%x",(unsigned *) &pixels)!=1 )
104 0 : goto errorGImageReadXbm;
105 0 : *scanline++ = ConvertXbmByte(pixels);
106 0 : if ( l>8 && j+1<base->bytes_per_line ) {
107 0 : *scanline++ = ConvertXbmByte(pixels>>8);
108 0 : ++j;
109 : }
110 0 : if ( l>16 && j+1<base->bytes_per_line ) {
111 0 : *scanline++ = ConvertXbmByte(pixels>>16);
112 0 : ++j;
113 0 : if ( j+1<base->bytes_per_line ) {
114 0 : *scanline++ = ConvertXbmByte(pixels>>24);
115 0 : ++j;
116 : }
117 : }
118 0 : fscanf(file,",");
119 : }
120 : }
121 0 : fclose(file);
122 0 : return( gi );
123 :
124 : errorGImageReadXbm:
125 0 : fprintf(stderr,"Bad input file \"%s\"\n",filename );
126 : errorGImageReadXbmMem:
127 0 : GImageDestroy(gi);
128 0 : fclose(file);
129 0 : return( NULL );
130 : }
|