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