1 /*
2 * readvmf.c
3 * Jean-Pierre Demailly
4 * July 2001
5 *
6 * Copyright (C) 2001 by Jean-Pierre Demailly <demailly@ujf-grenoble.fr>
7 *
8 * Permission to use, copy, modify and freely distribute these data for
9 * non-commercial and not-for-profit purposes is hereby granted
10 * without fee, provided that both the above copyright notice and this
11 * permission notice appear in all copies and in supporting
12 * documentation.
13 *
14 * The author makes no representations about the suitability of this
15 * software for any purpose. It is provided "as is" without express or
16 * implied warranty.
17 *
18 * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT
21 * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
23 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
24 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 */
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <math.h>
30 #ifdef ZLIB
31 #include <zlib.h>
32 #include <errno.h>
33 #endif
34
35 #include "sunclock.h"
36
37 #define LINELENGTH 256
38
39 extern char *ProgName;
40 extern char *vmfcolors;
41 extern char *vmfrange;
42 extern char *vmfcoordformat;
43
44 extern Display * dpy;
45 extern Colormap tmp_cmap;
46
47 extern int scr;
48 extern int bigendian;
49 extern int color_depth;
50 extern int color_pad;
51 extern int bytes_per_pixel;
52 extern int color_alloc_failed;
53 extern int verbose;
54 extern int reformat;
55 extern int min_zoomwidth;
56 extern int min_zoomheight;
57
58 static struct Sundata *map;
59 #define pixels map->vmfpixels /* Pointer to list of colors */
60
61 static int mapwidth;
62 static int mapheight;
63 static int fillmode;
64
65 static char *buffer; /* Buffer to hold input lines */
66 static int *grid; /* Pointer to grid data */
67 static int *palette; /* Pointer to list of color codes */
68
69 static int uu, cc, vv, vv1, vv2, full;
70 static int num_palette;
71 static int default_color;
72
73 static double txmin=1E27, txmax=-1E27, tymin=1E27, tymax=-1E27;
74
75 char *
salloc(nbytes)76 salloc(nbytes)
77 register int nbytes;
78 {
79 register char * p;
80
81 p = malloc((unsigned)nbytes);
82 if (p == (char *)NULL) {
83 fprintf(stderr, "%s: %d bytes required; out of memory\n",
84 ProgName, nbytes);
85 exit(1);
86 }
87 return (p);
88 }
89
90 void
plotdata(u,v,s)91 plotdata(u, v, s)
92 int u, v, s;
93 {
94 int v1=0, v2=0, c, w, ind;
95
96 c = u;
97 if (c<0) c+=map->zoom.width;
98 if (c>=map->zoom.width) c-=map->zoom.width;
99 c -= map->zoom.dx-1;
100 v -= map->zoom.dy;
101
102 if (fillmode==0) {
103 if (c>=0 && c<=mapwidth && v>=0 && v<mapheight) {
104 ind = c*mapheight+v;
105 if (s>0) grid[ind] = s * 65536;
106 if (s<0) grid[ind] = -s * 65536;
107 }
108 return;
109 }
110
111 if (c>=0 && c<=mapwidth) {
112 ind = c*mapheight;
113
114 if (v>=0 && v<mapheight) {
115 if (s>0) grid[ind+v] |= s;
116 if (s<0) grid[ind+v] |= -s;
117 }
118
119 s *= 65536;
120
121 if (v<0) v1=0; else v1=v+1;
122 if (v>=mapheight) v2=mapheight-1; else v2=v;
123
124 if (u==uu) {
125 if (v>vv)
126 for (w=vv1; w<=v2; w++) grid[ind+w] += s;
127 if (v<vv)
128 for (w=v1; w<=vv2; w++) grid[ind+w] -= s;
129 }
130 if (u>uu)
131 for (w=0; w<=v2; w++) grid[ind+w] += s;
132 }
133
134 if (u<uu && cc>=0 && cc<=mapwidth) {
135 ind = cc*mapheight;
136 for (w=0; w<=vv2; w++) grid[ind+w] -= s;
137 }
138
139 uu = u;
140 cc = c;
141 vv = v;
142 vv1 = v1;
143 vv2 = v2;
144 }
145
check(i,j,which)146 int check(i, j, which)
147 int i, j, which;
148 {
149 #define MASK -65536
150 int ind, indp, inds;
151
152 which *= 65536;
153
154 ind = i*mapheight+j;
155 if (j>0 && (grid[ind-1]&MASK)!=which) return 1;
156 if (j<mapheight-1 && (grid[ind+1]&MASK)!=which) return 1;
157
158 indp = (i-1)*mapheight+j;
159 if (i>0 && (grid[indp]&MASK)!=which) return 1;
160
161 inds = (i+1)*mapheight+j;
162 if (i<mapwidth && (grid[inds]&MASK)!=which) return 1;
163
164 if (full) {
165 if (j>0) {
166 if (i>0 && (grid[indp-1]&MASK)!=which) return 1;
167 if (i<mapwidth && (grid[inds-1]&MASK)!=which) return 1;
168 }
169 if (j<mapheight-1) {
170 if (i>0 && (grid[indp+1]&MASK)!=which) return 1;
171 if (i<mapwidth && (grid[inds+1]&MASK)!=which) return 1;
172 }
173 }
174 return 0;
175 }
176
177 void
filterdata()178 filterdata()
179 {
180 int i, j, t, ind;
181
182 if (fillmode==0) return;
183
184 if (fillmode==1) {
185
186 for (j=0; j<mapheight; j++)
187 for (i=0; i<=mapwidth; i++) {
188 ind = i*mapheight+j;
189 t = grid[ind];
190 full = 1;
191 if ( (t & 16383) && !check(i,j,0) ) {
192 grid[ind] |= 16384;
193 continue;
194 }
195 full = 0;
196 t = t/65536;
197 if ((t>0) && !check(i,j,t)) grid[ind] |= 32768;
198 }
199
200 for (j=0; j<mapheight; j++)
201 for (i=0; i<=mapwidth; i++) {
202 ind = i*mapheight+j;
203 t = grid[ind];
204 if (t&16384)
205 grid[ind] = (t&16383) * 65536;
206 else
207 if (t&32768)
208 grid[ind] = 0;
209 else
210 grid[ind] = t&MASK;
211 }
212 goto correct;
213 }
214
215 /* only remains fillmode = 2 */
216 full = 1;
217
218 for (j=0; j<mapheight; j++)
219 for (i=0; i<=mapwidth; i++)
220 if (check(i,j,0)) grid[i*mapheight+j] &= MASK;
221
222 for (j=0; j<mapheight; j++)
223 for (i=0; i<=mapwidth; i++) {
224 ind = i*mapheight+j;
225 t = (grid[ind] & 32767) * 65536;
226 grid[ind] |= t;
227 }
228
229 correct:
230 if (map->zoom.width > map->geom.width && map->zoom.dx == 0) {
231 for (j=0; j<mapheight; j++) grid[j+mapheight] = grid[j+2*mapheight];
232 }
233 }
234
235 char *
blacknwhite_image()236 blacknwhite_image()
237 {
238 int i, j, k, l, u;
239 char *bits;
240
241 bits = (char *)
242 salloc(((mapwidth+7)/8)*mapheight*sizeof(char));
243
244 k = 0;
245 for (j=0; j<mapheight; j++) {
246 l = 1;
247 u = 0;
248 for (i=0; i<mapwidth; i++) {
249 if (grid[(i+1)*mapheight+j]<65536) u = u+l;
250 l = l+l;
251 if (l==256 || i==mapwidth-1) {
252 bits[k] = u;
253 u = 0;
254 l = 1;
255 ++k;
256 }
257 }
258 }
259 return bits;
260 }
261
262 XImage *
pixmap_image()263 pixmap_image()
264 {
265 int i, j, k, l, w, h;
266 char *c;
267 XImage *image;
268 Visual visual;
269
270 visual = *DefaultVisual(dpy, scr);
271
272 w = mapwidth;
273 h = mapheight;
274
275 image = XCreateImage(dpy,&visual,
276 DefaultDepth(dpy, scr), ZPixmap, 0, NULL, w, h, color_pad, 0);
277 if (!image) return NULL;
278
279 bytes_per_pixel = (image->bits_per_pixel/8);
280 image->data = (char *) salloc(image->bytes_per_line * h);
281
282 if (color_depth>16)
283 for (j=0; j<mapheight; j++) {
284 c = image->data + j * image->bytes_per_line;
285 for (i=0; i<mapwidth; i++) {
286 k = bytes_per_pixel * i;
287 l = grid[(i+1)*mapheight+j]/65536;
288 if (l>=0 && l<num_palette)
289 l = palette[l];
290 else
291 l = default_color;
292 if (bigendian) {
293 c[k+1] = (pixels[l] >> 16) & 255;
294 c[k+2] = (pixels[l] >> 8) & 255;
295 c[k+3] = pixels[l];
296 } else {
297 c[k] = pixels[l];
298 c[k+1] = (pixels[l] >> 8) & 255;
299 c[k+2] = (pixels[l] >> 16) & 255;
300 }
301 }
302 }
303 else
304 if (color_depth>8)
305 for (j=0; j<mapheight; j++) {
306 c = image->data + j * mapwidth * bytes_per_pixel;
307 for (i=0; i<mapwidth; i++) {
308 k = bytes_per_pixel * i;
309 l = grid[(i+1)*mapheight+j]/65536;
310 if (l>=0 && l<num_palette)
311 l = palette[l];
312 else
313 l = default_color;
314 if (bigendian) {
315 c[k] = pixels[l] / 256;
316 c[k+1] = pixels[l] & 255;
317 } else {
318 c[k] = pixels[l] & 255;
319 c[k+1] = pixels[l] / 256;
320 }
321 }
322 }
323 else
324 for (j=0; j<mapheight; j++) {
325 c = image->data + j * mapwidth * bytes_per_pixel;
326 for (i=0; i<mapwidth; i++) {
327 k = bytes_per_pixel * i;
328 l = grid[(i+1)*mapheight+j]/65536;
329 if (l>=0 && l<num_palette)
330 l = palette[l];
331 else
332 l = default_color;
333 c[k] = pixels[l] & 255;
334 }
335 }
336
337 return image;
338 }
339
340 char *
getdata(fd)341 getdata(fd)
342 #ifdef ZLIB
343 gzFile fd;
344 #else
345 FILE *fd;
346 #endif
347 {
348 int i, j;
349 char c;
350
351 repeat:
352 #ifdef ZLIB
353 i = gzgetc(fd);
354 #else
355 i = fgetc(fd);
356 #endif
357 if (i==EOF) return NULL;
358
359 c = (char) i;
360
361 if (c=='%') {
362 if (reformat) printf("%c", i);
363 while (i!=EOF && (char) i!= '\n') {
364 #ifdef ZLIB
365 i = gzgetc(fd);
366 #else
367 i = fgetc(fd);
368 #endif
369 if (reformat) printf("%c", i);
370 }
371 if (i==EOF) return NULL;
372 goto repeat;
373 }
374
375 while(isspace(c)) goto repeat;
376
377 j = 0;
378 while(!isspace(c) && j<LINELENGTH) {
379 buffer[j] = c;
380 ++j;
381 #ifdef ZLIB
382 i = gzgetc(fd);
383 #else
384 i = fgetc(fd);
385 #endif
386 if (i==EOF) break;
387 c = (char) i;
388 }
389
390 buffer[j] = '\0';
391 return buffer;
392 }
393
394 Pixel
getPixel(cmap,str)395 getPixel(cmap, str)
396 Colormap cmap;
397 char *str;
398 {
399 Status s;
400 XColor c, e;
401
402 if (!str) {
403 color_alloc_failed += 2;;
404 return 0;
405 }
406
407 s = XAllocNamedColor(dpy, cmap, str, &c, &e);
408 if (s != (Status)1) {
409 fprintf(stderr, "%s: warning: can't allocate color `%s'\n",
410 ProgName, buffer);
411 color_alloc_failed += 2;
412 return 0;
413 }
414 return c.pixel;
415 }
416
417 int
readVMF(path,Context)418 readVMF(path, Context)
419 char * path;
420 struct Sundata * Context;
421 {
422 char coordformat[32] = "%7.3f %8.3f";
423 int num_colors, correct, maxgrid, run_flag = -1, opencurves = 0,
424 ret_value = -1;
425 int color=0, i, j, k, l, num=0, count=0, u=0, v=0, up, vp, flag;
426 int position=0;
427 int m, min, max, addumin, addvmin, addumax, addvmax, diffu, diffv, sum;
428 double fx=0.0, fy=0.0, fx0=0.0, fy0=0.0;
429 double fxmin=-180.0, fxmax=180.0, fymin=-90.0, fymax=90.0,
430 fdx=360.0, fdy=180.0;
431 double rxmin=-180.0, rxmax, rymin=-90.0, rymax;
432 double cx=1.0, cy=1.0, cdx=0.0, cdy=0.0;
433 double theta, phi;
434 char *str, *ptr;
435 #ifdef ZLIB
436 gzFile fd;
437 int plen;
438 char *zpath;
439 #else
440 FILE *fd;
441 #endif
442
443 fd = NULL;
444 buffer = NULL;
445 palette = NULL;
446 grid = NULL;
447 min_zoomwidth = 0;
448 min_zoomheight = 0;
449
450 if (!path) {
451 ret_value = 1;
452 goto abort;
453 }
454
455 map = Context;
456 fillmode = Context->flags.fillmode;
457 mapwidth = Context->geom.width;
458 if (mapwidth <=10) return 4;
459 mapheight = Context->geom.height;
460 if (mapheight<= 5) return 4;
461
462 if (verbose)
463 fprintf(stderr, "Loading vector map %s\n", path);
464 #ifdef ZLIB
465 fd = gzopen(path, "r");
466 #define Z_PATH_EXT ".gz"
467 #define Z_PATH_LEN ( sizeof( Z_PATH_EXT)- 1)
468 if ( fd == NULL && errno == ENOENT
469 && ( ( plen= strlen( path)) < Z_PATH_LEN
470 || strcmp( &path[ plen- Z_PATH_LEN], Z_PATH_EXT) != 0))
471 { /* try to open gzip'd file... (ThMO) */
472 #if __GNUC__ >= 2
473 zpath= alloca( plen+ Z_PATH_LEN+ 1);
474 #else
475 zpath= salloc( plen+ Z_PATH_LEN+ 1);
476 #endif
477 memcpy( zpath, path, plen);
478 memcpy( zpath+ plen, Z_PATH_EXT, Z_PATH_LEN+ 1);
479 if ( verbose)
480 fprintf( stderr, "Try loading vector map %s\n", zpath);
481 fd= gzopen( zpath, "r");
482 #if !( __GNUC__ >= 2)
483 free( zpath);
484 #endif
485 }
486 #undef Z_PATH_EXT
487 #undef Z_PATH_LEN
488 #else
489 fd = fopen(path, "r");
490 #endif
491 if (fd == NULL) {
492 ret_value = 1;
493 goto abort;
494 }
495
496 buffer = (char *) salloc(LINELENGTH+2);
497 if (!buffer) goto abort;
498
499 #ifdef ZLIB
500 str = gzgets(fd, buffer, LINELENGTH);
501 #else
502 str = fgets(buffer, LINELENGTH, fd);
503 #endif
504 if (!str || strncmp(buffer, "%!VMF", 5)) {
505 ret_value = 5;
506 goto abort;
507 }
508 if (reformat) printf(str);
509
510 k = 0;
511 num_colors = 0;
512 while (1) {
513 if (map->flags.colorlevel==FULLCOLORS) {
514 count = color_alloc_failed;
515 if (vmfcolors) {
516 if (vmfcolors[k]) {
517 strcpy(buffer, vmfcolors+k);
518 str = buffer;
519 l = 0;
520 while (str[l]!='|' && str[l] != '\0') ++l;
521 if (str[l]=='|')
522 k=k+l+1;
523 else
524 k=k+l;
525 str[l] = '\0';
526 if (*str) {
527 ++num_colors;
528 pixels =
529 (Pixel *)realloc((void *)pixels, num_colors*sizeof(Pixel));
530 if (!pixels) goto abort;
531 pixels[num_colors-1] = getPixel(tmp_cmap, str);
532 } else
533 --count;
534 } else
535 --count;
536 }
537 str = getdata(fd);
538 if (!strcmp(str, ";")) break;
539 if (!vmfcolors || color_alloc_failed>count) {
540 count = color_alloc_failed;
541 ++num_colors;
542 pixels = (Pixel *)realloc((void *)pixels, num_colors*sizeof(Pixel));
543 if (!pixels) goto abort;
544 pixels[num_colors-1] = getPixel(tmp_cmap, str);
545 }
546 if (color_alloc_failed>count) {
547 color_alloc_failed = 1;
548 ret_value = 6;
549 goto abort;
550 } else
551 color_alloc_failed &= 1;
552 if (color_depth<=8)
553 Context->daypixel[num_colors-1] =
554 (unsigned char) pixels[num_colors-1];
555 } else {
556 str = getdata(fd);
557 ++num_colors;
558 if (!strcmp(str, ";")) break;
559 }
560 if (reformat) printf("%s\t", str);
561 }
562 if (reformat) printf(";\n\n");
563 Context->ncolors = num_colors;
564
565 str = getdata(fd);
566 if (!str) goto abort;
567 default_color = atoi(str);
568 if (default_color<0 || default_color>=num_colors) goto abort;
569 if (reformat) printf("%d\n\n", default_color);
570
571 j = 0;
572 num_palette = 0;
573 while (1) {
574 str = getdata(fd);
575 if (!str) goto abort;
576 if (*str==';') {
577 if (reformat) printf("\n;\n\n");
578 break;
579 }
580 if (*str=='c') {
581 v = atoi(str+1);
582 if (v<0 || v>=num_colors) goto abort;
583 if (reformat) {
584 if (j) printf("\n");
585 printf("c%d", v);
586 }
587 }
588 else {
589 u = atoi(str);
590 if (u<0) goto abort;
591 if (u>=num_palette) {
592 palette = (int *) realloc(palette, (u+1)*sizeof(int));
593 if (!palette) goto abort;
594 for (k=num_palette; k<u; ++k) palette[k] = default_color;
595 num_palette = u+1;
596 }
597 palette[u] = v;
598 if (reformat) printf(" %d", u);
599 }
600 ++j;
601 }
602
603 str = getdata(fd);
604 if (!str) goto abort;
605 if (fillmode)
606 correct = atoi(str);
607 else
608 correct = 0;
609 if (reformat) printf("%d\n\n", correct);
610 correct *= 65536;
611
612 maxgrid = (mapwidth+1)*mapheight;
613 grid = (int *) salloc(maxgrid*sizeof(int));
614 for (i=0; i<maxgrid; i++) grid[i] = correct;
615
616 count = 0;
617
618 if (reformat) {
619 if (vmfrange) {
620 if (vmfcoordformat)
621 strncpy(coordformat, vmfcoordformat, 30);
622 else
623 strcpy(coordformat, "%g %g");
624 for (i=0; i<strlen(vmfrange); i++)
625 if (vmfrange[i]=='|') vmfrange[i] = ' ';
626 if (sscanf(vmfrange, "%lg %lg %lg %lg",
627 &rymin, &rymax, &rxmin, &rxmax)<4)
628 goto abort;
629 } else {
630 rxmin = fxmin;
631 rxmax = fxmax;
632 rymin = fymin;
633 rymax = fymax;
634 }
635 cx = (rxmax-rxmin)/fdx;
636 cy = (rymax-rymin)/fdy;
637 cdx = -fxmin*cx+rxmin;
638 cdy = -fymin*cy+rymin;
639 }
640
641 iter:
642 str = getdata(fd);
643 if (!str) goto abort;
644 if (*str >= 'A') {
645 if (!strcmp(str, "end")) {
646 if (reformat)
647 printf("\n%s\n", str);
648 goto endcurves;
649 } else
650 if (!strcmp(str, "flag")) {
651 str = getdata(fd);
652 if (!str) goto abort;
653 run_flag = atoi(str);
654 if (reformat)
655 printf("flag %d\n", run_flag);
656 } else
657 if (!strcmp(str, "opencurves")) {
658 if (reformat)
659 printf("%s\n", str);
660 opencurves = 1;
661 } else
662 if (!strcmp(str, "closedcurves")) {
663 if (reformat)
664 printf("%s\n", str);
665 opencurves = 0;
666 } else
667 if (!strcmp(str, "zoomwidth")) {
668 str = getdata(fd);
669 min_zoomwidth = atoi(str);
670 } else
671 if (!strcmp(str, "zoomheight")) {
672 str = getdata(fd);
673 min_zoomheight = atoi(str);
674 } else
675 if (!strcmp(str, "fillmode")) {
676 str = getdata(fd);
677 if (!str) goto abort;
678 i = atoi(str);
679 if (reformat)
680 printf("fillmode %d\n", i);
681 if (i>map->flags.fillmode)
682 i = map->flags.fillmode;
683 if (i<fillmode) filterdata();
684 fillmode = i;
685 } else
686 if (!strcmp(str, "range")) {
687 str = getdata(fd);
688 if (!str) goto abort;
689 fymin = atof(str);
690 str = getdata(fd);
691 if (!str) goto abort;
692 fymax = atof(str);
693 str = getdata(fd);
694 if (!str) goto abort;
695 fxmin = atof(str);
696 str = getdata(fd);
697 if (!str) goto abort;
698 fxmax = atof(str);
699 fdx = fxmax - fxmin;
700 fdy = fymax - fymin;
701 if (reformat) {
702 if (!vmfrange){
703 rxmin = fxmin;
704 rxmax = fxmax;
705 rymin = fymin;
706 rymax = fymax;
707 }
708 cx = (rxmax-rxmin)/fdx;
709 cy = (rymax-rymin)/fdy;
710 cdx = -fxmin*cx+rxmin;
711 cdy = -fymin*cy+rymin;
712 printf("range %g %g %g %g\n\n", rymin, rymax, rxmin, rxmax);
713 }
714 } else
715 if (!strcmp(str, "label")) {
716 /* get rid of count number */
717 str = getdata(fd);
718 str = getdata(fd);
719 if (!str) goto abort;
720 color = atoi(str);
721 str = getdata(fd);
722 if (!str) goto abort;
723 position = atoi(str);
724 str = getdata(fd);
725 if (!str) goto abort;
726 fy = atof(str);
727 str = getdata(fd);
728 if (!str) goto abort;
729 fx = atof(str);
730 if (reformat) {
731 printf("\nlabel %d %d %d ", count, color, position);
732 printf(coordformat, fy, fx);
733 printf("\n");
734 }
735 ++count;
736 ptr = NULL;
737 l = 0;
738 #ifdef ZLIB
739 while (!gzeof(fd)) {
740 str = gzgets(fd, buffer, LINELENGTH);
741 #else
742 while (!feof(fd)) {
743 str = fgets(buffer, LINELENGTH, fd);
744 #endif
745 if (!str) break;
746 if (reformat) {
747 printf("%s", str);
748 }
749 if (*str == ';') break;
750 if (*str == ' ') ++str; /* remove any initial blank space */
751 k = strlen(str);
752 if (k>=2 && str[k-1]=='\n' && str[k-2]=='\\' &&
753 (k==2 || (k>=3 && str[k-3]!='\\'))) {
754 k -=2;
755 str[k] = '\0';
756 }
757 ptr = realloc(ptr, l+k+2);
758 strcpy(ptr + l, str);
759 l += k;
760 }
761 if (ptr && *ptr) {
762 l -= 1;
763 if (l>=0 && ptr[l]=='\n') ptr[l] = '\0';
764 if (Context->zoom.width<min_zoomwidth) goto iter;
765 if (Context->zoom.height<min_zoomheight) goto iter;
766 str = (char *)Context->label;
767 Context->label = (struct TextLabel *)salloc(sizeof(TextLabel));
768 Context->label->text = ptr;
769 Context->label->lon = fx;
770 Context->label->lat = fy;
771 Context->label->color = color;
772 Context->label->position = position;
773 Context->label->next = (struct TextLabel *)str;
774 }
775 }
776 goto iter;
777 } else
778 if (*str == '#') {
779 num = 0;
780 str = getdata(fd);
781 if (!str) goto abort;
782 color = atoi(str);
783 if (reformat)
784 printf("\n#%d %d", count, color);
785 ++count;
786 } else
787 if (*str == ';') {
788 fx = fx0;
789 fy = fy0;
790 if (reformat) printf("\n;\n");
791 if (opencurves) goto iter;
792 } else {
793 fy = atof(str);
794 str = getdata(fd);
795 if (!str) goto abort;
796 fx = atof(str);
797 if (verbose) {
798 if (fx<txmin) txmin = fx;
799 if (fx>txmax) txmax = fx;
800 if (fy<tymin) tymin = fy;
801 if (fy>tymax) tymax = fy;
802 }
803 if (num == 0) {
804 fx0 = fx;
805 fy0 = fy;
806 }
807 if (reformat) {
808 if (num%4 == 0) printf("\n"); else printf(" ");
809 printf(coordformat, fy*cy+cdy, fx*cx+cdx);
810 }
811 ++num;
812 }
813
814 flag = run_flag & map->flags.vmfflags;
815 if (!flag) goto iter;
816 if ((flag&1) && !map->wintype) goto iter;
817 if (map->zoom.width<min_zoomwidth) goto iter;
818
819 theta = (fx - fxmin) / fdx;
820 phi = (fymax - fy) / fdy;
821 cc = uu = up = u;
822 if (cc<0) cc+=map->zoom.width;
823 if (cc>=map->zoom.width) cc-=map->zoom.width;
824 cc -= map->zoom.dx-1;
825
826 vp = v;
827 vv = v - map->zoom.dy;
828 vv1 = vv + 1;
829 if (vv1<0) vv1 = 0;
830 vv2 = vv;
831 if (vv2>=mapheight) vv2 = mapheight-1;
832
833 u = (int) (theta * (double) map->zoom.width);
834 v = (int) (phi * (double) map->zoom.height);
835 if (num>=2) {
836 diffu = abs(u-up);
837 if (diffu>map->zoom.width/2) {
838 if (u>up)
839 u -= map->zoom.width;
840 else
841 u += map->zoom.width;
842 diffu = abs(u-up);
843 }
844 diffv = abs(v-vp);
845 addumin = (u>up)? 1:-1;
846 addvmin = (v>vp)? 1:-1;
847 if (diffu>diffv) {
848 max = diffu ;
849 min = diffv;
850 addumax = addumin;
851 addvmax = 0;
852 } else {
853 max = diffv ;
854 min = diffu;
855 addumax = 0;
856 addvmax = addvmin;
857 }
858 sum = max/2-max;
859 for (m=0; m<max; m++) {
860 sum = sum + min;
861 if (sum>=max/2) {
862 sum -= max;
863 up += addumin;
864 vp += addvmin;
865 } else {
866 up += addumax;
867 vp += addvmax;
868 }
869 plotdata(up, vp, color);
870 }
871 }
872 goto iter;
873
874 endcurves:
875 filterdata();
876
877 if (map->flags.colorlevel==FULLCOLORS)
878 Context->xim = pixmap_image();
879 else
880 Context->bits = blacknwhite_image();
881 if ((map->flags.colorlevel<FULLCOLORS && Context->bits==NULL) ||
882 (map->flags.colorlevel==FULLCOLORS && Context->xim==NULL))
883 ret_value = 2;
884 if (ret_value < 0) ret_value = 0;
885
886 abort:
887 if (ret_value < 0) ret_value = 2;
888 #ifdef ZLIB
889 if (fd) gzclose(fd);
890 #else
891 if (fd) fclose(fd);
892 #endif
893 if (buffer) free(buffer);
894 if (grid) free(grid);
895 if (palette) free(palette);
896 if (verbose)
897 fprintf(stderr, "ymin = %9.3f ymax = %9.3f xmin = %9.3f xmax = %9.3f\n", tymin, tymax, txmin, txmax);
898 return ret_value;
899 }
900