From 916d5d7ac9c107205dcfe27d671f71285f7ec1c1 Mon Sep 17 00:00:00 2001 From: Maximilian Seesslen Date: Fri, 5 Jul 2013 19:29:33 +0200 Subject: [PATCH] added trivial support for DEM subfile --- Makefile | 2 +- garmin_struct.h | 14 +++++++++++++- gimglib.c | 9 +++++---- gimglib.h | 9 +++++++-- sf_dem.c | 26 ++++++++++++++++++++++++++ sf_gmp.c | 2 +- util.c | 3 ++- 7 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 sf_dem.c diff --git a/Makefile b/Makefile index c23faeb..7b4cee3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -GIMGLIB_SOURCES = gimglib.c util.c sf_typ.c sf_mps.c sf_tre.c sf_rgn.c sf_lbl.c sf_net.c sf_nod.c sf_gmp.c +GIMGLIB_SOURCES = gimglib.c util.c sf_typ.c sf_mps.c sf_tre.c sf_rgn.c sf_lbl.c sf_net.c sf_nod.c sf_dem.c sf_gmp.c GIMGLIB_OBJS = $(GIMGLIB_SOURCES:.c=.o) all: gimginfo gimgfixcmd gimgxor gimgunlock gimgch gimgextract cmdc diff --git a/garmin_struct.h b/garmin_struct.h index d5a0e3e..d0cc6db 100644 --- a/garmin_struct.h +++ b/garmin_struct.h @@ -374,6 +374,18 @@ struct garmin_nod uint32_t unknown_07b; // 0x7b } PACK_STRUCT ; +struct garmin_dem +{ + struct garmin_subfile comm; + uint32_t flags; // 0x015 + uint16_t zoom_levels; // 0x019 + uint32_t reserved0; // 0x01B + uint16_t record_size; // 0x01F + uint32_t points_to_block3; // 0x021 + // This may not be present on every map: + uint32_t reserved2; // 0x025 +} PACK_STRUCT ; + struct garmin_gmp { struct garmin_subfile comm; uint32_t unknown_015; @@ -382,7 +394,7 @@ struct garmin_gmp { uint32_t lbl_offset; uint32_t net_offset; uint32_t nod_offset; - uint32_t unknown_02d; + uint32_t dem_offset; } PACK_STRUCT ; /* http://ati.land.cz/ */ diff --git a/gimglib.c b/gimglib.c index 0e12f86..156fd0f 100644 --- a/gimglib.c +++ b/gimglib.c @@ -155,7 +155,7 @@ static int parse_img (struct gimg_struct *img) int k; //vlog("fat%d: gmp 0x%x+0x%x\n", i, fat->blocks[0] * block_size, fat->size); - for (k = 0; k < 5; k ++) { // k matches ST_TRE to ST_NOD + for (k = 0; k < NUMBER_SUBFILES; k ++) { // k matches ST_TRE to ST_NOD uint32_t abs_offset, rel_offset = *(&gmp->tre_offset + k); if (rel_offset == 0) { //vlog("GMP has no %s\n", get_subtype_name(k)); @@ -266,7 +266,7 @@ static int parse_img (struct gimg_struct *img) orphans_tail = orphans_tail->orphan_next = subfile; } else { switch (subfile->typeid) { - case ST_TRE: case ST_RGN: case ST_LBL: case ST_NET: case ST_NOD: + case ST_TRE: case ST_RGN: case ST_LBL: case ST_NET: case ST_NOD: case ST_DEM: if (submap->subfiles[subfile->typeid]) fprintf(stderr, "Warning: file %s has duplicate %s\n", subfile->name, subfile->type); submap->subfiles[subfile->typeid] = subfile; @@ -368,7 +368,7 @@ void dump_img (struct gimg_struct *img) submap->name, submap->gmp->offset, submap->gmp->size); - for (k = 0; k <= ST_NOD; k ++) { + for (k = 0; k < NUMBER_SUBFILES; k ++) { if (submap->subfiles[k]) printf(" %s abs=0x%x rel=0x%x\n", get_subtype_name(k), @@ -380,7 +380,7 @@ void dump_img (struct gimg_struct *img) } else { // OF int k; printf("%s: OF\n", submap->name); - for (k = 0; k <= ST_NOD; k ++) { + for (k = 0; k < NUMBER_SUBFILES; k ++) { if (submap->subfiles[k]) printf(" %s off=0x%x size=0x%x\n", get_subtype_name(k), @@ -425,6 +425,7 @@ void dump_subfile (struct gimg_struct *img, const char *subfile_name) case ST_LBL: dump_lbl(subfile); break; case ST_NET: dump_net(subfile); break; case ST_NOD: dump_nod(subfile); break; + case ST_DEM: dump_dem(subfile); break; case ST_TYP: dump_typ(subfile); break; case ST_MPS: dump_mps(subfile); break; case ST_GMP: dump_gmp(subfile); break; diff --git a/gimglib.h b/gimglib.h index f68cb5e..92377d2 100644 --- a/gimglib.h +++ b/gimglib.h @@ -28,9 +28,10 @@ #endif #include "garmin_struct.h" +#define NUMBER_SUBFILES 6 enum subtype { - ST_TRE, ST_RGN, ST_LBL, ST_NET, ST_NOD, // these 5 should match the GMP header + ST_TRE, ST_RGN, ST_LBL, ST_NET, ST_NOD, ST_DEM, // these 6 should match the GMP header ST_SRT, ST_GMP, ST_TYP, ST_MDR, ST_TRF, ST_MPS, ST_QSI, @@ -55,13 +56,14 @@ struct subfile_struct { struct submap_struct { char name[9]; union { - struct subfile_struct *subfiles[5]; + struct subfile_struct *subfiles[NUMBER_SUBFILES]; struct { struct subfile_struct *tre; // always set. struct subfile_struct *rgn; struct subfile_struct *lbl; struct subfile_struct *net; struct subfile_struct *nod; + struct subfile_struct *dem; }; }; struct subfile_struct *srt; @@ -121,6 +123,9 @@ void dump_net (struct subfile_struct *sf); /* sf_nod.c */ void dump_nod (struct subfile_struct *sf); +/* sf_dem.c */ +void dump_dem (struct subfile_struct *sf); + /* sf_gmp.c */ void dump_gmp (struct subfile_struct *sf); diff --git a/sf_dem.c b/sf_dem.c new file mode 100644 index 0000000..3b4bea7 --- /dev/null +++ b/sf_dem.c @@ -0,0 +1,26 @@ +#include "gimglib.h" + +void dump_dem (struct subfile_struct *sf) +{ + struct garmin_dem *header = (struct garmin_gmp *)sf->header; + + assert(sf->typeid == ST_DEM); + + dump_comm(sf->header); + + printf("=== DEM HEADER ===\n"); + printf("Flags: 0x%x\n", header->flags); + printf("Zoom Levels: 0x%x\n", header->zoom_levels); + printf("Reserved: 0x%x\n", header->reserved0); + printf("Record Size: 0x%x\n", header->record_size); + printf("Points to Block 3: 0x%x\n", header->points_to_block3); + printf("Reserved: 0x%x\n", header->reserved2); + + if (header->comm.hlen > sizeof(struct garmin_gmp)) + printf("from 0x%lx to 0x%x (0x%lx bytes): %s\n", + sizeof(struct garmin_gmp), header->comm.hlen - 1, + header->comm.hlen - sizeof(struct garmin_gmp), + dump_unknown_bytes((uint8_t *)header + sizeof(struct garmin_gmp), header->comm.hlen - sizeof(struct garmin_gmp))); + + return; +} diff --git a/sf_gmp.c b/sf_gmp.c index 8dc9992..82501f8 100644 --- a/sf_gmp.c +++ b/sf_gmp.c @@ -15,7 +15,7 @@ void dump_gmp (struct subfile_struct *sf) printf("LBL Offset: 0x%x\n", header->lbl_offset); printf("NET Offset: 0x%x\n", header->net_offset); printf("NOD Offset: 0x%x\n", header->nod_offset); - printf("unknown_02d: 0x%x\n", header->unknown_02d); + printf("DEM Offset: 0x%x\n", header->dem_offset); if (header->comm.hlen > sizeof(struct garmin_gmp)) printf("from 0x%lx to 0x%x (0x%lx bytes): %s\n", diff --git a/util.c b/util.c index f9d7cca..e29d3c5 100644 --- a/util.c +++ b/util.c @@ -104,6 +104,7 @@ enum subtype get_subtype_id (const char *str) // only use 3 chars from str if (memcmp(str, "LBL", 3) == 0) return ST_LBL; if (memcmp(str, "NET", 3) == 0) return ST_NET; if (memcmp(str, "NOD", 3) == 0) return ST_NOD; + if (memcmp(str, "DEM", 3) == 0) return ST_DEM; if (memcmp(str, "SRT", 3) == 0) return ST_SRT; if (memcmp(str, "GMP", 3) == 0) return ST_GMP; if (memcmp(str, "TYP", 3) == 0) return ST_TYP; @@ -117,7 +118,7 @@ enum subtype get_subtype_id (const char *str) // only use 3 chars from str const char *get_subtype_name (enum subtype id) { const static char *type_names[] = { - "TRE", "RGN", "LBL", "NET", "NOD", + "TRE", "RGN", "LBL", "NET", "NOD", "DEM", "SRT", "GMP", "TYP", "MDR", "TRF", "MPS", "QSI"}; return id >= ST_UNKNOWN ? NULL : type_names[id];