1 2#------------------------------------------------------------------------------ 3# $File: map,v 1.11 2024/06/10 23:09:52 christos Exp $ 4# map: file(1) magic for Map data 5# 6 7# Garmin .FIT files https://pub.ks-and-ks.ne.jp/cycling/edge500_fit.shtml 88 string .FIT FIT Map data 9>15 byte 0 10>>35 belong x \b, unit id %d 11>>39 lelong x \b, serial %u 12# https://pub.ks-and-ks.ne.jp/cycling/edge500_fit.shtml 13# 20 years after unix epoch 14# TZ=GMT date -d '1989-12-31 0:00' +%s 15>>43 leldate+631065600 x \b, %s 16 17>>47 leshort x \b, manufacturer %d 18>>47 leshort 1 \b (garmin) 19>>49 leshort x \b, product %d 20>>53 byte x \b, type %d 21>>53 byte 1 \b (Device) 22>>53 byte 2 \b (Settings) 23>>53 byte 3 \b (Sports/Cycling) 24>>53 byte 4 \b (Activity) 25>>53 byte 8 \b (Elevations) 26>>53 byte 10 \b (Totals) 27 28# Summary: Garmin map 29# From: Joerg Jenderek 30# URL: https://en.wikipedia.org/wiki/Garmin_.img 31# Reference: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/IMG_File_Format 32# sourceforge.net/projects/garmin-img/files/IMG%20File%20Format/1.0/imgformat-1.0.pdf 33# GRR: similar to MBR boot sector handled by ./filesystems 340x1FE leshort =0xAA55 35# look for valid map signature 36>0x13 string =IMG\0 37>>0 use garmin-map 380 name garmin-map 39>0 ubyte x Garmin 40!:mime application/x-garmin-map 41# If non-zero, every byte of the entire .img file is to be XORed with this value 42>0 ubyte !0 \b, %#x XORed 43# goto block before FAT 44>(0x40.b*512) ubyte x 45# 1st fat name "DLLINFO TXT" only found for vpm 46>>&512 string =DLLINFO\ TXT map (Voice Processing) 47# there exist 2 other Garmin VPM formats; see ./audio 48!:ext vpm 49# Deutsch__Yannick_D4481-00_0210.vpm 50#>>>512 search/0x0116da60/s RIFF \b; with 51# determine type voice type by ./riff 52#>>>>&0 indirect x \b 53>>&512 string !DLLINFO\ TXT map 54!:ext img 55# 9 zeros 56>1 ubelong !0 \b, zeroes %#x 57# Map's version major 58>8 ubyte x v%u 59# Map's version minor 60>9 ubyte x \b.%.2u 61# Map description[20], 0x20 padded 62>0x49 string x %.20s 63# Map name, continued (0x20 padded, \0 terminated) 64>0x65 string >\ \b%.31s 65# Update year (+1900 for val >= 0x63, +2000 for val <= 0x62) 66>0xB ubyte x \b, updated 67>>0xB ubyte >0x62 68>>>0xB ubyte-100 x 20%.2u 69>>0xB ubyte <0x63 70>>>0xB ubyte x 20%.2u 71# Update month (0-11) 72>0xA ubyte x \b-%.2u 73# All zeroes 74>0xc uleshort !0 \b, zeroes %#x 75# Mapsource flag, 1 - file created by Mapsource, 0 - Garmin map visible in Basecamp and Homeport 76#>0xE ubyte !0 \b, Mapsource flag %#x 77>0xE ubyte 1 \b, Mapsource 78# Checksum, sum of all bytes modulo 256 should be 0 79#>0xF ubyte x \b, Checksum %#x 80# Signature: DSKIMG 0x00 or DSDIMG 0x00 for demo map 81>0x10 string !DSKIMG \b, signature "%.7s" 82>0x39 use garmin-date 83# Map file identifier like GARMIN\0 84>0x41 string !GARMIN \b, id "%.7s" 85# Block size exponent, E1; appears to always be 0x09; minimum block size 512 bytes 86>0x61 ubyte !0x09 \b, E1=%u 87# Block size exponent, E2 ; file blocksize=2**(E1+E2) 88>>0x62 ubyte x \b, E2=%u 89>0x61 ubyte =0x09 \b, blocksize 90>>0x62 ubyte 0 512 91>>0x62 ubyte 1 1024 92>>0x62 ubyte 2 2048 93>>0x62 ubyte 3 4096 94>>0x62 ubyte 4 8192 95>>0x62 ubyte 5 16384 96>>0x62 default x 97>>>0x62 ubyte x E2=%u 98# MBR signature 99>0x1FE leshort !0xAA55 \b, invalid MBR 100# 512 zeros 101>0x200 uquad !0 \b, zeroes %#llx 102# First sub-file offset (absolute); sometimes NO/UNKNOWN sub file! 103>0x40C ulelong >0 \b, at %#x 104# sub-file Header length 105#>>(0x40C.l) uleshort x \b, header len %#x 106>>(0x40C.l) uleshort x %u bytes 107# sub-file Type[10] like "GARMIN RGN" "GARMIN TRE", "GARMIN TYP", etc. 108>>(0x40C.l+2) ubyte >0x1F 109>>>(0x40C.l+2) ubyte <0xFF 110>>>>(0x40C.l+2) string x "%.10s" 111# 0x00 for most maps, 0x80 for locked maps (City Nav, City Select, etc.) 112>>>>(0x40C.l+13) ubyte >0 \b, locked %#x 113# Block sequence numbers like 0000 0100 0200 ... FFFF 114# >0x420 ubequad >0 \b, seq. %#16.16llx 115# >>0x428 ubequad >0 \b%16.16llx 116# >>>0x430 ubequad >0 \b%16.16llx 117# >>>>0x438 ubequad >0 \b%16.16llx 118# >>>>>0x440 ubequad >0 \b%16.16llx 119# >>>>>>0x448 ubequad >0 \b%16.16llx 120# >>>>>>>0x450 ubequad >0 \b%16.16llx 121# >>>>>>>>0x458 ubequad >0 \b%16.16llx 122# >>>>>>>>>0x460 ubequad >0 \b%16.16llx 123# >>>>>>>>>>0x468 ubequad >0 \b%16.16llx 124# >>>>>>>>>>>0x470 ubequad >0 \b%16.16llx 125# >>>>>>>>>>>>0x478 ubequad >0 \b%16.16llx 126# >>>>>>>>>>>>>0x480 ubequad >0 \b%16.16llx 127# >>>>>>>>>>>>>>0x488 ubequad >0 \b%16.16llx 128# >>>>>>>>>>>>>>>0x490 ubequad >0 \b%16.16llx 129# >>>>>>>>>>>>>>>>0x498 ubequad >0 \b%16.16llx 130# >>>>>>>>>>>>>>>>>0x4A0 ubequad >0 \b%16.16llx 131# >>>>>>>>>>>>>>>>>>0x4A8 ubequad >0 \b%16.16llx 132# look for end of FAT 133#>>0x420 search/512/s \xff\xff FAT END 134# Physical block number of FAT header 135#>0x40 ubyte x \b, FAT at phy. block %u 136>0x40 ubyte x 137>>(0x40.b*512) ubyte x 138# 1st FAT block 139>>>&511 use garmin-fat 140# 2nd FAT block 141>>>&1023 use garmin-fat 142# 3th FAT block 143>>>&1535 use garmin-fat 144# 4th FAT block 145>>>&2047 use garmin-fat 146# ... xth FAT block 147# 148# 314 zeros but not in vpm and also gmaptz.img 149>0x84 uquad !0 \b, at 0x84 %#llx 150# display FileAllocationTable block entry in garmin map 1510 name garmin-fat 152>0 ubyte x \b; 153# sub file part; 0x0003 seems to be garbage 154>0x10 uleshort !0 next %#4.4x 155>0x10 uleshort =0 156# fat flag 0~dummy block 1~true sub file 157>>0 ubyte !1 flag %u 158>>0 ubyte =1 159# sub-file name like MAKEGMAP 12345678 160>>>0x1 string x %.8s 161# sub-file typ like RGN TRE MDR LBL 162>>>0x9 string x \b.%.3s 163# size of sub file 164>>>0xC ulelong x \b, %u bytes 165# 32-bit block sequence numbers 166#>>>0x20 ubequad x \b, seq. %#16.16llx 167 168# display date stored inside Garmin maps like yyyy-mm-dd h:mm:ss 1690 name garmin-date 170# year like 2018 171>0 uleshort x \b, created %u 172# month (0-11) 173>2 ubyte x \b-%.2u 174# day (1-31) 175>3 ubyte x \b-%.2u 176# hour (0-23) 177>4 ubyte x %u 178# minute (0-59) 179>5 ubyte x \b:%.2u 180# second (0-59) 181>6 ubyte x \b:%.2u 182 183# Summary: Garmin Map subfiles 184# From: Joerg Jenderek 185# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/IMG_File_Format 186# Garmin Common Header 1872 string GARMIN\ 188# skip ASCII text by checking for low header length 189>0 uleshort <0x1000 Garmin map, 190# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/GMP_Subfile_Format 191>>9 string GMP subtile 192!:mime application/x-garmin-gpm 193!:ext gmp 194# copyright message 195>>>(0.s) string x %s 196>>>0x0E use garmin-date 197# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/MDR_Subfile_Format 198# This contains the searchable address table used for finding routing destinations 199>>9 string MDR address table 200!:mime application/x-garmin-mdr 201!:ext mdr 202# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/NOD_Subfile_Format 203# http://svn.parabola.me.uk/display/trunk/doc/nod.txt 204# This contains the routing information 205>>9 string NOD routing 206!:mime application/x-garmin-nod 207!:ext nod 208>>>0x0E use garmin-date 209#>>>0x15 ulelong x \b, at %#x 210#>>>0x19 ulelong x %#x bytes NOD1 211#>>>0x25 ulelong x \b, at %#x 212#>>>0x29 ulelong x %#x bytes NOD2 213#>>>0x31 ulelong x \b, at %#x 214#>>>0x35 ulelong x %#x bytes NOD3 215# URL: http://www.pinns.co.uk/osm/net.html 216# routable highways (length, direction, allowed speed,house address information) 217>>9 string NET highways 218!:mime application/x-garmin-net 219!:ext net 220#>>>0x15 ulelong x \b, at %#x 221#>>>0x19 ulelong x %#x bytes NET1 222#>>>0x22 ulelong >0 223#>>>>0x1E ulelong x \b, at %#x 224#>>>>0x22 ulelong x %#x bytes NET2 225#>>>0x2B ulelong >0 226#>>>>0x27 ulelong x \b, at %#x 227#>>>>0x2B ulelong x %#x bytes NET3 228# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/LBL_Subfile_Format 229>>9 string LBL labels 230!:mime application/x-garmin-lbl 231!:ext lbl 232>>>(0.s) string x %s 233# Label coding type 6h 9h and ah 234>>>0x1E ubyte x \b, coding type %#x 235#>>>0x15 ulelong x \b, at %#x 236#>>>0x19 ulelong x %#x bytes LBL1 237#>>>0x1F ulelong x \b, at %#x 238#>>>0x23 ulelong x %#x bytes LBL2 239#>>>0x2D ulelong x \b, at %#x 240#>>>0x31 ulelong x %#x bytes LBL3 241# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/SRT_Subfile_Format 242# A lookup table of the chars in the map's codepage, and their collating sequence 243>>9 string SRT sort table 244!:mime application/x-garmin-srt 245!:ext srt 246>>>0x0E use garmin-date 247# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/TRE_Subfile_Format 248>>9 string TRE tree 249!:mime application/x-garmin-tre 250!:ext tre 251# title like City Nav Europe NTU 2019.2 Basemap 252# or OSM Street map 253>>>(0.s) string x %s 254# 2nd title like Copyright 1995-2018 by GARMIN Corporation. 255# or http://www.openstreetmap.org/ 256>>>>&1 string x %s 257>>>0x0E use garmin-date 258#>>>0x21 ulelong x \b, at %#x 259#>>>0x25 ulelong x %#x bytes TRE1 260#>>>0x29 ulelong x \b, at %#x 261#>>>0x2D ulelong x %#x bytes TRE2 262#>>>0x31 ulelong x \b, at %#x 263#>>>0x35 ulelong x %#x bytes TRE3 264# Copyright record size 265#>>>0x39 uleshort x \b, copyright record size %u 266# Map ID 267>>>0x74 ulelong x \b, ID %#x 268# URL: https://www.gpspower.net/garmin-tutorials/353310-basecamp-installing-free-desktop-map.html 269# For road traffic information service (RDS/TMS/TMC). Commonly seen in City Navigator maps 270>>9 string TRF traffic, 271!:mime application/x-garmin-trf 272!:ext trf 273# city/region like Preitenegg 274>>>(0.s+1) string x 1st %s 275# highway part like L606/L148 276>>>>&1 string x %s 277# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/Format 278# Reference: http://www.pinns.co.uk/osm/typformat.html 279# customize the appearance of objects. For GPS and MapSource/Qlandkarte better looking maps 280>>9 string TYP types 281!:mime application/x-garmin-typ 282!:ext typ 283>>>0x0E use garmin-date 284# character set 1252 65001~UTF8 285>>>0x15 uleshort x \b, code page %u 286# POIs 287#>>>0x17 ulelong x \b, at %#x 288#>>>0x1B ulelong x %#x bytes TYP1 289# extra pois 290#>>>0x5B ulelong x \b, at %#x 291#>>>0x5F ulelong x %#x bytes TYP8 292# URL: https://wiki.openstreetmap.org/wiki/OSM_Map_On_Garmin/RGN_Subfile_Format 293# http://www.pinns.co.uk/osm/RGN.html 294# region data used by the Garmin software 295>>9 string RGN region 296!:mime application/x-garmin-rgn 297!:ext rgn 298# POIs,Indexed POIs,Polylines or Polygons or first map level 299#>>>0x15 ulelong x \b, at %#x 300#>>>0x19 ulelong x %#x bytes RGN1 301# polygons with extended types 302#>>>0x21 ulelong >0 303#>>>>0x1D ulelong x \b, at %#x 304#>>>>0x21 ulelong x %#x bytes RGN2 305# polylines with extended types 306#>>>0x3D ulelong >0 307#>>>>0x39 ulelong x \b, at %#x 308#>>>>0x3D ulelong x %#x bytes RGN3 309# extended POIs 310#>>>0x59 ulelong >0 311#>>>>0x55 ulelong x \b, at %#x 312#>>>>0x59 ulelong x %#x bytes RGN3 313#>>9 default x unknown map type 314# Header length; GMP:31h 35h 3Dh,MDR:11Eh 238h 2C4h 310h,NOD:3Fh 7Fh,NET:64h, 315# LBL:2A9h,SRT:1Dh 25h 27h,TRE:CFh 135h,TRF:5Ah,TYP:5Bh 6Eh 7Ch AEh,RGN:7Dh 316>>0 uleshort x \b, header length %#x 317 318# URL: https://www.memotech.franken.de/FileFormats/ 319# Reference: https://www.memotech.franken.de/FileFormats/Garmin_RGN_Format.pdf 320# From: Joerg Jenderek 3210 string KpGr Garmin update 322# format version like: 0064h~1.0 323>0x4 uleshort !0x0064 324>>4 uleshort/100 x \b, version %u 325>>4 uleshort%100 x \b.%u 326# 1st Garmin entry 327>6 use garmin-entry 328# 2nd Garmin entry 329>(0x6.l+10) ubyte x 330>>&0 use garmin-entry 331# 3rd entry 332>(0x6.l+10) ubyte x 333>>&(&0.l+4) ubyte x 334>>>&0 use garmin-entry 335# look again at version to use default clause 336>0x4 uleshort x 337# test for region content by looking for 338# Garmin *.srf by ./images with normal builder name "SQA" or longer "hales" 339# 1 space after equal sign 340>>0x3a search/5/s GARMIN\ BITMAP \b= 341!:mime image/x-garmin-exe 342!:ext exe 343>>>&0 indirect x 344# if not bitmap *.srf then region; 1 space after equal sign 345>>0x3a default x \b= 346!:mime application/x-garmin-rgn 347!:ext rgn 348# recursiv embedded 349>>>0x3a search/5/s KpGrd 350>>>>&0 indirect x 351# look for ZIP or JAR archive by ./archive and ./zip 352>>>0x3a search/5/s PK\003\004 353>>>>&0 indirect x 354# TODO: other garmin RGN record content like foo 355#>>0x3a search/5/s bar BAR 356# display information of Garmin RGN record 3570 name garmin-entry 358# record length: 2 for Data, for Application often 1Bh sometimes 1Dh, "big" for Region 359#>0 ulelong x \b, length %#x 360# data record (ID='D') with version content like 0064h~1.0 361>4 ubyte =0x44 362>>5 uleshort !0x0064 \b; Data 363>>>5 uleshort/100 x \b, version %u 364>>>5 uleshort%100 x \b.%u 365# Application Record (ID='A') 366>4 ubyte =0x41 \b; App 367# version content like 00c8h~2.0 368>>5 uleshort !0x00C8 369>>>5 uleshort/100 x \b, version %u 370>>>5 uleshort%100 x \b.%u 371# builder name like: SQA sqa build hales 372>>7 string x \b, build by %s 373# build date like: Oct 25 1999, Oct 1 2008, Feb 23 2009, Dec 15 2009 374>>>&1 string x %s 375# build time like: 11:26:12, 11:45:54, 14:16:13, 18:23:01 376>>>>&1 string x %s 377# region record (ID='R') 378>4 ubyte =0x52 \b; Region 379# region ID:14~fw_all.bin: 78~ZIP, RGN or SRF bitmap; 148~ZIP or JAR; 249~display firmware; 251~WiFi or GCD firmware; 255~ZIP 380>>5 uleshort x ID=%u 381# delay in ms: like 0, 500 382>>7 ulelong !0 \b, %u ms 383# region size (is record length - 10) 384#>>11 ulelong x \b, length %#x 385# region content like: 386# "KpGr"~recursiv embedded,"GARMIN BITMAP"~Garmin Bitmap *.srf, "PK"~ZIP archive 387#>>15 string x \b, content "%s" 388>>15 ubequad x \b, content %#llx... 389# This does NOT WORK! 390#>>15 indirect x \b; contains 391>4 default x \b; other 392# garmin Record ID Identifies the record content like: D A R 393>>4 ubyte x ID '%c' 394 395# TOM TOM GPS watches ttbin files: 396# https://github.com/ryanbinns/ttwatch/tree/master/ttbin 397# From: Daniel Lenski 3980 byte 0x20 399>1 leshort 0x0007 400>>0x76 byte 0x20 401>>>0x77 leshort 0x0075 TomTom activity file, v7 402>>>>8 leldate x (%s, 403>>>>3 byte x device firmware %d. 404>>>>4 byte x \b%d. 405>>>>5 byte x \b%d, 406>>>>6 leshort x product ID %04d) 407 408# Garmin firmware: 409# https://www.memotech.franken.de/FileFormats/Garmin_GCD_Format.pdf 410# https://www.gpsrchive.com/GPSMAP/GPSMAP%2066sr/Firmware.html 4110 string GARMIN 412>6 uleshort 100 GARMIN firmware (version 1.0) 413