Hi

Another problem discovered when investigating indexes.

If you have a map with cities but no streets, MDR5 sets the flag that
indicates MDR20 indexes are present, and writes an erroneous byte after
each record.

Attached patch fixes and adds some more flag documentation.

Regards
Ticker 
Index: src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java	(revision 4285)
+++ src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java	(working copy)
@@ -207,6 +207,7 @@
 	 * @param val The value to write. Unsigned
 	 */
 	public void putNu(int nBytes, int val) {
+		assert nBytes >= 1 && nBytes <= 4: nBytes;
 		try {
 			file.write(val);
 			if (nBytes <= 1) {
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java	(revision 4285)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java	(working copy)
@@ -36,6 +36,7 @@
 	private List<Mdr5Record> cities = new ArrayList<>();
 	private int maxCityIndex;
 	private int localCitySize;
+	private int mdr20PointerSize = 0; // bytes for mdr20 pointer, or 0 if no mdr20
 
 	public Mdr5(MdrConfig config) {
 		setConfig(config);
@@ -188,7 +189,6 @@
 	}
 
 	public void writeSectData(ImgFileWriter writer) {
-		int size20 = getSizes().getMdr20Size();
 		Mdr5Record lastCity = null;
 		boolean hasString = hasFlag(0x8);
 		boolean hasRegion = hasFlag(0x4);
@@ -217,7 +217,8 @@
 				writer.put2u(region);
 			if (hasString)
 				putStringOffset(writer, city.getStringOffset());
-			writer.putNu(size20, city.getMdr20());
+			if (mdr20PointerSize > 0)
+				writer.putNu(mdr20PointerSize, city.getMdr20());
 		}
 	}
 
@@ -239,7 +240,7 @@
 		int size = sizes.getMapSize()
 				+ localCitySize
 				+ 3
-				+ sizes.getMdr20Size();
+				+ mdr20PointerSize;
 		if (hasFlag(0x4))
 			size += 2;
 		if (hasFlag(0x8))
@@ -252,10 +253,15 @@
 	}
 
 	/**
-	 * Known structure:
-	 * bits 0-1: size of local city index - 1 (all values appear to work)
-	 * bit  3: has region
-	 * bit  4: has string
+	 * Known structure bits/masks:
+	 * 0x0003 size of local city index - 1 (all values appear to work)
+	 * 0x0004 has region/country
+	 * 0x0008 has string
+	 * 0x0010 ? set unconditionally ?
+	 * 0x0040 mdr17 sub section
+	 * 0x0100 mdr20 present
+	 * 0x0400 28_29 offset
+	 * 0x0800 mdr20 offset
 	 * @return The value to be placed in the header.
 	 */
 	public int getExtraValue() {
@@ -269,7 +275,10 @@
 			val |= 0x08; // string
 		}
 		val |= 0x10;
-		val |= 0x100; // mdr20 present
+		if (getSizes().getNumberOfItems(20) > 0) { 
+			mdr20PointerSize = getSizes().getMdr20Size();
+			val |= 0x100; // mdr20 present
+		}
 		return val;
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java	(revision 4285)
+++ src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java	(working copy)
@@ -215,5 +215,9 @@
 		public int getSize(int sect) {
 			return sections[sect].getSizeForRecord();
 		}
+
+		public int getNumberOfItems(int sect) {
+			return sections[sect].getNumberOfItems();
+		}
 	}
 }
_______________________________________________
mkgmap-dev mailing list
mkgmap-dev@lists.mkgmap.org.uk
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to