Fix patches
[xfishtank.git] / read.c
CommitLineData
2ac45f02
MG
1#include <X11/Xlib.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5#include "compact.h"
6#include "medcut.h"
7
8#define DEF_BLACK BlackPixel(Dpy, DefaultScreen(Dpy))
9#define DEF_WHITE WhitePixel(Dpy, DefaultScreen(Dpy))
10#define MAX_LINE 81
11
12
13extern unsigned char *ReadGifBitmap();
14
15
16extern Display *Dpy;
17
18int NumColors;
19
20char nibMask[8] = {
21 1, 2, 4, 8, 16, 32, 64, 128
22};
23
24
25
26/*
27 * dscan is a quick replacement for:
28 *
29 * fscanf (fp, "%d", &ip);
30 */
31dscan(fp, ip)
32FILE *fp;
33int *ip;
34{
35
36 register int v = 0;
37 register int n = 0;
38 int done = 0;
39 static int nerrors;
40
41 while (!done) {
42 register int i;
43 i = getc(fp);
44 if (i < 0) {
45 *ip = v;
46 fprintf(stderr, "dscanf: EOF");
47 if (nerrors++ > 2)
48 return (-1);
49 else if (nerrors++ > 4)
50 exit(-1);
51 return (n);
52 }
53 i &= 0xFF;
54 switch (i) {
55 case '0':
56 case '1':
57 case '2':
58 case '3':
59 case '4':
60 case '5':
61 case '6':
62 case '7':
63 case '8':
64 case '9':
65 v = i - '0' + (v * 10);
66 n++;
67 break;
68 case '\n':
69 case '\r':
70 case ' ':
71 case '\t':
72 if (n) {
73 *ip = v;
74 done = 1;
75 }
76 break;
77 default:
78 fprintf(stderr, "dscanf: non numeric character (0x%x) '%c'\n", i, i);
79 if (nerrors++ > 4)
80 exit(-1);
81 return (-1);
82
83 }
84 }
85 return (n);
86}
87
88
89unsigned char *
90ReadXpmPixmap(fp, w, h, colrs, Colors, CharsPP)
91FILE *fp;
92int *w, *h;
93struct colr_data *colrs;
94int Colors, CharsPP;
95{
96 unsigned char *pixels;
97 char **Color_Vals;
98 XColor tmpcolr;
99 int i, j, k;
100 int value, found;
101 char line[BUFSIZ], name_and_type[MAX_LINE];
102 unsigned char *dataP;
103 unsigned char *bitp;
104 int tchar;
105 char *t;
106 char *t2;
107
108 NumColors = 256;
109 if (Colors == 0) {
110 fprintf(stderr, "Can't find Colors.\n");
111 return ((unsigned char *) NULL);
112 }
113 if (*w == 0) {
114 fprintf(stderr, "Invalid width.\n");
115 return ((unsigned char *) NULL);
116 }
117 if (*h == 0) {
118 fprintf(stderr, "Invalid height.\n");
119 return ((unsigned char *) NULL);
120 }
121
122 Color_Vals = (char **) malloc(sizeof(char *) * Colors);
123 for (i = 0; i < Colors; i++) {
124 tchar = getc(fp);
125 while ((tchar != '"') && (tchar != EOF)) {
126 tchar = getc(fp);
127 }
128 Color_Vals[i] = (char *) malloc(sizeof(char) * (CharsPP + 1));
129 j = 0;
130 tchar = getc(fp);
131 while ((tchar != '"') && (tchar != EOF) && (j < CharsPP)) {
132 Color_Vals[i][j] = (char) tchar;
133 tchar = getc(fp);
134 j++;
135 }
136 Color_Vals[i][j] = '\0';
137 if (tchar != '"') {
138 tchar = getc(fp);
139 while ((tchar != '"') && (tchar != EOF)) {
140 tchar = getc(fp);
141 }
142 }
143 tchar = getc(fp);
144 while ((tchar != '"') && (tchar != EOF)) {
145 tchar = getc(fp);
146 }
147 j = 0;
148 tchar = getc(fp);
149 while ((tchar != '"') && (tchar != EOF)) {
150 line[j] = (char) tchar;
151 tchar = getc(fp);
152 j++;
153 }
154 line[j] = '\0';
155 XParseColor(Dpy, DefaultColormap(Dpy, DefaultScreen(Dpy)), line, &tmpcolr);
156 colrs[i].red = tmpcolr.red;
157 colrs[i].green = tmpcolr.green;
158 colrs[i].blue = tmpcolr.blue;
159 }
160 for (i = Colors; i < 256; i++) {
161 colrs[i].red = 0;
162 colrs[i].green = 0;
163 colrs[i].blue = 0;
164 }
165 tchar = getc(fp);
166 while ((tchar != ';') && (tchar != EOF)) {
167 tchar = getc(fp);
168 }
169
170 for (;;) {
171 if (!(fgets(line, MAX_LINE, fp))) {
172 fprintf(stderr, "Can't find Pixels\n");
173 return ((unsigned char *) NULL);
174 } else if (sscanf(line, "static char * %s = {", name_and_type) == 1) {
175 if ((t = (char *) rindex(name_and_type, '_')) == NULL) {
176 t = name_and_type;
177 } else {
178 t++;
179 }
180 if ((t2 = (char *) index(name_and_type, '[')) != NULL) {
181 *t2 = '\0';
182 }
183 if (!strcmp("pixels", t)) {
184 break;
185 }
186 }
187 }
188 pixels = (unsigned char *) malloc((*w) * (*h));
189 if (pixels == NULL) {
190 fprintf(stderr, "Not enough memory for data.\n");
191 return ((unsigned char *) NULL);
192 }
193
194 line[0] = '\0';
195 t = line;
196 dataP = pixels;
197 tchar = getc(fp);
198 while ((tchar != '"') && (tchar != EOF)) {
199 tchar = getc(fp);
200 }
201 tchar = getc(fp);
202 for (j = 0; j < (*h); j++) {
203 for (i = 0; i < (*w); i++) {
204 k = 0;
205 while ((tchar != '"') && (tchar != EOF) && (k < CharsPP)) {
206 line[k] = (char) tchar;
207 tchar = getc(fp);
208 k++;
209 }
210 if ((k == 0) && (tchar == '"')) {
211 tchar = getc(fp);
212 while ((tchar != '"') && (tchar != EOF)) {
213 tchar = getc(fp);
214 }
215 k = 0;
216 tchar = getc(fp);
217 while ((tchar != '"') && (tchar != EOF) && (k < CharsPP)) {
218 line[k] = (char) tchar;
219 tchar = getc(fp);
220 k++;
221 }
222 }
223 line[k] = '\0';
224 found = 0;
225 for (k = 0; k < Colors; k++) {
226 if (strncmp(Color_Vals[k], line, CharsPP) == 0) {
227 *dataP++ = (unsigned char) k;
228 found = 1;
229 break;
230 }
231 }
232 if (found == 0) {
233 fprintf(stderr, "Invalid Pixel (%2s) in file\n", line);
234 *dataP++ = (unsigned char) 0;
235 }
236 }
237 }
238 bitp = pixels;
239 for (i = 0; i < ((*w) * (*h)); i++) {
240 if ((int) *bitp > (256 - 1))
241 *bitp = (unsigned char) 0;
242 bitp++;
243 }
244 for (i = 0; i < Colors; i++) {
245 free((char *) Color_Vals[i]);
246 }
247 free((char *) Color_Vals);
248 return (pixels);
249}
250
251
252unsigned char *
253ReadXbmBitmap(fp, w, h, colrs)
254FILE *fp;
255int *w, *h;
256struct colr_data *colrs;
257{
258 int blackbit = BlackPixel(Dpy, DefaultScreen(Dpy));
259 int whitebit = WhitePixel(Dpy, DefaultScreen(Dpy));
260 char line[MAX_LINE], name_and_type[MAX_LINE];
261 char *t;
262 char *t2;
263 unsigned char *ptr, *dataP;
264 int bytes_per_line, version10p, raster_length, padding;
265 int i, bytes, temp, value;
266 int Ncolors, charspp, xpmformat;
267
268 *w = 0;
269 *h = 0;
270 Ncolors = 0;
271 charspp = 0;
272 xpmformat = 0;
273 for (;;) {
274 if (!(fgets(line, MAX_LINE, fp)))
275 break;
276 if (strlen(line) == (MAX_LINE - 1)) {
277 fprintf(stderr, "Line too long.\n");
278 return ((unsigned char *) NULL);
279 }
280 if (sscanf(line, "#define %s %d", name_and_type, &value) == 2) {
281 if (!(t = (char *) rindex(name_and_type, '_')))
282 t = name_and_type;
283 else
284 t++;
285 if (!strcmp("width", t))
286 *w = value;
287 if (!strcmp("height", t))
288 *h = value;
289 if (!strcmp("ncolors", t))
290 Ncolors = value;
291 if (!strcmp("pixel", t))
292 charspp = value;
293 continue;
294 }
295 if (sscanf(line, "static short %s = {", name_and_type) == 1) {
296 version10p = 1;
297 break;
298 } else if (sscanf(line, "static char * %s = {", name_and_type) == 1) {
299 xpmformat = 1;
300 if (!(t = (char *) rindex(name_and_type, '_')))
301 t = name_and_type;
302 else
303 t++;
304 if ((t2 = (char *) index(name_and_type, '[')) != NULL)
305 *t2 = '\0';
306 if (!strcmp("mono", t))
307 continue;
308 else
309 break;
310 } else if (sscanf(line, "static char %s = {", name_and_type) == 1) {
311 version10p = 0;
312 break;
313 } else
314 continue;
315 }
316 if (xpmformat) {
317 dataP = ReadXpmPixmap(fp, w, h, colrs, Ncolors, charspp);
318 return (dataP);
319 }
320 if (*w == 0) {
321 fprintf(stderr, "Invalid width.\n");
322 return ((unsigned char *) NULL);
323 }
324 if (*h == 0) {
325 fprintf(stderr, "Invalid height.\n");
326 return ((unsigned char *) NULL);
327 }
328 padding = 0;
329 if (((*w % 16) >= 1) && ((*w % 16) <= 8) && version10p) {
330 padding = 1;
331 }
332 bytes_per_line = ((*w + 7) / 8) + padding;
333 raster_length = bytes_per_line * *h;
334 dataP = (unsigned char *) malloc((*w) * (*h));
335 if (dataP == NULL) {
336 fprintf(stderr, "Not enough memory.\n");
337 return ((unsigned char *) NULL);
338 }
339 ptr = dataP;
340 if (version10p) {
341 int cnt = 0;
342 int lim = (bytes_per_line - padding) * 8;
343 for (bytes = 0; bytes < raster_length; bytes += 2) {
344 if (fscanf(fp, " 0x%x%*[,}]%*[ \n]", &value) != 1) {
345 fprintf(stderr, "Error scanning bits item.\n");
346 return ((unsigned char *) NULL);
347 }
348 temp = value;
349 value = temp & 0xff;
350 for (i = 0; i < 8; i++) {
351 if (cnt < (*w)) {
352 if (value & nibMask[i])
353 *ptr++ = blackbit;
354 else
355 *ptr++ = whitebit;
356 }
357 if (++cnt >= lim)
358 cnt = 0;
359 }
360 if ((!padding) || ((bytes + 2) % bytes_per_line)) {
361 value = temp >> 8;
362 for (i = 0; i < 8; i++) {
363 if (cnt < (*w)) {
364 if (value & nibMask[i])
365 *ptr++ = blackbit;
366 else
367 *ptr++ = whitebit;
368 }
369 if (++cnt >= lim)
370 cnt = 0;
371 }
372 }
373 }
374 } else {
375 int cnt = 0;
376 int lim = bytes_per_line * 8;
377 for (bytes = 0; bytes < raster_length; bytes++) {
378 if (fscanf(fp, " 0x%x%*[,}]%*[ \n]", &value) != 1) {
379 fprintf(stderr, "Error scanning bits item.\n");
380 return ((unsigned char *) NULL);
381 }
382 for (i = 0; i < 8; i++) {
383 if (cnt < (*w)) {
384 if (value & nibMask[i])
385 *ptr++ = blackbit;
386 else
387 *ptr++ = whitebit;
388 }
389 if (++cnt >= lim)
390 cnt = 0;
391 }
392 }
393 }
394 NumColors = 2;
395 return (dataP);
396}
397
398
399unsigned char *
400ReadEbmBitmap(fp, w, h, colrs)
401FILE *fp;
402int *w, *h;
403struct colr_data *colrs;
404{
405 int i, temp, scale;
406 unsigned int bmap_size;
407 int *ptr[3];
408 int red, green, blue;
409 char line[1024];
410 unsigned char *bit_data;
411 unsigned char *bitp;
412
413 bit_data = NULL;
414 *w = 0;
415 *h = 0;
416
417 if ((fscanf(fp, "%12s %d %d %d\n", line, w, h, &scale) == 4) &&
418 (strcmp(line, "xstitch_data") == 0)) {
419 for (i = 0; i < 3; i++) {
420 fscanf(fp, "%s", line);
421 if (strcmp(line, "red") == 0) {
422 ptr[i] = &red;
423 } else if (strcmp(line, "green") == 0) {
424 ptr[i] = &green;
425 } else if (strcmp(line, "blue") == 0) {
426 ptr[i] = &blue;
427 } else {
428 fprintf(stderr, "File has improper format\n");
429 return ((unsigned char *) NULL);
430 }
431 }
432 fscanf(fp, "[^\n]\n");
433 for (i = 0; i < scale; i++) {
434 line[0] = '\0';
435 if (fscanf(fp, "%d %d %d%[^\n]\n", ptr[0], ptr[1], ptr[2], line) < 3) {
436 fprintf(stderr, "Bad color data #%d\n", i);
437 }
438 colrs[i].red = red * 65536 / scale;
439 colrs[i].green = green * 65536 / scale;
440 colrs[i].blue = blue * 65536 / scale;
441 }
442 for (i = scale; i < 256; i++) {
443 colrs[i].red = 0;
444 colrs[i].green = 0;
445 colrs[i].blue = 0;
446 }
447
448 bmap_size = (*w) * (*h);
449 bit_data = (unsigned char *) malloc(bmap_size);
450 if (bit_data == NULL) {
451 fprintf(stderr, "Cannot allocate space for bitmap\n");
452 }
453 bitp = bit_data;
454 for (i = 0; i < bmap_size; i++) {
455 if (dscan(fp, &temp) == -1)
456 break;
457 if (temp > (256 - 1))
458 temp = 0;
459 *bitp = (unsigned char) temp;
460 bitp++;
461 }
462 } else {
463 return ((unsigned char *) NULL);
464 }
465 NumColors = scale;
466 return (bit_data);
467}
468
469
470int
471swapint(in)
472int in;
473{
474 int out;
475
476 out = 0;
477 out = out | ((in >> 24) & 0xff);
478 out = out | ((in >> 8) & 0xff00);
479 out = out | ((in << 8) & 0xff0000);
480 out = out | ((in << 24) & 0xff000000);
481 return (out);
482}
483
484
485unsigned char *
486ReadCompactEbmBitmap(fp, w, h, colrs)
487FILE *fp;
488int *w, *h;
489struct colr_data *colrs;
490{
491 int i, scale;
492 unsigned int bmap_size;
493 char pix_file[1024];
494 unsigned char *bit_data;
495 unsigned char *bitp;
496 struct ebmhdr Hdr;
497 struct rgb_color color_data;
498 int doswap;
499
500 doswap = 0;
501 bit_data = NULL;
502 *w = 0;
503 *h = 0;
504
505 fread(&Hdr, sizeof(struct ebmhdr), 1, fp);
506 if (strcmp(Hdr.magic, "xstitch") == 0) {
507 /*
508 * a horrible hack to deal with different byte ordering on
509 * different machines. Is based on assumption of only 2
510 * possible byte orderings, and never more than 256 colors.
511 */
512 if (Hdr.num_colors > 256) {
513 doswap = 1;
514 Hdr.width = swapint(Hdr.width);
515 Hdr.height = swapint(Hdr.height);
516 Hdr.num_colors = swapint(Hdr.num_colors);
517 }
518
519 *w = Hdr.width;
520 *h = Hdr.height;
521 scale = Hdr.num_colors;
522 for (i = 0; i < Hdr.num_colors; i++) {
523 fread(&color_data, sizeof(struct rgb_color), 1, fp);
524 if (doswap) {
525 color_data.red = swapint(color_data.red);
526 color_data.green = swapint(color_data.green);
527 color_data.blue = swapint(color_data.blue);
528 color_data.pix_len = swapint(color_data.pix_len);
529 }
530 colrs[i].red = color_data.red * 65536 / scale;
531 colrs[i].green = color_data.green * 65536 / scale;
532 colrs[i].blue = color_data.blue * 65536 / scale;
533 if (color_data.pix_len != 0) {
534 if (color_data.pix_len > 1023) {
535 fprintf(stderr, "bad pattern\n");
536 return ((unsigned char *) NULL);
537 }
538 fread(pix_file, sizeof(char), color_data.pix_len, fp);
539 }
540 }
541 for (i = scale; i < 256; i++) {
542 colrs[i].red = 0;
543 colrs[i].green = 0;
544 colrs[i].blue = 0;
545 }
546
547 bmap_size = (*w) * (*h);
548 bit_data = (unsigned char *) malloc(bmap_size);
549 if (bit_data == NULL) {
550 fprintf(stderr, "Cannot allocate space for bitmap\n");
551 }
552 fread(bit_data, sizeof(unsigned char), ((*w) * (*h)), fp);
553
554 bitp = bit_data;
555 for (i = 0; i < bmap_size; i++) {
556 if ((int) *bitp > (256 - 1))
557 *bitp = (unsigned char) 0;
558 bitp++;
559 }
560 } else {
561 return ((unsigned char *) NULL);
562 }
563 NumColors = scale;
564 return (bit_data);
565}
566
567
568unsigned char *
569ReadBitmap(fp, w, h, colrs)
570FILE *fp;
571int *w, *h;
572struct colr_data *colrs;
573{
574 unsigned char *bit_data;
575
576 NumColors = 0;
577
578 if (fp != NULL) {
579 bit_data = ReadEbmBitmap(fp, w, h, colrs);
580 if (bit_data != NULL) {
581 return (bit_data);
582 }
583 rewind(fp);
584 bit_data = ReadCompactEbmBitmap(fp, w, h, colrs);
585 if (bit_data != NULL) {
586 return (bit_data);
587 }
588#ifdef GIF
589 rewind(fp);
590 bit_data = ReadGifBitmap(fp, w, h, colrs);
591 if (bit_data != NULL) {
592 return (bit_data);
593 }
594#endif
595 rewind(fp);
596 bit_data = ReadXbmBitmap(fp, w, h, colrs);
597 if (bit_data != NULL) {
598 return (bit_data);
599 }
600 }
601 return ((unsigned char *) NULL);
602}
This page took 0.040923 seconds and 4 git commands to generate.