static void mmo_read_CObjIcons(mmo_data_t *data) { #ifdef MMO_DBG const char *sobj = "CObjIcons"; #endif int i; DBG((sobj, ":-----------------------------------------------------\n")); DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", data->name, data->visible ? "yes" : "NO", data->objid)); gbfseek(fin, 6, SEEK_CUR); /* skip 6 unknown bytes */ while ((i = gbfgetuint32(fin))) { char *name; (void) gbfgetuint32(fin); (void) gbfgetuint32(fin); name = mmo_readstr(); // DBG((sobj, "bitmap(%d) = \"%s\"\n", i, name)); mmo_register_icon(i, name); xfree(name); gbfseek(fin, gbfgetuint32(fin), SEEK_CUR); } }
static void mmo_read_category(mmo_data_t *data) { int marker = gbfgetuint16(fin); if (marker & 0x8000) { mmo_data_t *tmp; gbfseek(fin, -2, SEEK_CUR); tmp = mmo_read_object(NULL); if (data) data->category = tmp->name; } }
static int lowranceusr_readstr(char *buf, const int maxlen, gbfile *file) { int org, len; org = len = gbfgetint32(file); if (len < 0) fatal(MYNAME ": Invalid item length (%d)!\n", len); else if (len) { if (len > maxlen) len = maxlen; (void) gbfread(buf, 1, len, file); if (org > maxlen) (void) gbfseek(file, org - maxlen, SEEK_CUR); } return len; }
static void mmo_read(void) { #ifdef MMO_DBG const char *sobj = "main"; #endif gbfile *fx; int i; /* copy file to memory stream (needed for seek-ops and piped commands) */ DBG(("main", "loading file \"%s\".\n", fin->name)); fx = gbfopen(NULL, "wb", MYNAME); gbfcopyfrom(fx, fin, 0x7FFFFFFF); gbfrewind(fx); gbfclose(fin); fin = fx; mmo_obj_ct = gbfgetuint16(fin); DBG((sobj, "number of objects = %d\n", mmo_obj_ct)); i = gbfgetuint16(fin); if (i != 0xFFFF) fatal(MYNAME ": Marker not equel to 0xFFFF!\n"); mmo_version = gbfgetuint16(fin); DBG((sobj, "version = 0x%02X\n", mmo_version)); mmo_filemark = 0xFFFF0000UL | be_read16(&mmo_version); DBG((sobj, "filemark = 0x%08X\n", mmo_filemark)); gbfseek(fin, -4, SEEK_CUR); while (! gbfeof(fin)) { /* main read loop */ (void) mmo_read_object(NULL); } #ifdef MMO_DBG printf("\n" MYNAME ":---------------------------------------\n"); printf(MYNAME ": EOF reached, nice!!!\n"); printf(MYNAME ": =======================================\n\n"); #endif }
static void humminbird_read_track_old(gbfile* fin) { humminbird_trk_header_old_t th; humminbird_trk_point_old_t* points; route_head* trk; waypoint* first_wpt; int i; int max_points = 0; gbint32 accum_east; gbint32 accum_north; double g_lat; const int file_len = 8048; char namebuf[TRK_NAME_LEN]; if (! gbfread(&th, 1, sizeof(th), fin)) fatal(MYNAME ": Unexpected end of file reading header!\n"); th.trk_num = be_read16(&th.trk_num); th.num_points = be_read16(&th.num_points); th.time = be_read32(&th.time); th.start_east = be_read32(&th.start_east); th.start_north = be_read32(&th.start_north); th.end_east = be_read32(&th.end_east); th.end_north = be_read32(&th.end_north); // These files are always 8048 bytes long. Note that that's the value // of the second 16-bit word in the signature. max_points = (file_len - (sizeof(th) + sizeof (gbuint32) + TRK_NAME_LEN)) / sizeof(humminbird_trk_point_old_t); if (th.num_points > max_points) fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); /* num_points is actually one too big, because it includes the value in the header. But we want the extra point at the end because the freak-value filter below looks at points[i+1] */ points = xcalloc(th.num_points, sizeof(humminbird_trk_point_old_t)); if (! gbfread(points, sizeof(humminbird_trk_point_old_t), th.num_points-1, fin)) fatal(MYNAME ": Unexpected end of file reading points!\n"); accum_east = th.start_east; accum_north = th.start_north; trk = route_head_alloc(); track_add_head(trk); /* The name is not in the header, but at the end of the file. (The last 20 bytes.) */ gbfseek(fin, file_len-TRK_NAME_LEN, SEEK_SET); gbfread(&namebuf, 1, TRK_NAME_LEN, fin); trk->rte_name = xstrndup(namebuf, sizeof(namebuf)); trk->rte_num = th.trk_num; /* We create one wpt for the info in the header */ first_wpt = waypt_new(); g_lat = gudermannian_i1924(accum_north); first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); first_wpt->longitude = accum_east/EAST_SCALE * 180.0; first_wpt->altitude = 0.0; track_add_wpt(trk, first_wpt); for(i=0 ; i<th.num_points-1 ; i++) { waypoint *wpt = waypt_new(); // gbint16 next_deltaeast, next_deltanorth; double guder; points[i].deltaeast = be_read16(&points[i].deltaeast); points[i].deltanorth = be_read16(&points[i].deltanorth); // I've commented this out, don't know if it happens in this // format. It happens in the newer version though. // /* Every once in a while the delta values are // 32767 followed by -32768. Filter that. */ // // next_deltaeast = be_read16(&points[i+1].deltaeast); // if (points[ i ].deltaeast == 32767 && // next_deltaeast == -32768) { // points[ i ].deltaeast = -1; // points[i+1].deltaeast = 0; /* BE 0 == LE 0 */ // } // next_deltanorth = be_read16(&points[i+1].deltanorth); // if (points[ i ].deltanorth == 32767 && // next_deltanorth == -32768) { // points[ i ].deltanorth = -1; // points[i+1].deltanorth = 0; // } // accum_east += points[i].deltaeast; accum_north += points[i].deltanorth; guder = gudermannian_i1924(accum_north); wpt->latitude = geocentric_to_geodetic_hwr(guder); wpt->longitude = accum_east/EAST_SCALE * 180.0; wpt->altitude = 0.0; if (i == th.num_points-2 && th.time != 0) { /* Last point. Add the date from the header. */ /* Unless it's zero. Sometimes happens, possibly if the gps didn't have a lock when the track was saved. */ wpt->creation_time = th.time; } track_add_wpt(trk, wpt); } xfree(points); }
static void mmo_read_CObjWaypoint(mmo_data_t *data) { #ifdef MMO_DBG const char *sobj = "CObjWaypoint"; #endif waypoint *wpt; time_t time; int rtelinks; mmo_data_t **rtelink = NULL; char *str; char buf[16]; int i, ux; DBG((sobj, ":-----------------------------------------------------\n")); DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", data->name, data->visible ? "yes" : "NO", data->objid)); wpt = waypt_new(); wpt->shortname = xstrdup(data->name); time = data->mtime; if (! time) time = data->ctime; if (time > 0) wpt->creation_time = time; wpt->latitude = gbfgetdbl(fin); wpt->longitude = gbfgetdbl(fin); DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); rtelinks = gbfgetuint16(fin); if (rtelinks > 0) { rtelink = xcalloc(sizeof(*rtelink), rtelinks); DBG((sobj, "rtelinks = %d\n", rtelinks)); for (i = 0; i < rtelinks; i++) { mmo_data_t *tmp; int objid; DBG((sobj, "read rtelink number %d\n", i + 1)); objid = gbfgetuint16(fin); gbfseek(fin, -2, SEEK_CUR); rtelink[i] = tmp = mmo_read_object(wpt); if ((objid < 0x8000) && (tmp != NULL) && (tmp->type == rtedata)) { route_head *rte = tmp->data; tmp->left--; route_add_wpt(rte, waypt_dupe(wpt)); DBG((sobj, "\"%s\" Added to route \"%s\"\n", wpt->shortname, rte->rte_name)); } } } str = mmo_readstr(); /* descr + url */ if (strncmp(str, "_FILE_ ", 7) == 0) { char *cx, *cend; cx = lrtrim(str + 7); cend = strchr(cx, '\n'); if (cend == NULL) cend = cx + strlen(cx); cx = lrtrim(xstrndup(cx, cend - cx)); if (*cx) wpt->url = cx; else xfree(cx); if (*cend++) wpt->notes = xstrdup(cend); if (wpt->url) DBG((sobj, "url = \"%s\"\n", wpt->url)); } else if (*str) wpt->notes = xstrdup(str); xfree(str); if (wpt->notes) DBG((sobj, "notes = \"%s\"\n", wpt->notes)); mmo_fillbuf(buf, 12, 1); i = le_read32(&buf[8]); /* icon */ if (i != -1) { char key[16]; char *name; snprintf(key, sizeof(key), "%d", i); if (avltree_find(icons, key, (void *)&name)) { wpt->icon_descr = xstrdup(name); wpt->wpt_flags.icon_descr_is_dynamic = 1; DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr)); } } wpt->proximity = le_read_float(&buf[4]); if (wpt->proximity) { wpt->wpt_flags.proximity = 1; DBG((sobj, "proximity = %f\n", wpt->proximity)); } str = mmo_readstr(); /* name on gps ??? option ??? */ if (*str) { wpt->description = wpt->shortname; wpt->shortname = str; DBG((sobj, "name on gps = %s\n", str)); } else xfree(str); ux = gbfgetuint32(fin); DBG((sobj, "proximity type = %d\n", ux)); if (rtelinks) { int i; for (i = 0; i < rtelinks; i++) { int j; route_head *rte = rtelink[i]->data; for (j = 0; j < rtelinks; j++) { if ((i != j) && (rtelink[i] == rtelink[j])) { rtelink[i]->loop = 1; break; } } rtelink[i]->done++; if ((rtelink[i]->left == 0) && (rtelink[i]->done == rte->rte_waypt_ct)) { if (mmo_version <= 0x11) mmo_end_of_route(rtelink[i]); } } } if (rtelink) { xfree(rtelink); waypt_free(wpt); data->data = NULL; } else waypt_add(wpt); }
static gbuint16 format_garmin_xt_rd_st_attrs(char *p_trk_name, gbuint8 *p_track_color) { int method = 0; gbuint16 trackbytes = 0, TrackPoints = 0; gbuint8 spam = 0; gbint32 TrackMaxLat = 0, TrackMaxLon = 0, TrackMinLat = 0, TrackMinLon = 0; char trk_name[30]=""; // TODO: SHIFT - can't test behaviour, do not have appropriate files //int ii; // get the option for the processing the track name if ( opt_trk_header ) { method = atoi(opt_trk_header); // if method is out of range set to default if ((method < 0) || (method > 1)) { method = 0; } } // set to RED if not specified *p_track_color=9; trackbytes = gbfgetuint16(fin); TrackPoints = gbfgetuint16(fin); switch (method) { case 1: break; // IGNORE /* TODO: SHIFT - can't test behaviour, do not have appropriate files case 2: { // SHIFTED method spam = gbfgetc(fin); gbfread(&trk_name, 30, DATABLOCKSIZE, fin); gbfseek(fin, -1, SEEK_CUR); for (ii = 0; ii<29; ii++) { trk_name[ii] = (trk_name[ii] >> 2) + ( trk_name[ii+1] % 4 ) * 64; } } break; */ default: { // NORMAL spam = gbfgetc(fin); gbfread(&trk_name, 30, DATABLOCKSIZE, fin); gbfseek(fin, -1, SEEK_CUR); } break; } spam = gbfgetc(fin); gbfread(&TrackMaxLat, 3, DATABLOCKSIZE, fin); gbfread(&spam, 1, DATABLOCKSIZE, fin); gbfread(&TrackMaxLon, 3, DATABLOCKSIZE, fin); gbfread(&spam, 1, DATABLOCKSIZE, fin); gbfread(&TrackMinLat, 3, DATABLOCKSIZE, fin); gbfread(&spam, 1, DATABLOCKSIZE, fin); gbfread(&TrackMinLon, 3, DATABLOCKSIZE, fin); gbfread(p_track_color, 1, DATABLOCKSIZE, fin); gbfread(&spam, 1, DATABLOCKSIZE, fin); strcpy( p_trk_name, trk_name ); return trackbytes; }
static void format_garmin_xt_proc_atrk(void) { gbuint16 block=0, uu=0; gbuint32 Lat=0, Lon=0; gbuint32 Tim=0; double LatF = 0, LonF = 0, AltF = 0; waypoint *wpt; int method = 0; unsigned char buf[3]; gbint32 num_trackpoints; // get the option for the processing the track name if ( opt_trk_header ) { method = atoi(opt_trk_header); } if (! track) { track = route_head_alloc(); // header option was not set to ignore if ( method !=1 ) { track->rte_name = xstrdup("ATRK XT"); } track_add_head(track); } // We think the word at offset 0xc is the trackpoint count. gbfseek(fin, 12, SEEK_SET); num_trackpoints = gbfgetuint32(fin); while (num_trackpoints--) { block = gbfgetuint16(fin); if (block != 0x0c) break; gbfread(&buf, 3, DATABLOCKSIZE, fin); //1. Lat Lat = buf[0] | (buf[1] << 8) | (buf[2] << 16); gbfread(&buf, 3, DATABLOCKSIZE, fin); //2. Lon Lon = buf[0] | (buf[1] << 8) | (buf[2] << 16); uu = gbfgetuint16(fin); Tim = gbfgetuint32(fin); Tim += 631065600; // adjustment to UnixTime LatF = Lat; if (LatF>8388608) {LatF -= 16777216;}; LonF = Lon; if (LonF>8388608) {LonF -= 16777216;}; AltF = (double)uu * GARMIN_XT_ELE - 1500; //create new waypoint wpt = waypt_new(); //populate wpt; wpt->latitude = LatF*180/16777216; /* Degrees */ wpt->longitude = LonF*360/16777216; /* Degrees */ wpt->altitude = AltF; /* Meters. */ wpt->creation_time = Tim; /* Unix Time adjusted to Garmin time */ track_add_wpt(track, wpt); } }
/* * Main Function to process Saved tracks file */ static void format_garmin_xt_proc_strk(void) { int Count = 0; // Used to obtain number of read bytes int NumberOfTracks = 0, TracksCompleted = 0; // Number of tracks in the file and number of processed tracks gbuint16 trackbytes = 0; // Bytes in track gbuint8 TrackBlock[STRK_BLOCK_SIZE]; // File Block gbuint8 ii; // temp variable double Lat = 0, Lon = 0; // wpt data double PrevLat = 0, PrevLon = 0, PrevEle = 0; // wpt data gbuint32 Time = 0, PrevTime =0; // wpt data int FirstCoo; gbuint8 trk_color = 0xff; // Skip 12 bytes from the BOF gbfseek(fin, 12, SEEK_SET); // read # of tracks NumberOfTracks = gbfgetuint16(fin); // Skip 2 bytes gbfseek(fin, 2, SEEK_CUR); // Process all tracks one by one while ((TracksCompleted < NumberOfTracks) && (!gbfeof( fin ) ) ) { route_head *tmp_track; waypoint *wpt; char *trk_name; trk_name = xmalloc(30); // Generate Track Header trackbytes = format_garmin_xt_rd_st_attrs(trk_name, &trk_color) - 50; tmp_track = route_head_alloc(); // update track color tmp_track->line_color.bbggrr = colors[trk_color]; tmp_track->line_color.opacity = 255; // update track name tmp_track->rte_name = trk_name; track_add_head(tmp_track); // This is the 1st coordinate of the track FirstCoo = TRUE; while (trackbytes>0) { if (trackbytes>=STRK_BLOCK_SIZE) { Count = gbfread(&TrackBlock, DATABLOCKSIZE, STRK_BLOCK_SIZE, fin); trackbytes -= STRK_BLOCK_SIZE; } else { Count = gbfread(&TrackBlock, DATABLOCKSIZE, trackbytes, fin); trackbytes = 0; } // decrypt loaded track block (Count - size of loaded TrackBlock) format_garmin_xt_decrypt_trk_blk(Count, TrackBlock); // process each track point in the loaded TrackBlock for (ii=1; ii <= ((Count-1) / 12); ii++) { // decompose loaded track block part (track point) format_garmin_xt_decomp_trk_blk(ii, TrackBlock, &PrevEle, &Lat, &Lon, &Time); // Add point to the track if not the first point if (!FirstCoo) { //create new waypoint wpt = waypt_new(); //populate wpt; wpt->latitude = PrevLat; /* Degrees */ wpt->longitude = PrevLon; /* Degrees */ wpt->altitude = PrevEle; /* Meters. */ wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ // add way point to the track track_add_wpt(tmp_track, wpt); } else { FirstCoo = FALSE; } PrevLat = Lat; PrevLon = Lon; PrevTime = Time; } } // decompose elevation for the last point if (Count > 12) { Count--; } format_garmin_xt_decomp_last_ele(Count, &PrevEle, TrackBlock); //create new waypoint wpt = waypt_new(); //populate wpt; wpt->latitude = PrevLat; /* Degrees */ wpt->longitude = PrevLon; /* Degrees */ wpt->altitude = PrevEle; /* Meters. */ wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ // add way point to the track track_add_wpt(tmp_track, wpt); // update completed tracks counter TracksCompleted++; } }