static void add_leg(point *fr, point *to, const char *prefix, int flags) { leg *l; fr->order++; to->order++; l = osmalloc(ossizeof(leg)); l->fr = fr; l->to = to; if (prefix) l->prefix = find_prefix(prefix); else l->prefix = NULL; l->next = headleg.next; l->dir = 0; l->fDone = 0; l->broken = 0; l->flags = flags; headleg.next = l; }
static point * find_point(const img_point *pt) { point *p; for (p = headpoint.next; p != NULL; p = p->next) { if (pt->x == p->p.x && pt->y == p->p.y && pt->z == p->p.z) { return p; } } p = osmalloc(ossizeof(point)); p->p = *pt; p->stns = NULL; p->order = 0; p->dir = 0; p->fDone = 0; p->fBroken = 0; p->next = headpoint.next; headpoint.next = p; return p; }
img * img_open_write(const char *fnm, char *title_buf, bool fBinary) { time_t tm; img *pimg; fBinary = fBinary; if (fDirectory(fnm)) { img_errno = IMG_DIRECTORY; return NULL; } pimg = (img *)xosmalloc(ossizeof(img)); if (pimg == NULL) { img_errno = IMG_OUTOFMEMORY; return NULL; } pimg->buf_len = 257; pimg->label_buf = xosmalloc(pimg->buf_len); if (!pimg->label_buf) { osfree(pimg); img_errno = IMG_OUTOFMEMORY; return NULL; } pimg->fh = fopen(fnm, "wb"); if (!pimg->fh) { osfree(pimg->label_buf); osfree(pimg); img_errno = IMG_CANTOPENOUT; return NULL; } /* Output image file header */ fputs("Survex 3D Image File\n", pimg->fh); /* file identifier string */ if (img_output_version < 2) { pimg->version = 1; fputs("Bv0.01\n", pimg->fh); /* binary file format version number */ } else { pimg->version = (img_output_version > LATEST_IMG_VERSION) ? LATEST_IMG_VERSION : img_output_version; fprintf(pimg->fh, "v%d\n", pimg->version); /* file format version no. */ } fputsnl(title_buf, pimg->fh); tm = time(NULL); if (tm == (time_t)-1) { fputsnl(TIMENA, pimg->fh); } else { char date[256]; /* output current date and time in format specified */ strftime(date, 256, TIMEFMT, localtime(&tm)); fputsnl(date, pimg->fh); } #if 0 if (img_output_version >= 5) { static const unsigned char codelengths[32] = { 4, 8, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; fwrite(codelengths, 32, 1, pimg->fh); } #endif pimg->fRead = fFalse; /* writing to this file */ img_errno = IMG_NONE; /* for version >= 3 we use label_buf to store the prefix for reuse */ pimg->label_buf[0] = '\0'; pimg->label_len = 0; pimg->date1 = 0; pimg->date2 = 0; pimg->olddate1 = 0; pimg->olddate2 = 0; pimg->l = pimg->r = pimg->u = pimg->d = -1.0; pimg->n_legs = 0; pimg->length = 0.0; pimg->E = pimg->H = pimg->V = 0.0; /* Don't check for write errors now - let img_close() report them... */ return pimg; }
img * img_open_survey(const char *fnm, const char *survey) { img *pimg; size_t len; char buf[LITLEN(FILEID) + 9]; int ch; if (fDirectory(fnm)) { img_errno = IMG_DIRECTORY; return NULL; } pimg = (img *)xosmalloc(ossizeof(img)); if (pimg == NULL) { img_errno = IMG_OUTOFMEMORY; return NULL; } pimg->buf_len = 257; pimg->label_buf = xosmalloc(pimg->buf_len); if (!pimg->label_buf) { osfree(pimg); img_errno = IMG_OUTOFMEMORY; return NULL; } pimg->fh = fopenWithPthAndExt("", fnm, EXT_SVX_3D, "rb", &(pimg->filename_opened)); if (pimg->fh == NULL) { osfree(pimg->label_buf); osfree(pimg); img_errno = IMG_FILENOTFOUND; return NULL; } pimg->fRead = fTrue; /* reading from this file */ img_errno = IMG_NONE; pimg->flags = 0; /* for version >= 3 we use label_buf to store the prefix for reuse */ /* for VERSION_COMPASS_PLT, 0 value indicates we haven't * entered a survey yet */ /* for VERSION_CMAP_SHOT, we store the last station here * to detect whether we MOVE or LINE */ pimg->label_len = 0; pimg->label_buf[0] = '\0'; pimg->survey = NULL; pimg->survey_len = 0; pimg->separator = '.'; pimg->date1 = 0; pimg->date2 = 0; pimg->is_extended_elevation = 0; pimg->l = pimg->r = pimg->u = pimg->d = -1.0; pimg->title = pimg->datestamp = NULL; if (survey) { len = strlen(survey); if (len) { if (survey[len - 1] == '.') len--; if (len) { char *p; pimg->survey = xosmalloc(len + 2); if (!pimg->survey) { img_errno = IMG_OUTOFMEMORY; goto error; } memcpy(pimg->survey, survey, len); /* Set title to leaf survey name */ pimg->survey[len] = '\0'; p = strchr(pimg->survey, '.'); if (p) p++; else p = pimg->survey; pimg->title = my_strdup(p); if (!pimg->title) { img_errno = IMG_OUTOFMEMORY; goto error; } pimg->survey[len] = '.'; pimg->survey[len + 1] = '\0'; } } pimg->survey_len = len; } /* [VERSION_COMPASS_PLT, VERSION_CMAP_STATION, VERSION_CMAP_SHOT] pending * IMG_LINE or IMG_MOVE - both have 4 added. * [VERSION_SURVEX_POS] already skipped heading line, or there wasn't one * [version 0] not in the middle of a 'LINE' command * [version >= 3] not in the middle of turning a LINE into a MOVE */ pimg->pending = 0; len = strlen(fnm); if (has_ext(fnm, len, EXT_SVX_POS)) { pos_file: pimg->version = VERSION_SURVEX_POS; if (!pimg->survey) pimg->title = baseleaf_from_fnm(fnm); pimg->datestamp = my_strdup(TIMENA); if (!pimg->datestamp) { img_errno = IMG_OUTOFMEMORY; goto error; } pimg->start = 0; return pimg; } if (has_ext(fnm, len, EXT_PLT) || has_ext(fnm, len, EXT_PLF)) { long fpos; plt_file: pimg->version = VERSION_COMPASS_PLT; /* Spaces aren't legal in Compass station names, but dots are, so * use space as the level separator */ pimg->separator = ' '; pimg->start = 0; if (!pimg->survey) pimg->title = baseleaf_from_fnm(fnm); pimg->datestamp = my_strdup(TIMENA); if (!pimg->datestamp) { img_errno = IMG_OUTOFMEMORY; goto error; } while (1) { ch = getc(pimg->fh); switch (ch) { case '\x1a': fseek(pimg->fh, -1, SEEK_CUR); /* FALL THRU */ case EOF: pimg->start = ftell(pimg->fh); return pimg; case 'N': { char *line, *q; fpos = ftell(pimg->fh) - 1; if (!pimg->survey) { /* FIXME : if there's only one survey in the file, it'd be nice * to use its description as the title here... */ ungetc('N', pimg->fh); pimg->start = fpos; return pimg; } line = getline_alloc(pimg->fh); if (!line) { img_errno = IMG_OUTOFMEMORY; goto error; } len = 0; while (line[len] > 32) ++len; if (pimg->survey_len != len || memcmp(line, pimg->survey, len) != 0) { osfree(line); continue; } q = strchr(line + len, 'C'); if (q && q[1]) { osfree(pimg->title); pimg->title = my_strdup(q + 1); } else if (!pimg->title) { pimg->title = my_strdup(pimg->label); } osfree(line); if (!pimg->title) { img_errno = IMG_OUTOFMEMORY; goto error; } if (!pimg->start) pimg->start = fpos; fseek(pimg->fh, pimg->start, SEEK_SET); return pimg; } case 'M': case 'D': pimg->start = ftell(pimg->fh) - 1; break; } while (ch != '\n' && ch != '\r') { ch = getc(pimg->fh); } } } if (has_ext(fnm, len, EXT_XYZ)) { char *line; xyz_file: /* Spaces aren't legal in CMAP station names, but dots are, so * use space as the level separator. */ pimg->separator = ' '; line = getline_alloc(pimg->fh); if (!line) { img_errno = IMG_OUTOFMEMORY; goto error; } /* FIXME: reparse date? */ len = strlen(line); if (len > 59) line[59] = '\0'; if (len > 45) { pimg->datestamp = my_strdup(line + 45); } else { pimg->datestamp = my_strdup(TIMENA); } if (strncmp(line, " Cave Survey Data Processed by CMAP ", LITLEN(" Cave Survey Data Processed by CMAP ")) == 0) { len = 0; } else { if (len > 45) { line[45] = '\0'; len = 45; } while (len > 2 && line[len - 1] == ' ') --len; if (len > 2) { line[len] = '\0'; pimg->title = my_strdup(line + 2); } } if (len <= 2) pimg->title = baseleaf_from_fnm(fnm); osfree(line); if (!pimg->datestamp || !pimg->title) { img_errno = IMG_OUTOFMEMORY; goto error; } line = getline_alloc(pimg->fh); if (!line) { img_errno = IMG_OUTOFMEMORY; goto error; } if (line[0] != ' ' || (line[1] != 'S' && line[1] != 'O')) { img_errno = IMG_BADFORMAT; goto error; } if (line[1] == 'S') { pimg->version = VERSION_CMAP_STATION; } else { pimg->version = VERSION_CMAP_SHOT; } osfree(line); line = getline_alloc(pimg->fh); if (!line) { img_errno = IMG_OUTOFMEMORY; goto error; } if (line[0] != ' ' || line[1] != '-') { img_errno = IMG_BADFORMAT; goto error; } osfree(line); pimg->start = ftell(pimg->fh); return pimg; } if (fread(buf, LITLEN(FILEID) + 1, 1, pimg->fh) != 1 || memcmp(buf, FILEID"\n", LITLEN(FILEID) + 1) != 0) { if (fread(buf + LITLEN(FILEID) + 1, 8, 1, pimg->fh) == 1 && memcmp(buf, FILEID"\r\nv0.01\r\n", LITLEN(FILEID) + 9) == 0) { /* v0 3d file with DOS EOLs */ pimg->version = 0; goto v03d; } rewind(pimg->fh); if (buf[1] == ' ') { if (buf[0] == ' ') { /* Looks like a CMAP .xyz file ... */ goto xyz_file; } else if (strchr("ZSNF", buf[0])) { /* Looks like a Compass .plt file ... */ /* Almost certainly it'll start "Z " */ goto plt_file; } } if (buf[0] == '(') { /* Looks like a Survex .pos file ... */ goto pos_file; } img_errno = IMG_BADFORMAT; goto error; } /* check file format version */ ch = getc(pimg->fh); pimg->version = 0; if (tolower(ch) == 'b') { /* binary file iff B/b prefix */ pimg->version = 1; ch = getc(pimg->fh); } if (ch != 'v') { img_errno = IMG_BADFORMAT; goto error; } ch = getc(pimg->fh); if (ch == '0') { if (fread(buf, 4, 1, pimg->fh) != 1 || memcmp(buf, ".01\n", 4) != 0) { img_errno = IMG_BADFORMAT; goto error; } /* nothing special to do */ } else if (pimg->version == 0) { if (ch < '2' || ch > '0' + LATEST_IMG_VERSION || getc(pimg->fh) != '\n') { img_errno = IMG_TOONEW; goto error; } pimg->version = ch - '0'; } else { img_errno = IMG_BADFORMAT; goto error; } v03d: if (!pimg->title) pimg->title = getline_alloc(pimg->fh); else osfree(getline_alloc(pimg->fh)); pimg->datestamp = getline_alloc(pimg->fh); if (!pimg->title || !pimg->datestamp) { img_errno = IMG_OUTOFMEMORY; error: osfree(pimg->title); osfree(pimg->datestamp); fclose(pimg->fh); osfree(pimg); return NULL; } pimg->start = ftell(pimg->fh); len = strlen(pimg->title); if (len > 11 && strcmp(pimg->title + len - 11, " (extended)") == 0) { pimg->title[len - 11] = '\0'; pimg->is_extended_elevation = 1; } return pimg; }