/* * Usage: rez2else [-rezfile name] [-output name] [-format type] * [-continents list] [-types list] * [-ascii type] [-verbose] [-silent] * where format type is one of NONE (default), TEXT, JPD * and TXT ascii type is one of DXDY (default), INT, REAL * */ #include #include #include #include #include #include #if __BYTE_ORDER == __BIG_ENDIAN #define WORDS_BIGENDIAN #endif #ifdef ZLIB #include #endif #define BIT32 int #define BIT16 short #ifdef WORDS_BIGENDIAN void bitflip (BIT32 *x) { BIT32 y=0; y |= 0xFF000000 & ((0x000000FF & *x) << 24); y |= 0x00FF0000 & ((0x0000FF00 & *x) << 8); y |= 0x0000FF00 & ((0x00FF0000 & *x) >> 8); y |= 0x000000FF & ((0xFF000000 & *x) >> 24); *x = y; } #endif /* WORDS_BIGENDIAN */ #define DEFAULT_REZ_FILE "/usr/share/rmap/CIA_map.rez" #define MAXSTROKES 6000000 /* conservative upper estimate */ #define REZ_TOTALSEG 31844 /* number of segments in WDB is really 31845, but one river showing up in Uganda is faulty and must be deleted ! */ #define SHORTFLAG 0x4000 #define REZ_MAGIC 0x86460346 #define JPD_MAGIC "!JPD1.0\n" #define DEBUG 1 enum { AFRICA=0, ASIA, EUROPE, NAMERICA, SAMERICA }; enum { BDY=0, PBY, RIV, CIL }; enum {NONE=0, TEXT, JPD }; enum {DX_DY=0, INT, REAL}; struct header { BIT32 magic; BIT32 segment_index_address; BIT32 segment_index_count; }; struct segment_index { BIT32 maxlat; BIT32 minlat; BIT32 maxlong; BIT32 minlong; BIT32 segment_address; BIT32 continent; BIT32 category; BIT32 type; }; struct segment_header { BIT32 orgx; BIT32 orgy; BIT32 nstrokes; }; struct stroke { BIT32 dx; BIT32 dy; }; char *cont_name[] = { "Africa", "Asia", "Europe", "North America", "South America" }; char *type_name[] = { "int", "nat", "riv", "cil" }; int jpd2rez_type_code[4] = { 2, 0, 1, 3 }; void fpr2(FILE * f, BIT32 n) { fprintf(f, "%c%c", n&255, (n>>8)&255); } void fpr3(FILE * f, BIT32 n) { fprintf(f, "%c%c%c", n&255, (n>>8)&255, (n>>16)&255); } void fpr4(FILE * f, BIT32 n) { fprintf(f, "%c%c%c%c", n&255, (n>>8)&255, (n>>16)&255, n>>24); } void usage() { fprintf(stderr, "Usage: rez2else [-rezfile name] [-output name] [-format type]\n" " [-continents list] [-types list]\n" " [-ascii type] [-verbose] [-silent]\n" "where format type is one of NONE (default), TEXT, JPD,\n" "and TEXT ascii type is one of DXDY (default), INT, REAL\n\n"); exit(-1); } int main (argc, argv) int argc; char **argv; { #ifdef ZLIB gzFile *ff; #else int ff; #endif FILE *fd; char *rez_file = NULL; char *list_cont=NULL, *list_types=NULL; int u, v, up, vp, w, i, j, k; int dm, quot, xp, yp, xt, yt, s; int format, numseg, rejected, verbose; int rez_length, jpd_length, rez_total_strokes; int maxwidth, maxheight; int text_output_type, count, addr; char magic[20], dx[MAXSTROKES], dy[MAXSTROKES]; /* +10 just to be safe */ int rez_nstrokes[REZ_TOTALSEG+10], rez_orgx[REZ_TOTALSEG+10], rez_orgy[REZ_TOTALSEG+10]; int jpd_count[REZ_TOTALSEG+10]; char * output; struct segment_index * segment_index_data = NULL; struct header header_data; struct segment_header segment_header_data; struct stroke stroke_data; #define U -1 char targets[4][20]; int jpd_encod[4][16] = { { U, 0, 1, 2, U, U, U, U, U, U, U, U, U, U, U, U }, /* int 2^2 */ { U, 3, U, 4, U, U, U, U, U, U, U, U, U, U, U, U }, /* nat 2^0 */ { U, 5, 6, 7, 8, 9, 10, 11, 12, U, 13, 14, U, 15, U, U }, /* riv 2^1 */ { U, 16, 17, 18, 19, U, 20, 21, 22, 23, 24, U, U, 25, 26, 27 }/* cil 2^3 */ }; int jpd_min[4] = { 0, 3, 5, 16 }; int jpd_max[4] = { 2, 4, 15, 27 }; int jpd_seg_count[5][28]; format = TEXT; text_output_type = DX_DY; verbose = 1; for (j=1; jmaxwidth) maxwidth = xp; if (yp>maxheight) maxheight = yp; } count = 0; jpd_count[0] = 0; for (i=0; idm) dm = stroke_data.dy; if (-stroke_data.dy>dm) dm = -stroke_data.dy; if (dm>8000) { if (stroke_data.dx<-650000) stroke_data.dx +=1296000; else if (stroke_data.dx>650000) stroke_data.dx -=1296000; ++quot; if (quot==1) goto retry; fprintf(stderr, "Strange values dx = %d , dy = %d\n", stroke_data.dx, stroke_data.dy); } if (dm<128) { dx[count] = (stroke_data.dx)&255; dy[count] = (stroke_data.dy)&255; ++count; } else { quot = 1+(dm/128); xp = yp = 0; for (s=1; s<=quot; s++) { xt = xp; yt = yp; xp = (s*stroke_data.dx)/quot; yp = (s*stroke_data.dy)/quot; dx[count] = (xp-xt)&255; dy[count] = (yp-yt)&255; ++count; } } } if (verbose && (i%500)==499) fprintf(stderr, "Read segments %d -- %d from REZ file\n", i-499, i); jpd_count[i+1] = count; if (segment_header_data.nstrokes>rez_length) rez_length = segment_header_data.nstrokes; xt = jpd_count[i+1]-jpd_count[i]; if (xt>jpd_length) jpd_length = xt; } fprintf(stderr, "Scanned %d REZ segments, %d rejected\n\n", numseg, rejected); fprintf(stderr, "Max length of REZ segments %d\n", rez_length); fprintf(stderr, "Max width of REZ segments %d\n", maxwidth); fprintf(stderr, "Max height of REZ segments %d\n", maxheight); fprintf(stderr, "Total number of REZ segment strokes %d\n\n", rez_total_strokes); fprintf(stderr, "Max length of JPD segments after refragmentation %d\n", jpd_length); fprintf(stderr, "Total number of JPD segment strokes %d\n\n", count); if (format == JPD) { bzero(magic, 16); strcpy(magic, JPD_MAGIC); /* Write 16 bytes = magic(12) + max length of segments(4) */ for (u=0; u<12; u++) fprintf(fd, "%c", magic[u]); fpr4(fd, jpd_length); /* Write segment counts for the 5*28=140 continents * types * 560 bytes in total */ count = 0; for (u=0; u<5; u++) for (v=0; v<4; v++) { up = 1< %s (%s %d)\nJPD address: %d\n", k, cont_name[u], type_name[v], w-jpd_min[v], addr); ++k; if (text_output_type == REAL) { fprintf(fd,"Box [%4.6f %4.6f] [%3.6f %3.6f]\nStrokes %d\n", segment_index_data[i].minlong/3600.0, segment_index_data[i].maxlong/3600.0, segment_index_data[i].minlat/3600.0, segment_index_data[i].maxlat/3600.0, jpd_count[i+1]-jpd_count[i]); fprintf(fd, "Origin %4.6f %3.6f\n", rez_orgx[i]/3600.0, rez_orgy[i]/3600.0); } else { fprintf(fd, "Box [%d %d] [%d %d]\nStrokes %d\n", segment_index_data[i].minlong, segment_index_data[i].maxlong, segment_index_data[i].minlat, segment_index_data[i].maxlat, jpd_count[i+1]-jpd_count[i]); fprintf(fd, "Origin %d %d\n", rez_orgx[i], rez_orgy[i]); } xp = rez_orgx[i]; yp = rez_orgy[i]; for (j=jpd_count[i]; j