Re: [Gpsbabel-code] Wrong or unsupported GPI file
GPSBabel converts and transfers data like waypoints, tracks & routes.
Brought to you by:
robertl
|
From: Øyvind J. <pe...@br...> - 2009-08-15 15:02:37
|
Hi, Some more info from my efforts to decode the Garmin GPI format. <LegalStuff> In case any Garmin lawyers are seeing this: All below info has been gathered by the following procedures, all of which are believed to be within what I am legally allowed to do by the licensing terms to which I have agreed: - Create GPX and CSV files according to the publicly available definitions of the contents of these files, using fictious or publicly available content, then converting the files by POI Loader. - Load the resulting GPI to my Garmin device, and observe the behaviour (the device display, as well as the actions when driving to/past a POI). - Load the resulting GPI to my computer, and decode the generated GPI files using hex editors and other tools, matching the contents to the source GPX/CSV files. - Load publicly available GPI files to my Garmin device, and observe the behaviour. - Decode those same GPI files, and match the device behaviour to the file contents. </LegalStuff> In any case, I only recently came across the GPSBabel project, and since I really like this type of project, I thought it would be a good idea to support it by providing my findings. At a future time I may be able to submit code, but for now I feel a lot more comfortable letting the experts handle that part! All line numbers refer to garmin_gpi.c rev 1.18. Also, I have grown into the habit of using bytes (8 bit), words (16 bit) and dwords (32 bit). Hopefully I have avoided mixing them up below. read_poi comment (record 0x02/0x80002): The byte being ignored in line 350 seems to be a flag indicating the type of alert info being present. If set to 0, there is no alert (i.e. no record 0x03), if 1 there is a record 0x03. I have seen other values as well (at least 2, 3 and 7), but have not yet managed to correlate those with any specific functionality. Some comments to the processing in read_tag: Record 0x03 (alert info, only present if the POI has an alert): Following the proximity and speed, 2 32-bit fields are read (lines 486, 487). The last one (line 487) seems to have the following layout: - First an unknown byte which is "always" 1. - Next a byte with the type of alert (0 for proximity only, 1 for speed, 2 for TourGuide) - Next a byte giving the source of the alert sound for this POI (0x10 built-in, 0x20 MP3 file) - Finally, the specific sound. If built-in, I have seen 4 (speed=0) and 5 (speed!=0). If from an MP3 file, this byte holds the MP3 "index" (or whatever), which matches the first byte in the record 0x12 that holds the actual MP3 content. Record 0x04, line 490 (only present if a BMP is associated with the POI or the group of POIs): Word, identifies the symbol used for a POI (i.e. the BMP file). Holds the "index" of the BMP, matching the first word of the record 0x05 that holds the actual BMP. Record 0x06 (only present if the gpx/csv source file is in a sub-directory): Word, identifies the group or category name within which this POI resides. Holds the "index" of the file name, matching the first word of the record 0x07 that holds the actual filename. Record 0x05 (BMP file): This one has a rather complex structure, and there are several fields that are unclear. However, in the interest of being able to build or extract the BMP, here are the details I have discovered so far (in sequence from start of record): Word, "index" that matches the one in record 0x04. Word, BMP height in pixels. Word, BMP width in pixels. Word, unknown use, but related to color depth (0x0c for mono/4-bit, 0x18 for 8-bit, 0x60 for 24-bit). Word, number of bits per pixel. Word, unknown and "always" 0. Dword, size of BMP image in bytes. Dword, offset of BMP image in bytes from start of record content. Dword, unclear, set to 0 for 24-bit, set to 16 for mono. Dword, unknown and usually 0xff-0x00-0xff-0x00. Dword, unknown and usually 1. Dword, offset of BMP color table in bytes from start of record content (set to 0 for 24-bit). Byte array for the BMP image, 1 byte each pixel, left to right, top to bottom (which is the reverse vertical order from the BMP file). Dword array for the BMP color table, 256 entries. Within each dword, the first is red, second Green, third Blue, and last unknown (always 0). The first 3 bytes are in reverse order from the BMP file. Record 0x07 matches my notes. Record 0x0a is the Comment field (GPX "cmt", CSV col 4), rather than the description. Record 0x0e contains the Description (GPX "desc", not present in CSV): Record 0x80002: I have also seen POI records that are not extended (i.e. record type 0x02). This would need a flag to read_poi to avoid reading the extended length (or perhaps better, do that before calling read_poi. Record 0x0b has still another field discovered only yesterday (line 562): Mask bit 5, when set, shows the presence of something that can only be the house number (a string without language indicator). Found by looking up the address of one of the German POIs via the web. I have not found any way of setting this from a GPX file, however. I guess the usual would be to have this as part of the street address (Germans and Scandinavians place the house number after the street name, which may explain why this field is there in the first place). Record 0x0c has a very minor issue on line 570: The GPX "Category" tag for this field has a space between "Phone" and "2". Record 0x8000c (line 587) most likely can use the code for record 0x0c. Record 0x12 (line 601): This record has the MP3 sound for a POI. Layout: Byte, sound number matching the field in record 0x03. Word, unknown and "always" 0x0120. 2-byte language(?) indicator (always "EN" on my files). Next follows the actual MP3 file (a direct copy). Record 0x11 (line 604) is definitely separate from record 0x07, although the meaning of this record is rather unclear. Also, record 0x11 belongs in the GPI heading part (I have only seen this one nested inside a record 0x01). Record 0x80007 is the same as record 0x07, but being "extended", it contains a nested record 0x04. A couple of comments to wdata_write: The comment to record 0x02 also affects line 934: This should probably be "if (dt->alerts) gbputc(1, fout);", as is also implied by the comment. The constant in line 957 should probably be 0x1000100 (an extra 0 between the 1's). The constant in line 959 should possibly be 0 if speed is zero (i.e. a proximity alert). I'm not sure how to detect that the POI is for a TourGuide - if so, the value should probably be 2. The "flag" that gets written in line 960 matches my notes exactly, but does not allow the option of adding MP3 files. Maybe this is for later, but the MP3 "index" goes here, and line 961 should then write 0x20. The section in lines 964 through 968 writes record type 0x04. In all files I have analyzed, this record is placed in front of record 0x03 (i.e. just before line 938). I don't know if this is significant. In line 966 the length is written (always 2). The next line writes the BMP "index", starting with 0 for the first BMP. Line 971 writes record 0x0a - this is the comment rather than the description. May need to change lines 914/915. Line 991: The 2 is the length field if the record is extended (having room for the bit mask only). I have also seen this record non-extended, in which case the length field would have to include all subsequent field. "Phone 2", "Fax", "Email" and "Link" may need to be added here (ref the decoder for record 0x0c). If the POI has associated JPGs, these get written following record 0x0c. One JPG per record. And finally the description (record 0x0e) gets written. All these records appear as nested records to the 0x02 POI record, and thus would have to be included in the extended length field of this record (line 927). peroy |