1
2
3#------------------------------------------------------------------------------
4# $File: map,v 1.10 2023/02/03 20:41:57 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, %#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 %#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 %#x
76# Mapsource flag, 1 - file created by Mapsource, 0 - Garmin map visible in Basecamp and Homeport
77#>0xE     ubyte               !0                  \b, Mapsource flag %#x
78>0xE      ubyte               1                   \b, Mapsource
79# Checksum, sum of all bytes modulo 256 should be 0
80#>0xF     ubyte               x                   \b, Checksum %#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 %#llx
103# First sub-file offset (absolute); sometimes NO/UNKNOWN sub file!
104>0x40C    ulelong             >0                  \b, at %#x
105# sub-file Header length
106#>>(0x40C.l)        uleshort  x         \b, header len %#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 %#x
114# Block sequence numbers like 0000 0100 0200 ... FFFF
115# >0x420  ubequad             >0        \b, seq. %#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 %#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 %#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. %#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 %#x
211#>>>0x19                      ulelong             x         %#x bytes NOD1
212#>>>0x25                      ulelong             x         \b, at %#x
213#>>>0x29                      ulelong             x         %#x bytes NOD2
214#>>>0x31                      ulelong             x         \b, at %#x
215#>>>0x35                      ulelong             x         %#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 %#x
222#>>>0x19                      ulelong             x         %#x bytes NET1
223#>>>0x22                      ulelong             >0
224#>>>>0x1E           ulelong             x         \b, at %#x
225#>>>>0x22           ulelong             x         %#x bytes NET2
226#>>>0x2B                      ulelong             >0
227#>>>>0x27           ulelong             x         \b, at %#x
228#>>>>0x2B           ulelong             x         %#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 %#x
236#>>>0x15                      ulelong             x         \b, at %#x
237#>>>0x19                      ulelong             x         %#x bytes LBL1
238#>>>0x1F                      ulelong             x         \b, at %#x
239#>>>0x23                      ulelong             x         %#x bytes LBL2
240#>>>0x2D                      ulelong             x         \b, at %#x
241#>>>0x31                      ulelong             x         %#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 %#x
260#>>>0x25                      ulelong             x         %#x bytes TRE1
261#>>>0x29                      ulelong             x         \b, at %#x
262#>>>0x2D                      ulelong             x         %#x bytes TRE2
263#>>>0x31                      ulelong             x         \b, at %#x
264#>>>0x35                      ulelong             x         %#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 %#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 %#x
289#>>>0x1B                      ulelong             x         %#x bytes TYP1
290# extra pois
291#>>>0x5B                      ulelong             x         \b, at %#x
292#>>>0x5F                      ulelong             x         %#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 %#x
301#>>>0x19                      ulelong          x  %#x bytes RGN1
302# polygons with extended types
303#>>>0x21                      ulelong          >0
304#>>>>0x1D           ulelong          x  \b, at %#x
305#>>>>0x21           ulelong          x  %#x bytes RGN2
306# polylines with extended types
307#>>>0x3D                      ulelong          >0
308#>>>>0x39           ulelong          x  \b, at %#x
309#>>>>0x3D           ulelong          x  %#x bytes RGN3
310# extended POIs
311#>>>0x59                      ulelong          >0
312#>>>>0x55           ulelong          x  \b, at %#x
313#>>>>0x59           ulelong          x  %#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 %#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 %#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 %#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 %#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# Garmin firmware:
410# https://www.memotech.franken.de/FileFormats/Garmin_GCD_Format.pdf
411# https://www.gpsrchive.com/GPSMAP/GPSMAP%2066sr/Firmware.html
4120         string              GARMIN
413>6        uleshort  100       GARMIN firmware (version 1.0)
414