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