28 #ifdef SIMAGE_XWD_SUPPORT
44 #define XWD_HEADER_SIZE 100
45 #define XWD_COLOR_SIZE 12
48 #define XWD_HOFF_HEADER_SIZE 0
49 #define XWD_HOFF_FILE_VERSION 4
50 #define XWD_HOFF_FORMAT 8
51 #define XWD_HOFF_DEPTH 12
52 #define XWD_HOFF_WIDTH 16
53 #define XWD_HOFF_HEIGHT 20
54 #define XWD_HOFF_XOFFSET 24
55 #define XWD_HOFF_BYTEORDER 28
56 #define XWD_HOFF_BITMAP_UNIT 32
57 #define XWD_HOFF_BITMAP_BITORDER 36
58 #define XWD_HOFF_BITMAP_PAD 40
59 #define XWD_HOFF_BITS_PER_PIXEL 44
60 #define XWD_HOFF_BYTES_PER_LINE 48
61 #define XWD_HOFF_VISUAL_CLASS 52
62 #define XWD_HOFF_RED_MASK 56
63 #define XWD_HOFF_GREEN_MASK 60
64 #define XWD_HOFF_BLUE_MASK 64
65 #define XWD_HOFF_BITS_PER_RGB 68
66 #define XWD_HOFF_COLORMAP_ENTRIES 72
67 #define XWD_HOFF_NUM_COLORS 76
68 #define XWD_HOFF_WINDOW_WIDTH 80
69 #define XWD_HOFF_WINDOW_HEIGHT 84
70 #define XWD_HOFF_WINDOW_X 88
71 #define XWD_HOFF_WINDOW_Y 92
72 #define XWD_HOFF_WINDOW_BORDERWIDTH 96
75 #define XWD_COFF_PIXEL 0
76 #define XWD_COFF_RED 4
77 #define XWD_COFF_GREEN 6
78 #define XWD_COFF_BLUE 8
79 #define XWD_COFF_FLAGS 10
84 #define XWD_NO_ERROR 0
85 #define XWD_FILE_STAT_ERROR 1
86 #define XWD_FILE_OPEN_ERROR 2
87 #define XWD_FILE_READ_ERROR 3
88 #define XWD_MALLOC_ERROR 4
89 #define XWD_NO_SUPPORT_ERROR 5
91 static int xwderror = XWD_NO_ERROR;
101 #define DirectColor 5
112 #define INT32BE(ptr) ((ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3])
113 #define INT16BE(ptr) ((ptr[0] << 8) | ptr[1])
115 unsigned long getuint32be(
const unsigned char * data ) {
return INT32BE(data); }
116 unsigned long getuint16be(
const unsigned char * data ) {
return INT16BE(data); }
118 unsigned long swap32(
unsigned long value ) {
119 value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8);
120 return ((value & 0xffff0000) >> 16) | ((value & 0x0000ffff) << 16);
130 switch ( xwderror ) {
131 case XWD_FILE_STAT_ERROR:
132 strncpy( buffer,
"XWD loader: file stat error", bufferlen );
134 case XWD_FILE_OPEN_ERROR:
135 strncpy( buffer,
"XWD loader: file open error", bufferlen );
137 case XWD_FILE_READ_ERROR:
138 strncpy( buffer,
"XWD loader: file read error", bufferlen );
140 case XWD_MALLOC_ERROR:
141 strncpy( buffer,
"XWD loader: malloc error", bufferlen );
143 case XWD_NO_SUPPORT_ERROR:
144 strncpy( buffer,
"XWD loader: unsupported operation", bufferlen );
154 const char * filename,
155 const unsigned char * header,
160 if ( headerlen < 12 )
return 0;
161 if ( getuint32be( header + XWD_HOFF_HEADER_SIZE ) < XWD_HEADER_SIZE ) {
169 if ( getuint32be( header + XWD_HOFF_FILE_VERSION ) != 7 ) {
177 if ( getuint32be( header + XWD_HOFF_FORMAT ) != ZPixmap ) {
192 const char * filename,
197 unsigned char * buf, * image, * ptr, * line, * imageptr;
198 unsigned long * palette;
199 unsigned int w, h, c, x, y, num_colors;
200 unsigned int bits_per_pixel, bytes_per_line;
201 unsigned int pixel, bits, got_bits, value;
204 struct stat statdata;
206 if ( stat( filename, &statdata ) == -1 ) {
207 xwderror = XWD_FILE_STAT_ERROR;
211 if ( (buf = (
unsigned char *) malloc( statdata.st_size )) == NULL ) {
212 xwderror = XWD_MALLOC_ERROR;
216 xwdfile = fopen( filename,
"rb" );
217 if ( (xwdfile = fopen( filename,
"rb" )) == NULL ) {
219 xwderror = XWD_FILE_OPEN_ERROR;
223 if ( fread( buf, 1, statdata.st_size, xwdfile ) != statdata.st_size ) {
226 xwderror = XWD_FILE_READ_ERROR;
232 w = getuint32be( buf + XWD_HOFF_WIDTH );
233 h = getuint32be( buf + XWD_HOFF_HEIGHT );
235 if ( (image = (
unsigned char *) malloc( w * h * c )) == NULL ) {
237 xwderror = XWD_MALLOC_ERROR;
242 bytes_per_line = getuint32be( buf + XWD_HOFF_BYTES_PER_LINE );
243 bits_per_pixel = getuint32be( buf + XWD_HOFF_BITS_PER_PIXEL );
244 num_colors = getuint32be( buf + XWD_HOFF_NUM_COLORS );
246 swap = (getuint32be( buf + XWD_HOFF_BYTEORDER ) == LSBFirst ) ? 1 : 0;
287 ptr = buf + getuint32be( buf + XWD_HOFF_HEADER_SIZE ) + (num_colors * XWD_COLOR_SIZE);
289 for ( y = 0; y < h; y++ ) {
290 line = ptr + ((h-(y+1)) * bytes_per_line);
293 for ( x = 0; x < w; x++ ) {
294 while ( got_bits < bits_per_pixel ) {
295 bits = (bits << 8) | line[0];
299 if ( got_bits > bits_per_pixel ) {
300 got_bits -= bits_per_pixel;
301 value = bits >> got_bits;
302 bits = bits & ((1 << got_bits) - 1);
308 if ( palette != NULL )
309 pixel = palette[value];
310 else if ( swap != 0 )
311 pixel = swap32(value);
316 *imageptr++ = (pixel >> 16) & 0xff;
317 *imageptr++ = (pixel >> 8) & 0xff;
318 *imageptr++ = pixel & 0xff;
333 const char * filename,
334 const unsigned char * bytes,
339 xwderror = XWD_NO_SUPPORT_ERROR;
int simage_xwd_save(const char *filename, const unsigned char *bytes, int width, int height, int numcomponents)
int simage_xwd_identify(const char *filename, const unsigned char *header, int headerlen)
unsigned char * simage_xwd_load(const char *filename, int *width, int *height, int *numcomponents)
int simage_xwd_error(char *buffer, int bufferlen)