Imported Upstream version 2.3
[xfishtank.git] / ppmtofish / ppmtofish.c
1 #include <stdio.h>
2
3 #define MAXCOLORS 256
4 #define COLS_PER_LINE 7
5 #define NUMS_PER_LINE 16
6
7 extern unsigned char *ReadGifBitmap();
8
9 struct ebmhdr {
10 char magic[12];
11 unsigned int width, height;
12 int num_colors;
13 };
14 struct rgb_color {
15 unsigned int red, green, blue;
16 int pix_len;
17 };
18
19
20
21 /*
22 * dscan is a quick replacement for:
23 *
24 * fscanf (fp, "%d", &ip);
25 */
26 dscan(fp, ip)
27 FILE *fp;
28 int *ip;
29 {
30
31 register int v = 0;
32 register int n = 0;
33 int done = 0;
34 static int nerrors;
35
36 while (!done) {
37 register int i;
38 i = getc(fp);
39 if (i < 0) {
40 *ip = v;
41 fprintf(stderr, "dscanf: EOF");
42 if (nerrors++ > 2)
43 return (-1);
44 else if (nerrors++ > 4)
45 exit(-1);
46 return (n);
47 }
48 i &= 0xFF;
49 switch (i) {
50 case '0':
51 case '1':
52 case '2':
53 case '3':
54 case '4':
55 case '5':
56 case '6':
57 case '7':
58 case '8':
59 case '9':
60 v = i - '0' + (v * 10);
61 n++;
62 break;
63 case '\n':
64 case '\r':
65 case ' ':
66 case '\t':
67 if (n) {
68 *ip = v;
69 done = 1;
70 }
71 break;
72 default:
73 fprintf(stderr, "dscanf: non numeric character (0x%x) '%c'\n", i, i);
74 if (nerrors++ > 4)
75 exit(-1);
76 return (-1);
77
78 }
79 }
80 return (n);
81 }
82
83
84
85 unsigned char *
86 ReadEbmBitmap(fp, w, h, colrs)
87 FILE *fp;
88 int *w, *h;
89 struct rgb_color *colrs;
90 {
91 int i, temp, scale;
92 unsigned int bmap_size;
93 int *ptr[3];
94 int red, green, blue;
95 char line[1024];
96 unsigned char *bit_data;
97 unsigned char *bitp;
98
99 bit_data = NULL;
100 *w = 0;
101 *h = 0;
102
103 if ((fscanf(fp, "%12s %d %d %d\n", line, w, h, &scale) == 4) &&
104 (strcmp(line, "xstitch_data") == 0)) {
105 for (i = 0; i < 3; i++) {
106 fscanf(fp, "%s", line);
107 if (strcmp(line, "red") == 0) {
108 ptr[i] = &red;
109 } else if (strcmp(line, "green") == 0) {
110 ptr[i] = &green;
111 } else if (strcmp(line, "blue") == 0) {
112 ptr[i] = &blue;
113 } else {
114 fprintf(stderr, "File has improper format\n");
115 return ((unsigned char *) NULL);
116 }
117 }
118 fscanf(fp, "[^\n]\n");
119 for (i = 0; i < scale; i++) {
120 line[0] = '\0';
121 if (fscanf(fp, "%d %d %d%[^\n]\n", ptr[0], ptr[1], ptr[2], line) < 3) {
122 fprintf(stderr, "Bad color data #%d\n", i);
123 }
124 colrs[i].red = red;
125 colrs[i].green = green;
126 colrs[i].blue = blue;
127 }
128
129 bmap_size = (*w) * (*h);
130 bit_data = (unsigned char *) malloc(bmap_size);
131 if (bit_data == NULL) {
132 fprintf(stderr, "Cannot allocate space for bitmap\n");
133 }
134 bitp = bit_data;
135 for (i = 0; i < bmap_size; i++) {
136 if (dscan(fp, &temp) == -1)
137 break;
138 if (temp > (scale - 1))
139 temp = 0;
140 *bitp = (unsigned char) temp;
141 bitp++;
142 }
143 } else {
144 return ((unsigned char *) NULL);
145 }
146 return (bit_data);
147 }
148
149
150
151 int
152 swapint(in)
153 int in;
154 {
155 int out;
156
157 out = 0;
158 out = out | ((in >> 24) & 0xff);
159 out = out | ((in >> 8) & 0xff00);
160 out = out | ((in << 8) & 0xff0000);
161 out = out | ((in << 24) & 0xff000000);
162 return (out);
163 }
164
165
166
167 unsigned char *
168 ReadCompactEbmBitmap(fp, w, h, colrs)
169 FILE *fp;
170 int *w, *h;
171 struct rgb_color *colrs;
172 {
173 int i, scale;
174 unsigned int bmap_size;
175 char pix_file[1024];
176 unsigned char *bit_data;
177 unsigned char *bitp;
178 struct ebmhdr Hdr;
179 struct rgb_color color_data;
180 int doswap;
181
182 doswap = 0;
183 bit_data = NULL;
184 *w = 0;
185 *h = 0;
186
187 fread(&Hdr, sizeof(struct ebmhdr), 1, fp);
188 if (strcmp(Hdr.magic, "xstitch") == 0) {
189 /*
190 * a horrible hack to deal with different byte ordering on
191 * different machines. Is based on assumption of only 2
192 * possible byte orderings, and never more than 256 colors.
193 */
194 if (Hdr.num_colors > 256) {
195 doswap = 1;
196 Hdr.width = swapint(Hdr.width);
197 Hdr.height = swapint(Hdr.height);
198 Hdr.num_colors = swapint(Hdr.num_colors);
199 }
200 *w = Hdr.width;
201 *h = Hdr.height;
202 scale = Hdr.num_colors;
203 for (i = 0; i < Hdr.num_colors; i++) {
204 fread(&colrs[i], sizeof(struct rgb_color), 1, fp);
205 if (doswap) {
206 colrs[i].red = swapint(colrs[i].red);
207 colrs[i].green = swapint(colrs[i].green);
208 colrs[i].blue = swapint(colrs[i].blue);
209 colrs[i].pix_len = swapint(colrs[i].pix_len);
210 }
211 if (colrs[i].pix_len != 0) {
212 if (colrs[i].pix_len > 1023) {
213 fprintf(stderr, "bad pattern\n");
214 return ((unsigned char *) NULL);
215 }
216 fread(pix_file, sizeof(char), colrs[i].pix_len, fp);
217 }
218 }
219
220 bmap_size = (*w) * (*h);
221 bit_data = (unsigned char *) malloc(bmap_size);
222 if (bit_data == NULL) {
223 fprintf(stderr, "Cannot allocate space for bitmap\n");
224 }
225 fread(bit_data, sizeof(unsigned char), ((*w) * (*h)), fp);
226
227 bitp = bit_data;
228 for (i = 0; i < bmap_size; i++) {
229 if ((int) *bitp > (scale - 1))
230 *bitp = (unsigned char) 0;
231 bitp++;
232 }
233 } else {
234 return ((unsigned char *) NULL);
235 }
236 return (bit_data);
237 }
238
239
240 struct rgb_color
241 *
242 MapColors(data1, colrs1, data2, colrs2, width, height, Cnt)
243 unsigned char *data1;
244 struct rgb_color *colrs1;
245 unsigned char *data2;
246 struct rgb_color *colrs2;
247 int width, height;
248 int *Cnt;
249 {
250 int i, j;
251 int fcnt, indx;
252 int Mapping[MAXCOLORS];
253 unsigned char *ptr;
254 struct rgb_color *fcolrs;
255
256 fcolrs = (struct rgb_color *) malloc((MAXCOLORS + 1) * sizeof(struct rgb_color));
257
258 fcnt = 0;
259 ptr = data1;
260 for (i = 0; i < (width * height); i++) {
261 indx = (int) *ptr;
262 for (j = 0; j < fcnt; j++) {
263 if ((fcolrs[j].red == colrs1[indx].red) &&
264 (fcolrs[j].green == colrs1[indx].green) &&
265 (fcolrs[j].blue == colrs1[indx].blue)) {
266 break;
267 }
268 }
269 if (j == fcnt) {
270 fcolrs[j].red = colrs1[indx].red;
271 fcolrs[j].green = colrs1[indx].green;
272 fcolrs[j].blue = colrs1[indx].blue;
273 Mapping[indx] = j;
274 fcnt++;
275 if (fcnt > MAXCOLORS) {
276 fprintf(stderr, "Error: cannot use more than %d colors in your fish\n",
277 MAXCOLORS);
278 exit(1);
279 }
280 }
281 ptr++;
282 }
283 ptr = data1;
284 for (i = 0; i < (width * height); i++) {
285 indx = (int) *ptr;
286 *ptr = (unsigned char) (Mapping[indx]);
287 ptr++;
288 }
289
290 ptr = data2;
291 for (i = 0; i < (width * height); i++) {
292 indx = (int) *ptr;
293 for (j = 0; j < fcnt; j++) {
294 if ((fcolrs[j].red == colrs2[indx].red) &&
295 (fcolrs[j].green == colrs2[indx].green) &&
296 (fcolrs[j].blue == colrs2[indx].blue)) {
297 break;
298 }
299 }
300 if (j == fcnt) {
301 fcolrs[j].red = colrs2[indx].red;
302 fcolrs[j].green = colrs2[indx].green;
303 fcolrs[j].blue = colrs2[indx].blue;
304 Mapping[indx] = j;
305 fcnt++;
306 if (fcnt > MAXCOLORS) {
307 fprintf(stderr, "Error: cannot use more than %d colors in your fish\n",
308 MAXCOLORS);
309 exit(1);
310 }
311 }
312 ptr++;
313 }
314 ptr = data2;
315 for (i = 0; i < (width * height); i++) {
316 indx = (int) *ptr;
317 *ptr = (unsigned char) (Mapping[indx]);
318 ptr++;
319 }
320
321 for (i = 0; i < fcnt; i++) {
322 fcolrs[i].red = fcolrs[i].red * 256;
323 fcolrs[i].green = fcolrs[i].green * 256;
324 fcolrs[i].blue = fcolrs[i].blue * 256;
325 }
326 for (i = fcnt; i < 16; i++) {
327 fcolrs[i].red = 0;
328 fcolrs[i].green = 0;
329 fcolrs[i].blue = 0;
330 }
331
332 if (fcnt < 16) {
333 fcnt = 16;
334 }
335 *Cnt = fcnt;
336 return (fcolrs);
337 }
338
339
340
341 main(argc, argv)
342 int argc;
343 char *argv[];
344 {
345 FILE *ifd;
346 FILE *ofd;
347 int i, cnt, fcnt;
348 struct rgb_color colrs1[MAXCOLORS];
349 struct rgb_color colrs2[MAXCOLORS];
350 struct rgb_color *fcolrs;
351 unsigned char *data1, *data2;
352 int width1, height1, width2, height2;
353 char outfile[256];
354 char *outname;
355 int num_cnt;
356
357 if (argc < 3) {
358 fprintf(stderr, "Usage: %s <fish1> <fish2> [<outprefix>]\n", argv[0]);
359 exit(1);
360 }
361
362 ifd = fopen(argv[1], "r");
363 if (ifd == NULL) {
364 fprintf(stderr, "Error: cannot open (%s) for read\n", argv[1]);
365 exit(1);
366 }
367
368 data1 = ReadCompactEbmBitmap(ifd, &width1, &height1, colrs1);
369 if (data1 == NULL) {
370 rewind(ifd);
371 data1 = ReadEbmBitmap(ifd, &width1, &height1, colrs1);
372 }
373 if (data1 == NULL) {
374 rewind(ifd);
375 data1 = ReadGifBitmap(ifd, &width1, &height1, colrs1);
376 }
377 fclose(ifd);
378
379 if (data1 == NULL) {
380 fprintf(stderr, "Error: (%s) has unknown format\n", argv[1]);
381 exit(1);
382 }
383
384 ifd = fopen(argv[2], "r");
385 if (ifd == NULL) {
386 fprintf(stderr, "Error: cannot open (%s) for read\n", argv[2]);
387 exit(1);
388 }
389
390 data2 = ReadCompactEbmBitmap(ifd, &width2, &height2, colrs2);
391 if (data2 == NULL) {
392 rewind(ifd);
393 data2 = ReadEbmBitmap(ifd, &width2, &height2, colrs2);
394 }
395 if (data2 == NULL) {
396 rewind(ifd);
397 data2 = ReadGifBitmap(ifd, &width2, &height2, colrs2);
398 }
399 fclose(ifd);
400
401 if (data2 == NULL) {
402 fprintf(stderr, "Error: (%s) has unknown format\n", argv[2]);
403 exit(1);
404 }
405
406
407 if ((width1 != width2) || (height1 != height2)) {
408 fprintf(stderr, "Error: fish must have same dimensions\n");
409 exit(1);
410 }
411
412 fcolrs = MapColors(data1, colrs1, data2, colrs2, width1, height1, &fcnt);
413
414 if (data1[0] != data2[0]) {
415 fprintf(stderr, "Error: fish must have same backgrounds\n");
416 exit(1);
417 }
418
419 if (argc >= 4) {
420 outname = argv[3];
421 } else {
422 cnt = 0;
423 while ((argv[1][cnt] == argv[2][cnt]) && (argv[1][cnt] != '.') && (argv[2][cnt] != '.')) {
424 cnt++;
425 }
426 if (cnt == 0) {
427 fprintf(stderr, "Error: files need common prefix\n");
428 exit(1);
429 }
430 outname = (char *) malloc(cnt + 1);
431 strncpy(outname, argv[1], cnt);
432 outname[cnt] = '\0';
433 }
434 sprintf(outfile, "%s.h", outname);
435
436 ofd = fopen(outfile, "w");
437 if (ofd == NULL) {
438 fprintf(stderr, "Error: cannot open (%s) for writing\n", outfile);
439 exit(1);
440 }
441
442 fprintf(ofd, "#define %s_width\t\t%d\n", outname, width1);
443 fprintf(ofd, "#define %s_height\t\t%d\n", outname, height1);
444 fprintf(ofd, "#define %s_colors\t\t%d\n", outname, fcnt);
445 fprintf(ofd, "#define %s_back\t\t%d\n", outname, (int) data1[0]);
446 fprintf(ofd, "int\t%s_reds[] = {", outname);
447 num_cnt = 0;
448 for (i = 0; i < fcnt; i++) {
449 if (i == (fcnt - 1)) {
450 fprintf(ofd, "%d};\n", fcolrs[i].red);
451 } else {
452 fprintf(ofd, "%d, ", fcolrs[i].red);
453 if (++num_cnt >= COLS_PER_LINE) {
454 fprintf(ofd, "\n");
455 num_cnt = 0;
456 }
457 }
458 }
459 fprintf(ofd, "int\t%s_greens[] = {", outname);
460 num_cnt = 0;
461 for (i = 0; i < fcnt; i++) {
462 if (i == (fcnt - 1)) {
463 fprintf(ofd, "%d};\n", fcolrs[i].green);
464 } else {
465 fprintf(ofd, "%d, ", fcolrs[i].green);
466 if (++num_cnt >= COLS_PER_LINE) {
467 fprintf(ofd, "\n");
468 num_cnt = 0;
469 }
470 }
471 }
472 fprintf(ofd, "int\t%s_blues[] = {", outname);
473 num_cnt = 0;
474 for (i = 0; i < fcnt; i++) {
475 if (i == (fcnt - 1)) {
476 fprintf(ofd, "%d};\n", fcolrs[i].blue);
477 } else {
478 fprintf(ofd, "%d, ", fcolrs[i].blue);
479 if (++num_cnt >= COLS_PER_LINE) {
480 fprintf(ofd, "\n");
481 num_cnt = 0;
482 }
483 }
484 }
485 fprintf(ofd, "unsigned char\t%s_rasterA[] = {\n", outname);
486 num_cnt = 0;
487 for (i = 0; i < (width1 * height1); i++) {
488 fprintf(ofd, "0x%02x,", data1[i]);
489 if (++num_cnt >= NUMS_PER_LINE) {
490 fprintf(ofd, "\n");
491 num_cnt = 0;
492 }
493 }
494 fprintf(ofd, "};\n");
495 fprintf(ofd, "unsigned char\t%s_rasterB[] = {\n", outname);
496 num_cnt = 0;
497 for (i = 0; i < (width1 * height1); i++) {
498 fprintf(ofd, "0x%02x,", data2[i]);
499 if (++num_cnt >= NUMS_PER_LINE) {
500 fprintf(ofd, "\n");
501 num_cnt = 0;
502 }
503 }
504 fprintf(ofd, "};\n");
505
506 fclose(ofd);
507
508 exit(0);
509 }
This page took 0.037794 seconds and 4 git commands to generate.