1 /*	SCCS Id: @(#)xpm2img.c	3.4	2002/03/17	*/
2 /*   Copyright (c) Christian Bressler 2002                 */
3 /*   NetHack may be freely redistributed.  See license for details. */
4 /* This is mainly a reworked tile2bmp.c + xpm2iff.c -- Marvin */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <ctype.h>
8 #include "bitmfile.h"
9 #define TRUE 1
10 #define FALSE 0
11 void get_color(unsigned int colind, struct RGB *rgb);
12 void get_pixel(int x, int y, unsigned int *colind);
13 char *xpmgetline();
14 unsigned int **Bild_daten;
15 /* translation table from xpm characters to RGB and colormap slots */
16 struct Ttable {
17 	char flag;
18 	struct RGB col;
19 	int slot;	/* output colortable index */
20 }ttable[256];
21 struct RGB *ColorMap;
22 int num_colors = 0;
23 int width=0, height=0;
24 int initflag;
25 FILE *fp;
26 int
main(argc,argv)27 main(argc, argv)
28 int argc;
29 char *argv[];
30 {
31 	int i;
32 	int row, col, planeno;
33 	int farben, planes;
34 	if (argc != 3) {
35 		fprintf(stderr, "usage: tile2img infile.xpm outfile.img\n");
36 		exit(EXIT_FAILURE);
37 	}
38 	initflag = 0;
39 	fp = fopen(argv[2],"wb");
40 	if (!fp) {
41 	    printf("Error creating IMG-file %s, aborting.\n",argv[2]);
42 	    exit(EXIT_FAILURE);
43 	}
44 	fclose(fp);
45 	if(fopen_xpm_file(argv[1],"r")!=TRUE){
46 	    printf("Error reading xpm-file %s, aborting.\n",argv[1]);
47 	    exit(EXIT_FAILURE);
48 	}
49 	Bild_daten=(unsigned int **)malloc((long)height*sizeof(unsigned int *));
50 	for(i=0;i<height;i++)
51 		Bild_daten[i]=(unsigned int *)malloc((long)width*sizeof(unsigned int));
52 	for(row = 0;row<height;row++){
53 		char *xb = xpmgetline();
54 		int plane_offset;
55 		if(xb==0){
56 			printf("Error to few lines in xpm-file %s, aborting.\n",argv[1]);
57 			exit(EXIT_FAILURE);
58 		}
59 		for(col = 0;col<width;col++){
60 			int color = xb[col];
61 			if(!ttable[color].flag)
62 				fprintf(stderr, "Bad image data\n");
63 			Bild_daten[row][col]= ttable[color].slot;
64 		}
65 	}
66 	if(num_colors>256){
67 		fprintf(stderr,"ERROR: zuviele Farben\n");
68 		exit(EXIT_FAILURE);
69 	}else if(num_colors>16){
70 		farben=256;
71 		planes=8;
72 	}else if(num_colors>2){
73 		farben=16;
74 		planes=4;
75 	}else{
76 		farben=2;
77 		planes=1;
78 	}
79 	bitmap_to_file(XIMG, width, height, 372, 372, planes, farben, argv[2], get_color, get_pixel );
80 	exit(EXIT_SUCCESS);
81 	/*NOTREACHED*/
82 	return 0;
83 }
get_color(unsigned int colind,struct RGB * rgb)84 void get_color(unsigned int colind, struct RGB *rgb){
85 	rgb->r=(1000L*(long)ColorMap[colind].r)/0xFF;
86 	rgb->g=(1000L*(long)ColorMap[colind].g)/0xFF;
87 	rgb->b=(1000L*(long)ColorMap[colind].b)/0xFF;
88 }
get_pixel(int x,int y,unsigned int * colind)89 void get_pixel(int x, int y, unsigned int *colind){
90 	*colind=Bild_daten[y][x];
91 }
92 FILE *xpmfh = 0;
93 char initbuf[200];
94 char *xpmbuf = initbuf;
95 /* version 1.  Reads the raw xpm file, NOT the compiled version.  This is
96  * not a particularly good idea but I don't have time to do the right thing
97  * at this point, even if I was absolutely sure what that was. */
fopen_xpm_file(const char * fn,const char * mode)98 fopen_xpm_file(const char *fn, const char *mode){
99 	int temp;
100 	char *xb;
101 	if(strcmp(mode, "r"))return FALSE;	/* no choice now */
102 	if(xpmfh)return FALSE;			/* one file at a time */
103 	xpmfh = fopen(fn, mode);
104 	if(!xpmfh)return FALSE;			/* I'm hard to please */
105 		/* read the header */
106 	xb = xpmgetline();
107 	if(xb == 0)return FALSE;
108 	if(4 != sscanf(xb,"%d %d %d %d",
109 		&width, &height,&num_colors, &temp))
110 			return FALSE;	/* bad header */
111 		/* replace the original buffer with one big enough for
112 		 * the real data
113 		 */
114 /* XXX */
115 	xpmbuf = malloc(width * 2);
116 	if(!xpmbuf){
117 		fprintf(stderr,"ERROR: Can't allocate line buffer\n");
118 		exit(1);
119 	}
120 	if(temp != 1)return FALSE;		/* limitation of this code */
121 	{
122 		/* read the colormap and translation table */
123 		int ccount = -1;
124 		ColorMap = (struct RGB *)malloc((long)num_colors*sizeof(struct RGB));
125 		while(ccount++ < (num_colors-1)){
126 			char index;
127 			int r, g, b;
128 			xb = xpmgetline();
129 			if(xb==0)return FALSE;
130 			if(4 != sscanf(xb,"%c c #%2x%2x%2x",&index,&r,&g,&b)){
131 			    fprintf(stderr,"Bad color entry: %s\n",xb);
132 			    return FALSE;
133 			}
134 			ttable[index].flag = 1;	/* this color is valid */
135 			ttable[index].col.r = r;
136 			ttable[index].col.g = g;
137 			ttable[index].col.b = b;
138 			ttable[index].slot = ccount;
139 			ColorMap[ccount].r=r;
140 			ColorMap[ccount].g=g;
141 			ColorMap[ccount].b=b;
142 		}
143 	}
144 	return TRUE;
145 }
146 /* This deserves better.  Don't read it too closely - you'll get ill. */
147 #define bufsz 2048
148 char buf[bufsz];
149 char *
xpmgetline()150 xpmgetline(){
151 	char *bp;
152 	do {
153 	    if(fgets(buf, bufsz, xpmfh) == 0)return 0;
154 	} while(buf[0] != '"');
155 		/* strip off the trailing <",> if any */
156 	for(bp = buf;*bp;bp++);
157 	bp--;
158 	while(isspace(*bp))bp--;
159 	if(*bp==',')bp--;
160 	if(*bp=='"')bp--;
161 	bp++;
162 	*bp = '\0';
163 	return &buf[1];
164 }
165