On 12/02/11 15:32, WanMil wrote:
I observed that the MapSource search menu is disabled if the MDR file is
larger than 0x7FFFFFF (134217727) bytes.

Maybe in this case a flag must be set?

My guess is in ImgHeader:

// This sectors, head, cylinders stuff appears to be used by mapsource
// and they have to be larger than the actual size of the map.  It
// doesn't appear to have any effect on a garmin device or other software.
int sectors = 0x20;   // 0x20 appears to be a max
header.putShort(OFF_SECTORS, (short) sectors);
int heads = 0x20;     // 0x20 appears to be max
header.putShort(OFF_HEADS, (short) heads);
int cylinders = 0x100;   // gives 128M will try more later

Try boosting cylinders to 0x200, or try to find if there is a maximum
useful value like it appears that there is for the others.

..Steve

My first simple tries were not successful. MapSource reject the maps
with changed cylinder values.
So I have started to implement the display for the IMG file header to be
able to analyze it. There are many solutions possible:
* Wrong E2 value? My large MDR-IMG files use E2=3. This seems to be too low.
* There are still quite a number of unknown bytes. Some of them are set
in my official Garmin maps.

WanMil

Hopefully the patch helps to find the correct settings for larger IMG files.

WanMil
Index: src/test/display/ImgDisplay.java
===================================================================
--- src/test/display/ImgDisplay.java	(revision 0)
+++ src/test/display/ImgDisplay.java	(revision 0)
@@ -0,0 +1,80 @@
+package test.display;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+
+public class ImgDisplay {
+
+	public ImgDisplay() {
+	}
+	
+	public void display(String imgFile) throws FileNotFoundException {
+		CommonFileReader reader = new CommonFileReader(new File(imgFile));
+		Displayer d = new Displayer(reader);
+		d.setTitle("IMG Header");
+
+		d.byteValue("XOR value %d");
+		d.rawValue(7, "Unknown");
+		d.byteValue("Unknown %d");
+		d.byteValue("Unknown %d");
+		d.byteValue("Month %d");
+		d.byteValue("Year %d");
+		d.int3sValue("Unknown %d");
+		d.byteValue("Checksum %d");
+		
+		d.stringValue(7, "Signature %s");
+		d.byteValue("Unknown  %d");
+		d.charValue("Sectors  %d");
+		d.charValue("Heads    %d");
+		d.charValue("Cylinder %d");
+
+		d.charValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.intValue("Unknown %d");
+		d.byteValue("Unknown %d");
+
+		d.charValue("Year   %d");
+		d.byteValue("Month  %d");
+		d.byteValue("Day    %d");
+		d.byteValue("Hour   %d");
+		d.byteValue("Minute %d");
+		d.byteValue("Second %d");
+		d.byteValue("Directory start block? %d");
+
+		d.stringValue(7, "Identifier %s");
+		d.byteValue("Unknown %d");
+		d.stringValue(20, "Map description \"%s\"");
+		d.charValue("Heads    %d");
+		d.charValue("Sectors  %d");
+		d.byteValue("E1 %d");
+		d.byteValue("E2 %d");
+		d.charValue("Unknown %d");
+		d.stringValue(31, "Map name \"%s\"");
+		d.rawValue(314, "Fill - Unknown");
+		
+		
+		d.print(System.out);	
+	}
+	
+	public static void main(String[] args) throws FileNotFoundException {
+		if (args.length < 1) {
+			System.err.println("Usage: imgdisplay <filename>");
+			System.exit(1);
+		}
+
+		String name = args[0];
+
+		try {
+			ImgDisplay id = new ImgDisplay();
+			id.display(name);
+		} catch (FileNotFoundException exp) {
+			System.err.println();
+		}
+	}
+
+}
Index: src/test/display/CommonFileReader.java
===================================================================
--- src/test/display/CommonFileReader.java	(revision 0)
+++ src/test/display/CommonFileReader.java	(revision 0)
@@ -0,0 +1,204 @@
+package test.display;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+
+import uk.me.parabola.imgfmt.MapFailedException;
+import uk.me.parabola.imgfmt.ReadFailedException;
+import uk.me.parabola.imgfmt.app.ImgFileReader;
+
+public class CommonFileReader implements ImgFileReader {
+
+	private final FileChannel channel;
+	private final ByteBuffer buffer;
+	private long bufferReadPos;
+
+	public CommonFileReader(File file) throws FileNotFoundException {
+		channel = new FileInputStream(file).getChannel();
+		buffer = ByteBuffer.allocate(1000*1000);
+		buffer.order(ByteOrder.LITTLE_ENDIAN);
+		loadNext();
+	}
+
+	@Override
+	public void close() throws IOException {
+		channel.close();
+	}
+
+	@Override
+	public long position() {
+			return bufferReadPos - buffer.remaining();
+	}
+
+	@Override
+	public void position(long pos) {
+		try {
+			channel.position(pos);
+			bufferReadPos = pos;
+			buffer.clear();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void loadNext() {
+//		buffer.flip();
+		try {
+			channel.read(buffer);
+			bufferReadPos = channel.position();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		buffer.flip();
+
+	}
+
+	@Override
+	public byte get() throws ReadFailedException {
+		if (buffer.remaining() >= 1) {
+			return buffer.get();
+		} else {
+			loadNext();
+			return get();
+		}
+	}
+
+	@Override
+	public char getChar() throws ReadFailedException {
+		if (buffer.remaining() >= 2) {
+			return buffer.getChar();
+		} else {
+			loadNext();
+			return getChar();
+		}
+	}
+
+	@Override
+	public int get3() throws ReadFailedException {
+		if (buffer.remaining() >= 3) {
+			byte b1 = get();
+			byte b2 = get();
+			byte b3 = get();
+
+			return (b1 & 0xff) | ((b2 & 0xff) << 8) | (b3 << 16);
+		} else {
+			loadNext();
+			return get3();
+		}
+	}
+
+	@Override
+	public int getu3() throws ReadFailedException {
+		return get3() & 0xffffff;
+	}
+
+	@Override
+	public int getInt() throws ReadFailedException {
+		if (buffer.remaining() >= 4) {
+			return buffer.getInt();
+		} else {
+			loadNext();
+			return getInt();
+		}
+	}
+
+	@Override
+	public int getUint(int n) throws ReadFailedException {
+		switch (n) {
+		case 1:
+			return get() & 0xff;
+		case 2:
+			return getChar();
+		case 3:
+			return getu3();
+		case 4:
+			return getInt();
+		default: // this is a programming error so exit
+			throw new MapFailedException("bad integer size " + n);
+		}
+	}
+
+	@Override
+	public byte[] get(int len) throws ReadFailedException {
+		if (buffer.remaining() >= len) {
+			byte[] result = new byte[len];
+			buffer.get(result);
+			return result;
+		} else {
+			loadNext();
+			return get(len);
+		}
+	}
+
+	@Override
+	public String getZString() throws ReadFailedException {
+		StringBuilder sb = new StringBuilder();
+
+		// Slow but sure implementation.
+		for (byte b = get(); b != 0; b = get()) {
+			sb.append((char) b);
+		}
+		return sb.toString();
+	}
+
+	public String getBase11str(byte firstChar, char delimiter) {
+		// NB totally untested.
+		StringBuilder str11 = new StringBuilder();
+		int term = 2;
+
+		int ch = firstChar & 0xff;
+		do {
+			if (str11.length() == 0) {
+				// Not found
+				if (ch < 0x80)
+					return "";
+			}
+
+			if ((ch & 0x80) != 0)
+				--term;
+			str11.append(base(ch & 0x7F, 11, 2));
+			if (term != 0)
+				ch = get();
+		} while (term != 0);
+
+		// Remove any trailing delimiters
+		int idx;
+		if ((idx = str11.lastIndexOf("A")) >= 0)
+			str11.setLength(idx);
+
+		// Convert in-line delimiters to the char delimiter
+		int len = str11.length();
+		for (int i = 0; i < len; i++) {
+			if (str11.charAt(i) == 'A')
+				str11.setCharAt(i, delimiter);
+		}
+
+		return str11.toString();
+	}
+
+	private String base(int inNum, int base, int width) {
+		int num = inNum;
+		StringBuilder val = new StringBuilder();
+
+		if (base < 2 || base > 36 || width < 1)
+			return "";
+
+		String digit = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+		while (num != 0) {
+			val.append(digit.charAt(num % base));
+			num /= base;
+		}
+
+		while (val.length() < width)
+			val.append('0');
+
+		val.reverse();
+		return val.toString();
+	}
+
+}
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to