/* rmap - vector based global map generating program
* Copyright (C) 2000 Reza Naima <reza@reza.net>
*
* http://www.reza.net/rmap/
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SHORTFLAG 0x4000
#define CBD_MAGIC 0x20770002
#define HEADER_MAGIC 0x86460346 //random number
#define BIT32 int
#define BIT16 short
// THE INPUT PARAMS MUST BE IN THE FORM OF
// generate Map/*.Map/*.cbd
// for the proper continent and type mappings
// (i need to pull it fromt he filenames, and
// rather than parsing it, i just pull it from
// various spots)
//
struct cbdhead
{
BIT32 magic; /* Magic number */
BIT32 dictaddr; /* Offset of segment dictionary in file */
BIT32 segcount; /* Number of segments in file */
BIT32 segsize; /* Size of segment dictionary */
BIT32 segmax; /* Size of largest segment's strokes, /2 */
BIT32 fill[(40 / sizeof (BIT32)) - 5]; /* Filler */
};
struct myheader
{
BIT32 magic;
BIT32 segment_index_address;
BIT32 segment_index_count;
};
int main (int argc, char **argv) {
int cat, continent;
char string[4];
int Ofile;
int my_seg_idx = 0;
int my_segment_total = 0;
int my_stroke_count = 0;
int ret;
int Ifile, segcount, idx, idy, segbufsize, olt, oln, j, k,
jstroke, iseg;
char filename[20][80];
char file[30];
int filenum;
BIT32 i32;
BIT16 *segbuf;
struct my_segment_index
{
BIT32 maxlat;
BIT32 minlat;
BIT32 maxlong;
BIT32 minlong;
BIT32 segment_address;
BIT32 continent;
BIT32 catagory;
BIT32 type;
}
seg_idx;
struct my_segment_header
{
BIT32 orgx;
BIT32 orgy;
BIT32 nstrokes;
}
seg_head;
struct my_stroke
{
BIT32 dx;
BIT32 dy;
}
stroke;
struct segdict
{
BIT32 segid;
BIT32 maxlat, minlat, maxlong, minlong;
BIT32 absaddr;
BIT16 nbytes;
BIT16 rank;
}
*sd, *sdbuf;
struct segment
{
BIT32 orgx, orgy;
BIT32 id;
BIT16 nstrokes;
BIT16 dummy;
} sb;
struct cbdhead header;
struct myheader my_top;
// create a file to output my data to
Ofile = creat ("output.rez", S_IRWXU);
if (Ofile == -1 ) {
printf ("couln't open output file\n");
exit (2);
}
if (Ofile <3 ) {
printf("opened fh= %d\n", Ofile);
exit(-1);
}
// initialize some shitz
//itterate through this twice.. once to create list of indexes,
//and a second time to generate the data
//determine the number of segments
for (filenum = 1; filenum < argc; filenum++) {
strcpy (filename[filenum], argv[filenum]);
Ifile = open (filename[filenum], O_RDONLY, 0);
if (Ifile == -1) {
printf("unable to open file %s", filename[filenum]);
continue;
}
printf ("Reading %s\n", filename[filenum]);
read (Ifile, &header, sizeof header);
if (header.magic != CBD_MAGIC) {
printf ("File has bad magic number %d != %d\n", header.magic, CBD_MAGIC);
exit (2);
}
my_seg_idx += header.segcount;
close (Ifile);
}
printf ("determined that there are %d segments\n", my_seg_idx);
my_segment_total = my_seg_idx;
my_seg_idx = 0;
my_top.magic = HEADER_MAGIC;
my_top.segment_index_address = sizeof my_top;
my_top.segment_index_count = my_segment_total;
ret = write (Ofile, &my_top, sizeof (my_top));
if (ret != sizeof (my_top)) {
printf ("error 1\n");
exit (2);
}
//now generate a list of the segment_indexs
printf("Writing Segment Indexes ");
for (filenum = 1; filenum < argc; filenum++) {
continent=0; cat=0; //init
strcpy (filename[filenum], argv[filenum]);
strcpy (file, argv[filenum]);
Ifile = open (filename[filenum], O_RDONLY, 0);
if (Ifile == -1) continue; // problem?
// determine the continent and catagory id
bzero(string,3);
strncpy(string, file+4, 3);
string[3]='\0';
if (!strcmp(string, "afr")) continent=1;
if (!strcmp(string, "asi")) continent=2;
if (!strcmp(string, "eur")) continent=3;
if (!strcmp(string, "nam")) continent=4;
if (!strcmp(string, "sam")) continent=5;
printf("Country -> %s -> %d\n", string, continent);
bzero(string,3);
strncpy(string, file+(strlen(file)-7), 3);
string[3]='\0';
if (!strcmp(string, "pby")) cat=1;
if (!strcmp(string, "riv")) cat=2;
if (!strcmp(string, "bdy")) cat=3;
if (!strcmp(string, "cil")) cat=4;
printf("Type -> %s -> %d\n", string, cat);
printf ("Reading %s\n", filename[filenum]);
read (Ifile, &header, sizeof header);
/* allocate space for the segment buffer */
segbufsize = 2 * header.segmax;
segbuf = (BIT16 *) malloc (50 + segbufsize);
sd = sdbuf = (struct segdict *) malloc (100 + header.segsize);
/* Go read in the segment dictionary (it's at the end of the file) */
lseek (Ifile, header.dictaddr, L_SET);
j = read (Ifile, sd + 1, header.segsize);
if (j < header.segsize) {
fprintf (stderr, "File segment dictionary expecting %d got %d\n",
header.segsize, j);
exit (2);
}
segcount = header.segcount;
for (iseg = 1; iseg <= segcount; iseg++) {
sd++; /* next one */
//determine the country and
// the catagory using a crude method
my_seg_idx++;
seg_idx.maxlat = sd->maxlat;
seg_idx.minlat = sd->minlat;
seg_idx.maxlong = sd->maxlong;
seg_idx.minlong = sd->minlong;
seg_idx.segment_address = sizeof (my_top) //hader
+ sizeof (seg_idx) * my_segment_total //the segment index block
+ sizeof (seg_head) * (my_seg_idx - 1) //the number of past segment headers
+ sizeof (stroke) * my_stroke_count;
seg_idx.continent = 0x00000001 << continent-1; // aka the file num
seg_idx.catagory = 0x00000001 << cat-1; // should break this up really..
seg_idx.type = sd->rank;
if (my_seg_idx < 10)
printf("my_seg_idx = %d, addr = %d\n", my_seg_idx, seg_idx.segment_address);
lseek (Ifile, sd->absaddr, L_SET);
read (Ifile, &sb, sizeof sb);
my_stroke_count += sb.nstrokes;
ret = write (Ofile, &seg_idx, sizeof (seg_idx));
if (ret != sizeof (seg_idx)) {
printf ("error 1\n");
exit (2);
}
//printf ("wrote segment_index %d (strokes = %d)\n", my_seg_idx, my_stroke_count);
//if (!iseg%(my_segment_total/20))
// printf(".");
}
printf("\n");
close (Ifile);
free (sdbuf);
free (segbuf);
}
//another loop!
for (filenum = 1; filenum < argc; filenum++) {
strcpy (filename[filenum], argv[filenum]);
if ((Ifile = open (filename[filenum], O_RDONLY, 0)) == -1)
continue;
printf ("Reading %s\n", filename[filenum]);
read (Ifile, &header, sizeof header);
/* allocate space for the segment buffer */
segbufsize = 2 * header.segmax;
segbuf = (BIT16 *) malloc (50 + segbufsize);
sd = sdbuf = (struct segdict *) malloc (100 + header.segsize);
/* Go read in the segment dictionary (it's at the end of the file) */
lseek (Ifile, header.dictaddr, L_SET);
j = read (Ifile, sd + 1, header.segsize);
if (j < header.segsize) {
fprintf (stderr, "File segment dictionary expecting %d got %d\n",
header.segsize, j);
exit (2);
}
segcount = header.segcount;
for (iseg = 1; iseg <= segcount; iseg++) {
sd++; /* next one */
lseek (Ifile, sd->absaddr, L_SET);
read (Ifile, &sb, sizeof sb);
if (sd->nbytes > segbufsize) {
fprintf (stderr,
"Segment %d needs %d bytes; buffer limit is %d.\n",
iseg, sd->nbytes, segbufsize);
exit (2);
}
read (Ifile, segbuf, sd->nbytes);
k = 0;
oln = sb.orgx;
olt = sb.orgy;
seg_head.orgx = sb.orgx;
seg_head.orgy = sb.orgy;
seg_head.nstrokes = sb.nstrokes;
//ret = lseek(Ofile, 0, SEEK_CUR);
//printf("the offset is at %d\n", ret);
ret = write (Ofile, &seg_head, sizeof (seg_head));
if (ret != sizeof (seg_head)) {
printf ("error 1\n");
exit (2);
}
//printf ("writing stroke header - total strokes = %d\n", sb.nstrokes);
printf(".");
fflush(stdout);
for (jstroke = 1; jstroke <= sb.nstrokes; jstroke++) {
if (segbuf[k] & SHORTFLAG) {
/* Flag bit on: unpack a 16-bit field into dx and dy */
i32 = segbuf[k++];
if (i32 > 0)
i32 &= ~SHORTFLAG; /* turn off short flag bits */
idy = i32 & 0x000000FF;
if (idy & 0x00000080)
idy |= ~0x000000FF; /* extend sign */
idx = i32 >> 8;
if (idx & 0x00000080)
idx |= ~0x000000BF; /* extend sign */
} else {
/* Flag bit off: take dx and dy from 32-bit fields. */
idx = segbuf[k++];
if (idx < 0)
idx |= SHORTFLAG;
idx = (idx << 16) | (unsigned short) segbuf[k];
k++;
idy = segbuf[k];
k++;
if (idy < 0)
idy |= SHORTFLAG;
idy = (idy << 16) | segbuf[k];
k++;
}
stroke.dx = idx;
stroke.dy = idy;
ret = write (Ofile, &stroke, sizeof (stroke));
if (ret != sizeof (stroke)) {
printf ("error 1\n");
exit (2);
}
}
}
printf("\n");
close (Ifile);
free (sdbuf);
free (segbuf);
}
close (Ofile);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1