OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / win / gem / xpm2img.c
1 /* NetHack 3.6  xpm2img.c       $NHDT-Date: 1432512809 2015/05/25 00:13:29 $  $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */
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
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 =
50         (unsigned int **) malloc((long) height * sizeof(unsigned int *));
51     for (i = 0; i < height; i++)
52         Bild_daten[i] =
53             (unsigned int *) malloc((long) width * sizeof(unsigned int));
54     for (row = 0; row < height; row++) {
55         char *xb = xpmgetline();
56         int plane_offset;
57         if (xb == 0) {
58             printf("Error to few lines in xpm-file %s, aborting.\n", argv[1]);
59             exit(EXIT_FAILURE);
60         }
61         for (col = 0; col < width; col++) {
62             int color = xb[col];
63             if (!ttable[color].flag)
64                 fprintf(stderr, "Bad image data\n");
65             Bild_daten[row][col] = ttable[color].slot;
66         }
67     }
68     if (num_colors > 256) {
69         fprintf(stderr, "ERROR: zuviele Farben\n");
70         exit(EXIT_FAILURE);
71     } else if (num_colors > 16) {
72         farben = 256;
73         planes = 8;
74     } else if (num_colors > 2) {
75         farben = 16;
76         planes = 4;
77     } else {
78         farben = 2;
79         planes = 1;
80     }
81     bitmap_to_file(XIMG, width, height, 372, 372, planes, farben, argv[2],
82                    get_color, get_pixel);
83     exit(EXIT_SUCCESS);
84     /*NOTREACHED*/
85     return 0;
86 }
87 void
88 get_color(unsigned int colind, struct RGB *rgb)
89 {
90     rgb->r = (1000L * (long) ColorMap[colind].r) / 0xFF;
91     rgb->g = (1000L * (long) ColorMap[colind].g) / 0xFF;
92     rgb->b = (1000L * (long) ColorMap[colind].b) / 0xFF;
93 }
94 void
95 get_pixel(int x, int y, unsigned int *colind)
96 {
97     *colind = Bild_daten[y][x];
98 }
99 FILE *xpmfh = 0;
100 char initbuf[200];
101 char *xpmbuf = initbuf;
102 /* version 1.  Reads the raw xpm file, NOT the compiled version.  This is
103  * not a particularly good idea but I don't have time to do the right thing
104  * at this point, even if I was absolutely sure what that was. */
105 fopen_xpm_file(const char *fn, const char *mode)
106 {
107     int temp;
108     char *xb;
109     if (strcmp(mode, "r"))
110         return FALSE; /* no choice now */
111     if (xpmfh)
112         return FALSE; /* one file at a time */
113     xpmfh = fopen(fn, mode);
114     if (!xpmfh)
115         return FALSE; /* I'm hard to please */
116                       /* read the header */
117     xb = xpmgetline();
118     if (xb == 0)
119         return FALSE;
120     if (4 != sscanf(xb, "%d %d %d %d", &width, &height, &num_colors, &temp))
121         return FALSE; /* bad header */
122                       /* replace the original buffer with one big enough for
123                        * the real data
124                        */
125     /* XXX */
126     xpmbuf = malloc(width * 2);
127     if (!xpmbuf) {
128         fprintf(stderr, "ERROR: Can't allocate line buffer\n");
129         exit(1);
130     }
131     if (temp != 1)
132         return FALSE; /* limitation of this code */
133     {
134         /* read the colormap and translation table */
135         int ccount = -1;
136         ColorMap =
137             (struct RGB *) malloc((long) num_colors * sizeof(struct RGB));
138         while (ccount++ < (num_colors - 1)) {
139             char index;
140             int r, g, b;
141             xb = xpmgetline();
142             if (xb == 0)
143                 return FALSE;
144             if (4 != sscanf(xb, "%c c #%2x%2x%2x", &index, &r, &g, &b)) {
145                 fprintf(stderr, "Bad color entry: %s\n", xb);
146                 return FALSE;
147             }
148             ttable[index].flag = 1; /* this color is valid */
149             ttable[index].col.r = r;
150             ttable[index].col.g = g;
151             ttable[index].col.b = b;
152             ttable[index].slot = ccount;
153             ColorMap[ccount].r = r;
154             ColorMap[ccount].g = g;
155             ColorMap[ccount].b = b;
156         }
157     }
158     return TRUE;
159 }
160 /* This deserves better.  Don't read it too closely - you'll get ill. */
161 #define bufsz 2048
162 char buf[bufsz];
163 char *
164 xpmgetline()
165 {
166     char *bp;
167     do {
168         if (fgets(buf, bufsz, xpmfh) == 0)
169             return 0;
170     } while (buf[0] != '"');
171     /* strip off the trailing <",> if any */
172     for (bp = buf; *bp; bp++)
173         ;
174     bp--;
175     while (isspace(*bp))
176         bp--;
177     if (*bp == ',')
178         bp--;
179     if (*bp == '"')
180         bp--;
181     bp++;
182     *bp = '\0';
183     return &buf[1];
184 }