Index: src/uk/me/parabola/imgfmt/app/BufferedImgFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/BufferedImgFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/BufferedImgFileReader.java	(working copy)
@@ -48,6 +48,8 @@
 
 	public BufferedImgFileReader(ImgChannel chan) {
 		this.chan = chan;
+//		buf.order(ByteOrder.LITTLE_ENDIAN);
+// could use getShort/getChar/getInt if sure buffer loaded		
 	}
 
 	/**
@@ -80,7 +82,7 @@
 
 	/**
 	 * Read in a single byte from the current position.
-	 *
+	 * Should not be used for reading numbers, use get1s/u instead.
 	 * @return The byte that was read.
 	 */
 	public byte get() throws ReadFailedException {
@@ -90,6 +92,8 @@
 		int pos = (int) (position - bufStart);
 		if (pos >= bufSize)
 			return 0; // XXX do something else
+// doing following makes test/func/files/GmapsuppTest.java test fail 		
+//			throw new MapFailedException("buffered input unavailable");
 
 		position++;
 		return buf.get(pos);
@@ -96,28 +100,35 @@
 	}
 
 	/**
+	 * Read in a single byte from the current position.
+	 * @return int sign-extended value that was read.
+	 */
+	public int get1s() throws ReadFailedException {
+		return (int)get();
+	}
+
+	/**
 	 * Read in two bytes.  Done in the correct byte order.
-	 *
-	 * @return The 2 byte integer that was read.
+	 * @return int sign-extended value that was read.
 	 */
-	public char getChar() throws ReadFailedException {
-		// Slow but sure implementation
+	public int get2s() throws ReadFailedException {
 		byte b1 = get();
 		byte b2 = get();
-		return (char) (((b2 & 0xff) << 8) + (b1 & 0xff));
+		return (b1 & 0xff)
+				| (b2 << 8)
+				;
 	}
 
 	/**
 	 * Read a three byte signed quantity.
-	 * @return The read value.
+	 * @return int sign-extended value that was read.
 	 * @throws ReadFailedException
 	 */
-	public int get3() throws ReadFailedException {
+	public int get3s() throws ReadFailedException {
 		// Slow but sure implementation
 		byte b1 = get();
 		byte b2 = get();
 		byte b3 = get();
-
 		return (b1 & 0xff)
 				| ((b2 & 0xff) << 8)
 				| (b3 << 16)
@@ -124,40 +135,68 @@
 				;
 	}
 
-	public int getu3() throws ReadFailedException {
-		return get3() & 0xffffff;
+	public int get1u() throws ReadFailedException {
+		return get() & 0xff;
 	}
 
 	/**
-	 * Read in a 4 byte value.
+	 * Read in two bytes.  Done in the correct byte order.
 	 *
-	 * @return A 4 byte integer.
+	 * @return The 2 byte integer that was read.
 	 */
-	public int getInt() throws ReadFailedException {
+	public int get2u() throws ReadFailedException {
+		byte b1 = get();
+		byte b2 = get();
+		return (b1 & 0xff)
+				| ((b2 & 0xff) << 8)
+				;
+	}
+
+	/**
+	 * Read a three byte signed quantity.
+	 * @return The read value.
+	 * @throws ReadFailedException
+	 */
+	public int get3u() throws ReadFailedException {
 		// Slow but sure implementation
 		byte b1 = get();
 		byte b2 = get();
 		byte b3 = get();
-		byte b4 = get();
 		return (b1 & 0xff)
 				| ((b2 & 0xff) << 8)
 				| ((b3 & 0xff) << 16)
-				| ((b4 & 0xff) << 24)
 				;
 	}
 
-	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();
+
+	public int getNu(int nBytes) throws ReadFailedException {
+		switch (nBytes) {
+		case 1: return get1u();
+		case 2: return get2u();
+		case 3: return get3u();
+		case 4: return get4();
 		default: // this is a programming error so exit
-			throw new MapFailedException("bad integer size " + n);
+			throw new MapFailedException("bad integer size " + nBytes);
 		}
 	}
 
 	/**
+	 * Read in a 4 byte signed value.
+	 *
+	 * @return A 4 byte integer.
+	 */
+	public int get4() throws ReadFailedException {
+		byte b1 = get();
+		byte b2 = get();
+		byte b3 = get();
+		byte b4 = get();
+		return (b1 & 0xff)
+				| ((b2 & 0xff) << 8)
+				| ((b3 & 0xff) << 16)
+				|  (b4 << 24)
+				;
+	}
+	/**
 	 * Read in an arbitrary length sequence of bytes.
 	 *
 	 * @param len The number of bytes to read.
Index: src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/BufferedImgFileWriter.java	(working copy)
@@ -106,7 +106,8 @@
 
 	/**
 	 * Write out a single byte.
-	 *
+ 	 * Should not be used for writing numbers, use put1s/u instead.
+	 * %%% temporary
 	 * @param b The byte to write.
 	 */
 	public void put(byte b) {
@@ -115,21 +116,41 @@
 	}
 
 	/**
-	 * Write out two bytes.  Done in the correct byte order.
-	 *
-	 * @param c The value to write.
+	 * Write out int in range -128..127 as single byte.
+	 * @param val The byte to write.
 	 */
-	public void putChar(char c) {
+	public void put1s(int val) {
+		assert val >= -128 && val <= 127 : val;
+		ensureSize(1);
+		buf.put((byte)val);
+	}
+
+	/**
+	 * Write out int in range -32768..32767 as two bytes in little endian byte order.
+	 * @param val The value to write.
+	 */
+	public void put2s(int val) {
+		assert val >= -32768 && val <= 32767 : val;
 		ensureSize(2);
-		buf.putChar(c);
+		buf.putShort((short)val);
 	}
 
 	/**
+	 * Write out int in range -0x800000..0x7fffff in little endian byte order.
+	 * @param int The value to write.
+	 */
+	public void put3s(int val) {
+		assert val >= -0x800000 && val <= 0x7fffff : val;
+		ensureSize(3);
+		buf.put((byte)val);
+		buf.putShort((short)(val >> 8));
+	}
+
+	/**
 	 * Write out int in range 0..255 as single byte.
-	 * Use instead of put() for unsigned for clarity.
 	 * @param val The value to write.
 	 */
-	public void put1(int val) {
+	public void put1u(int val) {
 		assert val >= 0 && val <= 255 : val;
 		ensureSize(1);
 		buf.put((byte)val);
@@ -136,53 +157,45 @@
 	}
 
 	/**
-	 * Write out int in range 0..65535 as two bytes in correct byte order.
-	 * Use instead of putChar() for unsigned for clarity.
+	 * Write out int in range 0..65535 as two bytes in little endian byte order.
 	 * @param val The value to write.
 	 */
-	public void put2(int val) {
+	public void put2u(int val) {
 		assert val >= 0 && val <= 65535 : val;
 		ensureSize(2);
-		buf.putShort((short)val);
+		buf.putChar((char)val);
 	}
 
 	/**
-	 * Write out a 3 byte value in the correct byte order etc.
-	 *
+	 * Write out int in range 0..0xffffff as three bytes in little endian byte order.
 	 * @param val The value to write.
 	 */
-	public void put3(int val) {
+	public void put3u(int val) {
+		assert val >= 0 && val <= 0xffffff : val;
 		ensureSize(3);
-		buf.put((byte) (val & 0xff));
-		buf.putChar((char) (val >> 8));
+		buf.put((byte)val);
+		buf.putChar((char)(val >> 8));
 	}
 
 	/**
-	 * Write out 4 byte value.
+	 * Write out int as 1-4 bytes in little endian byte order.
 	 *
-	 * @param val The value to write.
-	 */
-	public void putInt(int val) {
-		ensureSize(4);
-		buf.putInt(val);
-	}
-
-	/**
-	 * Write out 1-4 bytes.  Done in the correct byte order.
-	 *
 	 * @param nBytes The number of bytes to write.
-	 * @param val The value to write.
+	 * @param val The value to write. Unsigned
 	 */
-	public void putN(int nBytes, int val) {
+	public void putNu(int nBytes, int val) {
 		ensureSize(nBytes);
 		switch (nBytes) {
 		case 1:
-			buf.put((byte)val);
+			assert val >= 0 && val <= 255 : val;
+			put((byte)val);
 			break;
 		case 2:
+			assert val >= 0 && val <= 65535 : val;
 			buf.putShort((short)val);
 			break;
 		case 3:
+			assert val >= 0 && val <= 0xffffff : val;
 			buf.put((byte)val);
 			buf.putShort((short)(val >> 8));
 			break;
@@ -195,6 +208,16 @@
 	}
 
 	/**
+	 * Write out int (signed or unsigned) as 4 bytes.
+	 *
+	 * @param val The value to write.
+	 */
+	public void put4(int val) {
+		ensureSize(4);
+		buf.putInt(val);
+	}
+
+	/**
 	 * Write out an arbitrary length sequence of bytes.
 	 *
 	 * @param val The values to write.
Index: src/uk/me/parabola/imgfmt/app/CommonHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/CommonHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/CommonHeader.java	(working copy)
@@ -61,11 +61,11 @@
 
 		writer.position(0);
 
-		writer.putChar((char) headerLength);
+		writer.put2u(headerLength);
 		writer.put(Utils.toBytes(type, TYPE_LEN, (byte) 0));
 
-		writer.put((byte) 1);  // unknown
-		writer.put((byte) 0);  // not locked
+		writer.put1u(1);  // unknown
+		writer.put1u(0);  // not locked
 
 		byte[] date = Utils.makeCreationTime(new Date());
 		writer.put(date);
@@ -79,7 +79,7 @@
 	 */
 	public final void readHeader(ImgFileReader reader) throws ReadFailedException {
 		reader.position(0);
-		headerLength = reader.getChar();
+		headerLength = reader.get2u();
 		byte[] bytes = reader.get(TYPE_LEN);
 		try {
 			type = new String(bytes, "ascii");
Index: src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/FileBackedImgFileWriter.java	(working copy)
@@ -49,7 +49,7 @@
 			tmpChannel = out.getChannel();
 			file = new BufferedOutputStream(out, 16*1024);
 		} catch (IOException e) {
-			throw new MapFailedException("Could not create mdr temporary file");
+			throw new MapFailedException("Could not create temporary file");
 		}
 
 		if (chan instanceof FileLink) {
@@ -70,7 +70,7 @@
 			channel.transferTo(0, channel.size(), outputChan);
 		} finally {
 			if (!tmpFile.delete())
-				System.err.println("Could not delete mdr img temporary file");
+				System.err.println("could not delete temporary file " + tmpFile.getPath());
 		}
 	}
 
@@ -99,13 +99,13 @@
 			file.flush();
 			tmpChannel.position(pos);
 		} catch (IOException e) {
-			throw new MapFailedException("Could not set position in mdr tmp file");
+			throw new MapFailedException("could not set position in temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
 	 * Write out a single byte.
-	 *
+	 * %%% temporary
 	 * @param b The byte to write.
 	 */
 	public void put(byte b) {
@@ -117,94 +117,124 @@
 	}
 
 	/**
-	 * Write out two bytes. Can't use writeChar() since need to reverse the byte
-	 * order.
-	 *
-	 * @param c The value to write.
+	 * Write out int in range -128..127 as single byte.
+	 * @param val The byte to write.
 	 */
-	public void putChar(char c) {
+	public void put1s(int val) {
+		assert val >= -128 && val <= 127 : val;
 		try {
-			file.write(c);
-			file.write(c >> 8);
+			file.write(val);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write char to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
+	 * Write out int in range -32768..32767 as two bytes in little endian byte order.
+	 * @param val The value to write.
+	 */
+	public void put2s(int val) {
+		assert val >= -32768 && val <= 32767 : val;
+		try {
+			file.write(val);
+			file.write(val >> 8);
+		} catch (IOException e) {
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
+		}
+	}
+
+	/**
+	 * Write out int in range -0x800000..0x7fffff in little endian byte order.
+	 * @param int The value to write.
+	 */
+	public void put3s(int val) {
+		assert val >= -0x800000 && val <= 0x7fffff : val;
+		try {
+			file.write(val);
+			file.write(val >> 8);
+			file.write(val >> 16);
+		} catch (IOException e) {
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
+		}
+	}
+
+	/**
 	 * Write out int in range 0..255 as single byte.
-	 * Use instead of put() for unsigned for clarity.
 	 * @param val The value to write.
 	 */
-	public void put1(int val) {
+	public void put1u(int val) {
 		assert val >= 0 && val <= 255 : val;
  		try {
 			file.write(val);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write byte to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
-	 * Write out int in range 0..65535 as two bytes in correct byte order.
-	 * Use instead of putChar() for unsigned for clarity.
+	 * Write out int in range 0..65535 as two bytes in little endian byte order.
 	 * @param val The value to write.
 	 */
-	public void put2(int val) {
+	public void put2u(int val) {
 		assert val >= 0 && val <= 65535 : val;
  		try {
 			file.write(val);
 			file.write(val >> 8);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write 2 bytes to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
-
 	}
 
 	/**
-	 * Write out three bytes.  Done in the little endian byte order.
-	 *
-	 * @param val The value to write, only the bottom three bytes will be written.
+	 * Write out int in range 0..0xffffff as three bytes in little endian byte order.
+	 * @param val The value to write.
 	 */
-	public void put3(int val) {
+	public void put3u(int val) {
+		assert val >= 0 && val <= 0xffffff : val;
 		try {
 			file.write(val);
 			file.write(val >> 8);
 			file.write(val >> 16);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write3 to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
-	 * Write out 1-4 bytes.  Done in the correct byte order.
+	 * Write out int as 1-4 bytes in little endian byte order.
 	 *
 	 * @param nBytes The number of bytes to write.
-	 * @param val The value to write.
+	 * @param val The value to write. Unsigned
 	 */
-	public void putN(int nBytes, int val) {
+	public void putNu(int nBytes, int val) {
 		try {
 			file.write(val);
-			if (nBytes <= 1)
+			if (nBytes <= 1) {
+				assert val >= 0 && val <= 255 : val;
 				return;
+			}
 			file.write(val >> 8);
-			if (nBytes <= 2)
+			if (nBytes <= 2) {
+				assert val >= 0 && val <= 65535 : val;
 				return;
+			}
 			file.write(val >> 16);
-			if (nBytes <= 3)
+			if (nBytes <= 3) {
+				assert val >= 0 && val <= 0xffffff : val;
 				return;
+			}
 			file.write(val >> 24);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write put3 to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
-	 * Write out 4 byte value.
+	 * Write out 4 byte (signed or unsigned) value.
 	 *
 	 * @param val The value to write.
 	 */
-	public void putInt(int val) {
+	public void put4(int val) {
 		try {
 			file.write(val);
 			file.write(val >> 8);
@@ -211,7 +241,7 @@
 			file.write(val >> 16);
 			file.write(val >> 24);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write int to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
@@ -224,7 +254,7 @@
 		try {
 			file.write(val);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write bytes to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
@@ -239,7 +269,7 @@
 		try {
 			file.write(src, start, length);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write bytes to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
@@ -253,7 +283,7 @@
 			file.flush();
 			tmpChannel.write(src);
 		} catch (IOException e) {
-			throw new MapFailedException("could not write buffer to mdr tmp file");
+			throw new MapFailedException("could not write to temporary file " + tmpFile.getPath());
 		}
 	}
 
@@ -270,13 +300,13 @@
 			file.flush();
 			return tmpChannel.size();
 		} catch (IOException e) {
-			throw new MapFailedException("could not get size of mdr tmp file");
+			throw new MapFailedException("could not get size of temporary file " + tmpFile.getPath());
 		}
 	}
 
 	/**
-	 * Closes this stream and releases any system resources associated with it. If the stream is already closed then
-	 * invoking this method has no effect.
+	 * Closes this stream with the result that the contents of the temporary file are written to the
+	 * real output.
 	 *
 	 * @throws IOException if an I/O error occurs
 	 */
Index: src/uk/me/parabola/imgfmt/app/ImgFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/ImgFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/ImgFileReader.java	(working copy)
@@ -40,49 +40,58 @@
 	 * Set the position of the file.
 	 * @param pos The new position in the file.
 	 */
-	void position(long pos);
+	public void position(long pos);
 
 	/**
 	 * Read in a single byte.
+	 * Should not be used for reading numbers, use get1s/u instead.
 	 * @return The byte that was read.
 	 */
 	public byte get() throws ReadFailedException;
 
 	/**
-	 * Read in two bytes.  Done in the correct byte order.
-	 * @return The 2 byte integer that was read.
+	 * Read in a single byte.
+	 * @return int sign-extended value that was read.
 	 */
-	public char getChar() throws ReadFailedException;
+	public int get1s() throws ReadFailedException;
 
 	/**
-	 * Get a 3byte signed quantity.
-	 *
-	 * @return The value read.
-	 * @throws ReadFailedException When the file cannot be read.
+	 * Read in two bytes in little endian byte order.
+	 * @return int sign-extended value that was read.
 	 */
-	public int get3() throws ReadFailedException;
+	public int get2s() throws ReadFailedException;
 
 	/**
-	 * Get a 3byte unsigned quantity.
-	 *
-	 * @return The value read.
-	 * @throws ReadFailedException When the file cannot be read.
+	 * Read in three bytes in little endian byte order.
+	 * @return int sign-extended value that was read.
 	 */
-	public int getu3() throws ReadFailedException;
+	public int get3s() throws ReadFailedException;
 
+// don't think needed:
+//	public int getNs(int nBytes) throws ReadFailedException;
+
+	public int get1u() throws ReadFailedException;
+
+	public int get2u() throws ReadFailedException;
+
+	public int get3u() throws ReadFailedException;
+
+//	public default long get4u() throws ReadFailedException {
+//		return get4() & 0xffff_ffffL;
+//	}
+
 	/**
-	 * Read in a 4 byte value.
-	 * @return A 4 byte integer.
+	 * Read a variable sized integer.  The size is given.
+	 * @param nBytes The size of the integer to read. Must be 1 to 4.
+	 * @return The integer which will not be sign extended.
 	 */
-	public int getInt() throws ReadFailedException;
+	public int getNu(int nBytes) throws ReadFailedException;
 
 	/**
-	 * Read a variable sized integer.  The size is given.
-	 * @param n The size of the integer to read. Must be 1 to 4.
-	 * @return The integer which will not be sign extended if it is less
-	 * than 4 bytes long.
+	 * Read in a 4 byte signed value.
+	 * @return A 4 byte integer.
 	 */
-	public int getUint(int n) throws ReadFailedException;
+	public int get4() throws ReadFailedException;
 
 	/**
 	 * Read in an arbitrary length sequence of bytes.
Index: src/uk/me/parabola/imgfmt/app/ImgFileWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/ImgFileWriter.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/ImgFileWriter.java	(working copy)
@@ -53,52 +53,69 @@
 
 	/**
 	 * Write out a single byte.
+	 * %%% temporary
 	 * @param b The byte to write.
 	 */
 	public void put(byte b);
 
 	/**
-	 * Write out two bytes.  Done in the correct byte order.
-	 * @param c The value to write.
+	 * Write out int in range -128..127 as single byte.
+	 * @param val The byte to write.
 	 */
-	public void putChar(char c);
+	public void put1s(int val);
 
 	/**
+	 * Write out int in range -32768..32767 as two bytes in little endian byte order.
+	 * @param val The value to write.
+	 */
+	public void put2s(int val);
+
+	/**
+	 * Write out int in range -0x800000..0x7fffff in little endian byte order.
+	 * @param int The value to write.
+	 */
+	public void put3s(int val);
+
+// don't think needed:
+//	public void putNs(int nBytes, int val);
+
+	/**
 	 * Write out int in range 0..255 as single byte.
-	 * Use instead of put() for unsigned for clarity.
 	 * @param val The value to write.
 	 */
-	public void put1(int val);
+	public void put1u(int val);
 
 	/**
-	 * Write out int in range 0..65535 as two bytes in correct byte order.
-	 * Use instead of putChar() for unsigned for clarity.
+	 * Write out int in range 0..65535 as two bytes in little endian byte order.
 	 * @param val The value to write.
 	 */
-	public void put2(int val);
+	public void put2u(int val);
 
 	/**
-	 * Write out three bytes.  Done in the correct byte order.
-	 *
-	 * @param val The value to write, only the bottom three bytes will be
-	 * written.
+	 * Write out int in range 0..0xffffff as three bytes in little endian byte order.
+	 * @param val The value to write.
 	 */
-	public void put3(int val);
+	public void put3u(int val);
 	
 	/**
-	 * Write out 1-4 bytes.  Done in the correct byte order.
+	 * Write out int as 1-4 bytes in little endian byte order.
+	 * verifies that fits OK as unsigned.
 	 *
 	 * @param nBytes The number of bytes to write.
 	 * @param val The value to write.
 	 */
-	public void putN(int nBytes, int val);
-
+	public void putNu(int nBytes, int val);
+    
 	/**
-	 * Write out 4 byte value.
+	 * Write out 4 byte value in.
 	 * @param val The value to write.
 	 */
-	public void putInt(int val);
+	public void put4(int val);
 
+// 	public default void put4u(long val) {
+//		put4((int) val);
+//	}
+
 	/**
 	 * Write out an arbitrary length sequence of bytes.
 	 *
Index: src/uk/me/parabola/imgfmt/app/Section.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/Section.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/Section.java	(working copy)
@@ -23,7 +23,7 @@
  * total size of the section.
  */
 public class Section {
-	private char itemSize;
+	private int itemSize;
 	private int size;
 	private int position;
 	private Section link;
@@ -32,11 +32,11 @@
 	public Section() {
 	}
 
-	public Section(char itemSize) {
+	public Section(int itemSize) {
 		this.itemSize = itemSize;
 	}
 
-	public Section(Section link, char itemSize) {
+	public Section(Section link, int itemSize) {
 		this.itemSize = itemSize;
 		this.link = link;
 	}
@@ -49,11 +49,11 @@
 		size += itemSize;
 	}
 
-	public char getItemSize() {
+	public int getItemSize() {
 		return itemSize;
 	}
 
-	public void setItemSize(char itemSize) {
+	public void setItemSize(int itemSize) {
 		this.itemSize = itemSize;
 	}
 
@@ -105,7 +105,7 @@
 		if (itemSize == 0)
 			return 0;
 		
-		return size/ (int) itemSize;
+		return size/itemSize;
 	}
 
 	protected int getExtraValue() {
@@ -117,10 +117,10 @@
 	}
 
 	public void readSectionInfo(ImgFileReader reader, boolean withItemSize) {
-		setPosition(reader.getInt());
-		setSize(reader.getInt());
+		setPosition(reader.get4());
+		setSize(reader.get4());
 		if (withItemSize)
-			setItemSize(reader.getChar());
+			setItemSize(reader.get2u());
 	}
 
 	public SectionWriter makeSectionWriter(ImgFileWriter writer) {
@@ -137,12 +137,12 @@
 	}
 
 	public void writeSectionInfo(ImgFileWriter writer, boolean withItemSize, boolean withExtraValue) {
-		writer.putInt(getPosition());
-		writer.putInt(getSize());
+		writer.put4(getPosition());
+		writer.put4(getSize());
 		if (withItemSize || getItemSize() > 0)
-			writer.putChar(getItemSize());
+			writer.put2u(getItemSize());
 		if (withExtraValue)
-			writer.putInt(getExtraValue());
+			writer.put4(getExtraValue());
 	}
 
 	public static void close(ImgFileWriter writer) {
@@ -149,7 +149,7 @@
 		assert writer instanceof SectionWriter;
 		try {
 			writer.close();
-		} catch (IOException e) {
+		} catch (IOException ignore) {
 			// ignore as this is only for section writers.
 		}
 	}
Index: src/uk/me/parabola/imgfmt/app/SectionWriter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/SectionWriter.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/SectionWriter.java	(working copy)
@@ -62,30 +62,38 @@
 		writer.put(b);
 	}
 
-	public void putChar(char c) {
-		writer.putChar(c);
+	public void put1s(int val) {
+		writer.put1s(val);
 	}
 
-	public void put1(int val) {
-		writer.put1(val);
-	};
+	public void put2s(int val) {
+		writer.put2s(val);
+	}
 
-	public void put2(int val) {
-		writer.put2(val);
-	};
+	public void put3s(int val) {
+		writer.put3s(val);
+	}
 
-	public void put3(int val) {
-		writer.put3(val);
+	public void put1u(int val) {
+		writer.put1u(val);
 	}
 
-	public void putN(int nBytes, int val) {
-		writer.putN(nBytes, val);
+	public void put2u(int val) {
+		writer.put2u(val);
 	}
 
-	public void putInt(int val) {
-		writer.putInt(val);
+	public void put3u(int val) {
+		writer.put3u(val);
 	}
 
+	public void putNu(int nBytes, int val) {
+		writer.putNu(nBytes, val);
+	}
+
+	public void put4(int val) {
+		writer.put4(val);
+	}
+
 	public void put(byte[] val) {
 		writer.put(val);
 	}
Index: src/uk/me/parabola/imgfmt/app/dem/DEMHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/dem/DEMHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/dem/DEMHeader.java	(working copy)
@@ -55,12 +55,12 @@
 		}
 		writer.position(pos);
 		
-		writer.putInt(0); // 0: elevation in metres, 1: foot
-		writer.put2(zoomLevels.size());
-		writer.putInt(0); // unknown
-		writer.put2(60); // size of zoom level record
-		writer.putInt(offset); // offset to first DemSection header (they appear at the end of the file!)
-		writer.putInt(1); // unknown, 0 and 1 spotted
+		writer.put4(0); // 0: elevation in metres, 1: foot
+		writer.put2u(zoomLevels.size());
+		writer.put4(0); // unknown
+		writer.put2u(60); // size of zoom level record
+		writer.put4(offset); // offset to first DemSection header (they appear at the end of the file!)
+		writer.put4(1); // unknown, 0 and 1 spotted
 		
 	}
 
Index: src/uk/me/parabola/imgfmt/app/dem/DEMSection.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/dem/DEMSection.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/dem/DEMSection.java	(working copy)
@@ -23,7 +23,7 @@
 public class DEMSection {
 	private static final Logger log = Logger.getLogger(DEMSection.class);
 	private static final int STD_DIM = 64; 
-	private byte unknown1 = 0;
+	private int unknown1 = 0;
 	private final int zoomLevel;
 	private final boolean lastLevel;
 	private final int pointsPerLat = STD_DIM;
@@ -183,28 +183,28 @@
 	}
 
 	public void writeHeader(ImgFileWriter writer) {
-		writer.put(unknown1);	//0x00 
-		writer.put1(zoomLevel);	//0x01 
-		writer.putInt(pointsPerLat);	//0x02
-		writer.putInt(pointsPerLon);	//0x06 
-		writer.putInt(nonStdHeight - 1);	//0x0A
-		writer.putInt(nonStdWidth - 1);	//0x0E 
-		writer.put2(flags1);	//0x12
-		writer.putInt(tilesLon - 1);	//0x14
-		writer.putInt(tilesLat - 1);	//0x18
+		writer.put1u(unknown1);	//0x00 
+		writer.put1u(zoomLevel);	//0x01 
+		writer.put4(pointsPerLat);	//0x02
+		writer.put4(pointsPerLon);	//0x06 
+		writer.put4(nonStdHeight - 1);	//0x0A
+		writer.put4(nonStdWidth - 1);	//0x0E 
+		writer.put2u(flags1);	//0x12
+		writer.put4(tilesLon - 1);	//0x14
+		writer.put4(tilesLat - 1);	//0x18
 		
-		writer.put2(recordDesc);	//0x1c
-		writer.put2(tileDescSize);	//0x1e
-		writer.putInt(dataOffset);	//0x20
-		writer.putInt(dataOffset2);	//0x24
-		writer.putInt(left);	//0x28 
-		writer.putInt(top);	//0x2c 
-		writer.putInt(pointsDistanceLat);	//0x30
-		writer.putInt(pointsDistanceLon);	//0x34
+		writer.put2u(recordDesc);	//0x1c
+		writer.put2u(tileDescSize);	//0x1e
+		writer.put4(dataOffset);	//0x20
+		writer.put4(dataOffset2);	//0x24
+		writer.put4(left);	//0x28 
+		writer.put4(top);	//0x2c 
+		writer.put4(pointsDistanceLat);	//0x30
+		writer.put4(pointsDistanceLon);	//0x34
 		assert minHeight >= Short.MIN_VALUE && minHeight <= Short.MAX_VALUE; 
-		writer.putChar((char) minHeight);	//0x38
+		writer.put2u(minHeight);	//0x38
 		assert maxHeight >= Short.MIN_VALUE && maxHeight <= Short.MAX_VALUE; 
-		writer.putChar((char) maxHeight);	//0x3a
+		writer.put2u(maxHeight);	//0x3a
 	}
 
 	public void writeRest(ImgFileWriter writer) {
Index: src/uk/me/parabola/imgfmt/app/dem/DEMTile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/dem/DEMTile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/dem/DEMTile.java	(working copy)
@@ -41,7 +41,7 @@
 	private int offset;					// offset from section.dataOffset2
 	private final int baseHeight;		// base or minimum height in this tile 
 	private final int maxDeltaHeight;	// delta between max height and base height
-	private final byte encodingType;  	// determines how the highest values are displayed 
+	private final int encodingType;  	// determines how the highest values are displayed 
 	private final boolean hasData;		// not all voids
 
 	private int bitPos;
@@ -395,26 +395,14 @@
 		int baseSize = ((recordDesc & 0x4) >> 2) + 1;
 		int deltaSize = ((recordDesc & 0x8) >> 3) + 1;
 		boolean hasExtra = (recordDesc & 0x10) != 0;
-		switch (offsetSize) {
-		case 1:
-			writer.put1(offset);
-			break;
-		case 2:
-			writer.put2(offset);
-			break;
-		case 3:
-			writer.put3(offset);
-			break;
-		default:
-			writer.putInt(offset);
-		}
+		writer.putNu(offsetSize, offset);
 		if (baseSize == 1)
-			writer.put((byte) baseHeight);
+			writer.put1u(baseHeight);
 		else 
-			writer.putChar((char) baseHeight);
-		writer.putN(deltaSize, maxDeltaHeight);
+			writer.put2u(baseHeight);
+		writer.putNu(deltaSize, maxDeltaHeight);
 		if (hasExtra)
-			writer.put(encodingType);
+			writer.put1u(encodingType);
 	}
 
 	public void writeBitStreamData(ImgFileWriter writer) {
Index: src/uk/me/parabola/imgfmt/app/lbl/City.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/City.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/City.java	(working copy)
@@ -42,7 +42,7 @@
 	// The location of the city.  These could both be zero if we are using a
 	// label instead.
 	private Subdivision subdivision;
-	private byte pointIndex;
+	private int pointIndex;
 
 
 	// You can have either a label or a subdivision and point.  This will be
@@ -63,21 +63,21 @@
 		//writer.put3()
 		if (pointRef) {
 		    //		    System.err.println("City point = " + (int)pointIndex + " div = " + subdivision.getNumber());
-			writer.put(pointIndex);
-			writer.putChar((char)subdivision.getNumber());
+			writer.put1u(pointIndex);
+			writer.put2u(subdivision.getNumber());
 		} else {
-			writer.put3(label.getOffset());
+			writer.put3u(label.getOffset());
 		}
 
-		char info;
+		int info;
 		if(region != null)
-		    info = (char) (region.getIndex() & 0x3fff);
+		    info = region.getIndex() & 0x3fff;
 		else
-		    info = (char) (REGION_IS_COUNTRY | (country.getIndex() & 0x3fff));
+		    info = REGION_IS_COUNTRY | (country.getIndex() & 0x3fff);
 		if (pointRef)
 			info |= POINT_REF;
 
-		writer.putChar(info);
+		writer.put2u(info);
 	}
 
 	public int getIndex() {
@@ -95,7 +95,7 @@
 		this.label = label;
 	}
 
-	public void setPointIndex(byte pointIndex) {
+	public void setPointIndex(int pointIndex) {
 		pointRef = true;
 		this.pointIndex = pointIndex;
 	}
Index: src/uk/me/parabola/imgfmt/app/lbl/Country.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/Country.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/Country.java	(working copy)
@@ -26,7 +26,7 @@
  */
 public class Country {
 	// The country number.  This is not recorded in the file
-	private char index;
+	private int index;
 	private Label label;
 
 	public Country(int index) {
@@ -34,10 +34,10 @@
 	}
 
 	void write(ImgFileWriter writer) {
-		writer.put3(label.getOffset());
+		writer.put3u(label.getOffset());
 	}
 
-	public char getIndex() {
+	public int getIndex() {
 		return index;
 	}
 
@@ -50,6 +50,6 @@
 	}
 
 	public void setIndex(int index) {
-		this.index = (char) index;
+		this.index = index;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/lbl/ExitFacility.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/ExitFacility.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/ExitFacility.java	(working copy)
@@ -51,9 +51,10 @@
 		word |= type << 24;	 // 24:27 = 4 bit type
 		// 28 = unknown
 		word |= direction << 29; // 29:31 = 3 bit direction
-		writer.putChar((char)word);
-		writer.putChar((char)(word >> 16));
-		writer.put((byte)facilities);
+//		writer.put2u(word && 0xffff);
+//		writer.put2u(word >> 16);
+		writer.put4(word);
+		writer.put1u(facilities);
 	}
 
 	public int getIndex() {
Index: src/uk/me/parabola/imgfmt/app/lbl/Highway.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/Highway.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/Highway.java	(working copy)
@@ -33,9 +33,9 @@
 
 	class ExitPoint implements Comparable<ExitPoint> {
 		final String name;
-		final byte index;
+		final int index;
 		final Subdivision div;
-		public ExitPoint(String name, byte index, Subdivision div) {
+		public ExitPoint(String name, int index, Subdivision div) {
 			this.name = name;
 			this.index = index;
 			this.div = div;
@@ -63,19 +63,19 @@
 
 	void write(ImgFileWriter writer, boolean extraData) {
 		if(extraData) {
-			writer.put((byte)0);
-			writer.putChar(region == null? 0 : region.getIndex());
+			writer.put1u(0);
+			writer.put2u(region == null? 0 : region.getIndex());
 			Collections.sort(exits);
 			for(ExitPoint ep : exits) {
-			    writer.put(ep.index);
-			    writer.putChar((char)ep.div.getNumber());
+				writer.put1u(ep.index);
+				writer.put2u(ep.div.getNumber());
 			}
 		}
 		else {
 			assert extraDataOffset != 0;
-			writer.put3(label.getOffset());
-			writer.putChar((char)extraDataOffset);
-			writer.put((byte)0); // unknown (setting any of 0x3f stops exits being found)
+			writer.put3u(label.getOffset());
+			writer.put2u(extraDataOffset);
+			writer.put1u(0); // unknown (setting any of 0x3f stops exits being found)
 		}
 	}
 
@@ -96,6 +96,6 @@
 	}
 
 	public void addExitPoint(String name, int index, Subdivision div) {
-		exits.add(new ExitPoint(name, (byte)index, div));
+		exits.add(new ExitPoint(name, index, div));
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/LBLFile.java	(working copy)
@@ -71,7 +71,7 @@
 		position(LBLHeader.HEADER_LEN + lblHeader.getSortDescriptionLength());
 
 		// The zero offset is for no label.
-		getWriter().put((byte) 0);
+		getWriter().put1u(0);
 		alignForNext();
 
 		places.init(this, lblHeader.getPlaceHeader());
@@ -91,7 +91,7 @@
 
 		// Text can be put between the header and the body of the file.
 		writer.put(Utils.toBytes(sort.getDescription()));
-		writer.put((byte) 0);
+		writer.put1u(0);
 		assert writer.position() == LBLHeader.HEADER_LEN + lblHeader.getSortDescriptionLength();
 	}
 
@@ -157,7 +157,7 @@
 	private void alignForNext() {
 		// Align ready for next label
 		while ((getCurrentLabelOffset() & ((1 << offsetMultiplier) - 1)) != 0)
-			getWriter().put((byte) 0);
+			getWriter().put1u(0);
 	}
 
 	private int getNextLabelOffset() {
Index: src/uk/me/parabola/imgfmt/app/lbl/LBLFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/LBLFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/LBLFileReader.java	(working copy)
@@ -139,7 +139,7 @@
 		reader.position(start);
 		int index = 1;
 		while (reader.position() < end) {
-			int offset = reader.getu3();
+			int offset = reader.get3u();
 			Label label = fetchLabel(offset);
 
 			if (label != null) {
@@ -167,8 +167,8 @@
 		reader.position(start);
 		int index = 1;
 		while (reader.position() < end) {
-			int country = reader.getChar();
-			int offset = reader.getu3();
+			int country = reader.get2u();
+			int offset = reader.get3u();
 			Label label = fetchLabel(offset);
 			if (label != null) {
 				Region region = new Region(countries.get(country));
@@ -200,8 +200,8 @@
 		while (reader.position() < end) {
 			// First is either a label offset or a point/subdiv combo, we
 			// don't know until we have read further
-			int label = reader.getu3();
-			int info = reader.getChar();
+			int label = reader.get3u();
+			int info = reader.get2u();
 
 			City city;
 			if ((info & 0x4000) == 0) {
@@ -221,7 +221,7 @@
 				// Has subdiv/point index
 				int pointIndex = label & 0xff;
 				int subdiv = (label >> 8) & 0xffff;
-				city.setPointIndex((byte) pointIndex);
+				city.setPointIndex(pointIndex);
 				city.setSubdivision(Subdivision.createEmptySubdivision(subdiv));
 			}
 			cities.add(city);
@@ -311,7 +311,7 @@
 
 		int zipIndex = 1;
 		while (reader.position() < end) {
-			int lblOffset = reader.get3();
+			int lblOffset = reader.get3u();
 			
 			Zip zip = new Zip();
 			zip.setLabel(fetchLabel(lblOffset));
@@ -344,7 +344,7 @@
 
 		while (reader.position() < end) {
 			int poiOffset = position() - start;
-			int val = reader.getu3();
+			int val = reader.get3u();
 			int labelOffset = val & 0x3fffff;
 
 
@@ -365,7 +365,7 @@
 			boolean hasTides;
 
 			if (override) {
-				flags = reader.get();
+				flags = reader.get1u();
 
 				hasStreetNum = (flags & localMask.streetNumMask) != 0;
 				hasStreet = (flags & localMask.streetMask) != 0;
@@ -390,7 +390,7 @@
 				byte b = reader.get();
 				if ((b & 0x80) == 0) {
 					int mpoffset = (b << 16) & 0xff0000;
-					mpoffset |= reader.getChar() & 0xffff;
+					mpoffset |= reader.get2u();
 
 					poi.setComplexStreetNumber(fetchLabel(mpoffset));
 				} else {
@@ -399,18 +399,18 @@
 			}
 
 			if (hasStreet) {
-				int streetNameOffset = reader.getu3();// label for street
+				int streetNameOffset = reader.get3u();// label for street
 				Label label = fetchLabel(streetNameOffset);
 				poi.setStreetName(label);
 			}
 
 			if (hasCity) {
-				int cityIndex = reader.getUint(Utils.numberToPointerSize(placeHeader.getNumCities()));
+				int cityIndex = reader.getNu(Utils.numberToPointerSize(placeHeader.getNumCities()));
 				poi.setCity(cities.get(cityIndex-1));
 			}
 
 			if (hasZip) {
-				int zipIndex = reader.getUint(Utils.numberToPointerSize(placeHeader.getNumZips()));
+				int zipIndex = reader.getNu(Utils.numberToPointerSize(placeHeader.getNumZips()));
 				poi.setZip(zips.get(zipIndex-1));
 			}
 			
@@ -419,7 +419,7 @@
 				if ((b & 0x80) == 0) {
 					// Yes this is a bit strange it is a byte followed by a char
 					int mpoffset = (b << 16) & 0xff0000;
-					mpoffset |= reader.getChar() & 0xffff;
+					mpoffset |= reader.get2u();
 
 					poi.setComplexPhoneNumber(fetchLabel(mpoffset));
 				} else {
@@ -428,14 +428,14 @@
 			}
 
 			if (hasHighwayExit) {
-				int lblinfo = reader.getu3();
+				int lblinfo = reader.get3u();
 				int highwayLabelOffset = lblinfo & 0x3FFFF;
 				boolean indexed = (lblinfo & 0x800000) != 0;
 				boolean overnightParking = (lblinfo & 0x400000) != 0;
 
-				int highwayIndex = reader.getUint(Utils.numberToPointerSize(placeHeader.getNumHighways()));
+				int highwayIndex = reader.getNu(Utils.numberToPointerSize(placeHeader.getNumHighways()));
 				if (indexed) {
-					int eidx = reader.getUint(Utils.numberToPointerSize(placeHeader.getNumExits()));
+					int eidx = reader.getNu(Utils.numberToPointerSize(placeHeader.getNumExits()));
 				}
 			}
 
@@ -457,7 +457,7 @@
 	private PoiMasks makeLocalMask(PlacesHeader placeHeader) {
 		int globalPoi = placeHeader.getPOIGlobalFlags();
 
-		char mask= 0x1;
+		int mask= 0x1;
 
 		boolean hasStreetNum = (globalPoi & POIRecord.HAS_STREET_NUM) != 0;
 		boolean hasStreet = (globalPoi & POIRecord.HAS_STREET) != 0;
@@ -524,13 +524,13 @@
 	}
 
 	private class PoiMasks {
-		private char streetNumMask;
-		private char streetMask;
-		private char cityMask;
-		private char zipMask;
-		private char phoneMask;
-		private char highwayExitMask;
-		private char tidesMask;
+		private int streetNumMask;
+		private int streetMask;
+		private int cityMask;
+		private int zipMask;
+		private int phoneMask;
+		private int highwayExitMask;
+		private int tidesMask;
 	}
 
 	public int getEncodingType() {
Index: src/uk/me/parabola/imgfmt/app/lbl/LBLHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/LBLHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/LBLHeader.java	(working copy)
@@ -68,8 +68,8 @@
 	 * @param reader The header is read from here.
 	 */
 	protected void readFileHeader(ImgFileReader reader) {
-		labelStart = reader.getInt();
-		labelSize = reader.getInt();
+		labelStart = reader.get4();
+		labelSize = reader.get4();
 		offsetMultiplier = 1 << reader.get();
 		encodingType = reader.get();
 
@@ -76,11 +76,11 @@
 		// Read the places part of the header.
 		placeHeader.readFileHeader(reader);
 
-		int codepage = reader.getChar();
-		int id1 = reader.getChar();
-		int id2 = reader.getChar();
-		int descOff = reader.getInt();
-		int descLen = reader.getInt();
+		int codepage = reader.get2u();
+		int id1 = reader.get2u();
+		int id2 = reader.get2u();
+		int descOff = reader.get4();
+		int descLen = reader.get4();
 
 		reader.position(descOff);
 		byte[] bytes = reader.get(descLen);
@@ -109,32 +109,32 @@
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
 		// LBL1 section, these are regular labels
-		writer.putInt(HEADER_LEN + sortDescriptionLength);
-		writer.putInt(getLabelSize());
+		writer.put4(HEADER_LEN + sortDescriptionLength);
+		writer.put4(getLabelSize());
 
-		writer.put((byte) offsetMultiplier);
-		writer.put((byte) encodingType);
+		writer.put1u(offsetMultiplier);
+		writer.put1u(encodingType);
 
 		placeHeader.writeFileHeader(writer);
 
-		writer.putChar((char) getCodePage());
+		writer.put2u(getCodePage());
 
 		// Identifying the sort
-		char id1 = (char) sort.getId1();
-		writer.putChar(id1);
+		int id1 = sort.getId1();
+		writer.put2u(id1);
 		
-		char id2 = (char) sort.getId2();
+		int id2 = sort.getId2();
 		if (id1 != 0 && id2 != 0)
 			id2 |= 0x8000;
-		writer.putChar(id2);
+		writer.put2u(id2);
 
-		writer.putInt(HEADER_LEN);
-		writer.putInt(sortDescriptionLength);
+		writer.put4(HEADER_LEN);
+		writer.put4(sortDescriptionLength);
 
-		writer.putInt(placeHeader.getLastPos());
-		writer.putInt(0);
-		writer.putChar(UNK3_REC_LEN);
-		writer.putChar((char) 0);
+		writer.put4(placeHeader.getLastPos());
+		writer.put4(0);
+		writer.put2u(UNK3_REC_LEN);
+		writer.put2u(0);
 	}
 
 	protected int getEncodingType() {
Index: src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/POIIndex.java	(working copy)
@@ -27,11 +27,11 @@
 public class POIIndex {
 
 	private final String name;
-	private final byte poiIndex;
+	private final int poiIndex;
 	private final Subdivision group;
-	private final byte subType;
+	private final int subType;
 
-	public POIIndex(String name, byte poiIndex, Subdivision group, byte subType) {
+	public POIIndex(String name, int poiIndex, Subdivision group, int subType) {
 		this.name = name;
 		this.poiIndex = poiIndex;
 		this.group = group;
@@ -39,9 +39,9 @@
 	}
 
 	void write(ImgFileWriter writer) {
-		writer.put(poiIndex);
-		writer.putChar((char)group.getNumber());
-		writer.put(subType);
+		writer.put1u(poiIndex);
+		writer.put2u(group.getNumber());
+		writer.put1u(subType);
 	}
 
 	public String getName() {
Index: src/uk/me/parabola/imgfmt/app/lbl/POIRecord.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/POIRecord.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/POIRecord.java	(working copy)
@@ -28,13 +28,13 @@
  */
 public class POIRecord {
 
-	static final byte HAS_STREET_NUM = 0x01;
-	static final byte HAS_STREET     = 0x02;
-	static final byte HAS_CITY       = 0x04;
-	static final byte HAS_ZIP        = 0x08;
-	static final byte HAS_PHONE      = 0x10;
-	static final byte HAS_EXIT       = 0x20;
-	static final byte HAS_TIDE_PREDICTION = 0x40;
+	static final int HAS_STREET_NUM = 0x01;
+	static final int HAS_STREET     = 0x02;
+	static final int HAS_CITY       = 0x04;
+	static final int HAS_ZIP        = 0x08;
+	static final int HAS_PHONE      = 0x10;
+	static final int HAS_EXIT       = 0x20;
+	static final int HAS_TIDE_PREDICTION = 0x40;
 
 	/* Not used yet
 	private static final AddrAbbr ABBR_HASH = new AddrAbbr(' ', "#");
@@ -105,45 +105,42 @@
 		this.exit = exit;
 	}
 
-	void write(ImgFileWriter writer, byte POIGlobalFlags, int realofs,
+	void write(ImgFileWriter writer, int POIGlobalFlags, int realofs,
 		   long numCities, long numZips, long numHighways, long numExitFacilities) {
 		assert offset == realofs : "offset = " + offset + " realofs = " + realofs;
 		int ptr = poiName.getOffset();
 		if (POIGlobalFlags != getPOIFlags())
 			ptr |= 0x800000;
-		writer.put3(ptr);
+		writer.put3u(ptr);
 
 		if (POIGlobalFlags != getPOIFlags())
-			writer.put(getWrittenPOIFlags(POIGlobalFlags));
+			writer.put1u(getWrittenPOIFlags(POIGlobalFlags));
 
 		if (streetNumberName != null)
 		{
 			int labOff = streetNumberName.getOffset();
-			writer.put((byte)((labOff & 0x7F0000) >> 16));
-			writer.putChar((char)(labOff & 0xFFFF));
+			// !!! seems to write as hybrid endian
+			writer.put1u(labOff >> 16);
+			writer.put2u(labOff & 0xFFFF);
 		}
 		else if (simpleStreetNumber.isUsed())
 			simpleStreetNumber.write(writer);
 
 		if (streetName != null)
-			writer.put3(streetName.getOffset());
+			writer.put3u(streetName.getOffset());
 
 		if (city != null)
-		{
-			char cityIndex = (char) city.getIndex();
-			writer.putN(Utils.numberToPointerSize((int)numCities), cityIndex);
-		}
+			writer.putNu(Utils.numberToPointerSize((int)numCities), city.getIndex());
 
-		if (zip != null) {
-			char zipIndex = (char) zip.getIndex();
-			writer.putN(Utils.numberToPointerSize((int)numZips), zipIndex);
-		}
+		if (zip != null)
+			writer.putNu(Utils.numberToPointerSize((int)numZips), zip.getIndex());
 
 		if (complexPhoneNumber != null)
 		{
 			int labOff = complexPhoneNumber.getOffset();
-			writer.put((byte)((labOff & 0x7F0000) >> 16));
-			writer.putChar((char)(labOff & 0xFFFF));
+			// !!! seems to write as hybrid endian
+			writer.put1u(labOff >> 16);
+			writer.put2u(labOff & 0xFFFF);
 		}
 		else if (simplePhoneNumber.isUsed())
 			simplePhoneNumber.write(writer);
@@ -163,20 +160,20 @@
 				ef = facilites.get(0);
 			if(ef != null)
 				val |= 0x800000; // exit facilities defined
-			writer.put3(val);
+			writer.put3u(val);
 
-			char highwayIndex = (char)exit.getHighway().getIndex();
-			writer.putN(Utils.numberToPointerSize((int)numHighways), highwayIndex);
+			int highwayIndex = exit.getHighway().getIndex();
+			writer.putNu(Utils.numberToPointerSize((int)numHighways), highwayIndex);
 
 			if(ef != null) {
-				char exitFacilityIndex = (char)ef.getIndex();
-				writer.putN(Utils.numberToPointerSize((int)numExitFacilities), exitFacilityIndex);
+				int exitFacilityIndex = ef.getIndex();
+				writer.putNu(Utils.numberToPointerSize((int)numExitFacilities), exitFacilityIndex);
 			}
 		}
 	}
 
-	byte getPOIFlags() {
-		byte b = 0;
+	int getPOIFlags() {
+		int b = 0;
 		if (streetName != null)
 			b |= HAS_STREET;
 		if (simpleStreetNumber.isUsed() || streetNumberName != null)
@@ -192,7 +189,7 @@
 		return b;
 	}
 	
-	byte getWrittenPOIFlags(byte POIGlobalFlags) 
+	int getWrittenPOIFlags(int POIGlobalFlags)
 	{
 		int flag = 0;
 		int j = 0;
@@ -218,15 +215,15 @@
 
 		flag |= 0x80; // gpsmapedit asserts for this bit set
 	    
-		return (byte) flag;
+		return flag;
 	}
 
 	/**
 	 * Sets the start offset of this POIRecord
 	 *
-	 * \return Number of bytes needed by this entry
+	 * @return Number of bytes needed by this entry
 	 */
-	int calcOffset(int ofs, byte POIGlobalFlags, long numCities, long numZips, long numHighways, long numExitFacilities) {
+	int calcOffset(int ofs, int POIGlobalFlags, long numCities, long numZips, long numHighways, long numExitFacilities) {
 		offset = ofs;
 		int size = 3;
 		if (exit != null) {
@@ -340,8 +337,9 @@
 
 		public void write(ImgFileWriter writer)
 		{
-			for(int i = 0; i < encodedSize; i++)
-				writer.put(encodedNumber[i]);
+//			for(int i = 0; i < encodedSize; i++)
+//				writer.put1u(encodedNumber[i]);
+			writer.put(encodedNumber, 0, encodedSize);
 		}
 
 		public boolean isUsed()
Index: src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/PlacesFile.java	(working copy)
@@ -108,7 +108,7 @@
 		placeHeader.endPOIIndex(writer.position());
 
 		int poistart = writer.position();
-		byte poiglobalflags = placeHeader.getPOIGlobalFlags();
+		int poiglobalflags = placeHeader.getPOIGlobalFlags();
 		for (POIRecord p : pois)
 			p.write(writer, poiglobalflags,
 				writer.position() - poistart, cityList.size(), postalCodes.size(), highways.size(), exitFacilities.size());
@@ -117,8 +117,8 @@
 		int numPoiIndexEntries = 0;
 		for (int i = 0; i < 256; ++i) {
 			if(poiIndex[i] != null) {
-				writer.put((byte)i);
-				writer.put3(numPoiIndexEntries + 1);
+				writer.put1u(i);
+				writer.put3u(numPoiIndexEntries + 1);
 				numPoiIndexEntries += poiIndex[i].size();
 			}
 		}
@@ -305,7 +305,7 @@
 		if (t < MIN_INDEXED_POI_TYPE || t > MAX_INDEXED_POI_TYPE) 
 			return;
 		
-		POIIndex pi = new POIIndex(name, (byte)index, group, (byte)type);
+		POIIndex pi = new POIIndex(name, index, group, type);
 		if(poiIndex[t] == null)
 			poiIndex[t] = new ArrayList<POIIndex>();
 		poiIndex[t].add(pi);
@@ -319,7 +319,7 @@
 
 		poisClosed = true;
 
-		byte poiFlags = 0;
+		int poiFlags = 0;
 		for (POIRecord p : pois) {
 			poiFlags |= p.getPOIFlags();
 		}
Index: src/uk/me/parabola/imgfmt/app/lbl/PlacesHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/PlacesHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/PlacesHeader.java	(working copy)
@@ -49,40 +49,40 @@
 	private final Section highway = new Section(zip, HIGHWAY_REC_LEN);
 	private final Section exitFacility = new Section(highway, EXIT_REC_LEN);
 	private final Section highwayData = new Section(exitFacility, HIGHWAYDATA_REC_LEN);
-	private byte POIGlobalFlags ;
+	private int POIGlobalFlags ;
 
-	void setPOIGlobalFlags(byte flags) {
+	void setPOIGlobalFlags(int flags) {
 		this.POIGlobalFlags = flags;
 	}
 
-	byte getPOIGlobalFlags() {
+	int getPOIGlobalFlags() {
 		return POIGlobalFlags;
 	}
 
 	void writeFileHeader(ImgFileWriter writer) {
-		writer.putInt(country.getPosition());
-		writer.putInt(country.getSize());
-		writer.putChar(country.getItemSize());
-		writer.putInt(0);
+		writer.put4(country.getPosition());
+		writer.put4(country.getSize());
+		writer.put2u(country.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(region.getPosition());
-		writer.putInt(region.getSize());
-		writer.putChar(region.getItemSize());
-		writer.putInt(0);
+		writer.put4(region.getPosition());
+		writer.put4(region.getSize());
+		writer.put2u(region.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(city.getPosition());
-		writer.putInt(city.getSize());
-		writer.putChar(city.getItemSize());
-		writer.putInt(0);
+		writer.put4(city.getPosition());
+		writer.put4(city.getSize());
+		writer.put2u(city.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(poiIndex.getPosition());
-		writer.putInt(poiIndex.getSize());
-		writer.putChar(poiIndex.getItemSize());
-		writer.putInt(0);
+		writer.put4(poiIndex.getPosition());
+		writer.put4(poiIndex.getSize());
+		writer.put2u(poiIndex.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(poiProperties.getPosition());
-		writer.putInt(poiProperties.getSize());
-		writer.put((byte) 0); // offset multiplier
+		writer.put4(poiProperties.getPosition());
+		writer.put4(poiProperties.getSize());
+		writer.put1u(0); // offset multiplier
 
 		// mb 5/9/2009 - discovered that Garmin maps can contain more
 		// than 8 bits of POI global flags - have seen the 9th bit set
@@ -91,34 +91,34 @@
 		// of further bytes to read << 1) - therefore, this group
 		// should probably be: 16 bits of POI global flags followed by
 		// 16 zero bits rather than 8 bits of flags and 24 zero bits
-		writer.put(POIGlobalFlags); // properties global mask
-		writer.putChar((char) 0);
-		writer.put((byte) 0);
+		writer.put1u(POIGlobalFlags); // properties global mask
+		writer.put2u(0);
+		writer.put1u(0);
 
-		writer.putInt(poiTypeIndex.getPosition());
-		writer.putInt(poiTypeIndex.getSize());
-		writer.putChar(poiTypeIndex.getItemSize());
-		writer.putInt(0);
+		writer.put4(poiTypeIndex.getPosition());
+		writer.put4(poiTypeIndex.getSize());
+		writer.put2u(poiTypeIndex.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(zip.getPosition());
-		writer.putInt(zip.getSize());
-		writer.putChar(zip.getItemSize());
-		writer.putInt(0);
+		writer.put4(zip.getPosition());
+		writer.put4(zip.getSize());
+		writer.put2u(zip.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(highway.getPosition());
-		writer.putInt(highway.getSize());
-		writer.putChar(highway.getItemSize());
-		writer.putInt(0);
+		writer.put4(highway.getPosition());
+		writer.put4(highway.getSize());
+		writer.put2u(highway.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(exitFacility.getPosition());
-		writer.putInt(exitFacility.getSize());
-		writer.putChar(exitFacility.getItemSize());
-		writer.putInt(0);
+		writer.put4(exitFacility.getPosition());
+		writer.put4(exitFacility.getSize());
+		writer.put2u(exitFacility.getItemSize());
+		writer.put4(0);
 
-		writer.putInt(highwayData.getPosition());
-		writer.putInt(highwayData.getSize());
-		writer.putChar(highwayData.getItemSize());
-		writer.putInt(0);
+		writer.put4(highwayData.getPosition());
+		writer.put4(highwayData.getSize());
+		writer.put2u(highwayData.getItemSize());
+		writer.put4(0);
 	}
 
 	void readFileHeader(ImgFileReader reader) {
@@ -125,38 +125,38 @@
 		reader.position(0x1f);
 
 		country.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		region.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		city.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		poiIndex.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		poiProperties.readSectionInfo(reader, false);
 		reader.get(); // offset multiplier
 
-		POIGlobalFlags = reader.get();
-		reader.getChar();
+		POIGlobalFlags = reader.get1u();
+		reader.get2u();
 		reader.get();
 
 		poiTypeIndex.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		zip.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		highway.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		exitFacility.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		highwayData.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 	}
 
 	int getLastPos() {
Index: src/uk/me/parabola/imgfmt/app/lbl/Region.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/Region.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/Region.java	(working copy)
@@ -25,7 +25,7 @@
  * @author Steve Ratcliffe
  */
 public class Region {
-	private char index;
+	private int index;
 
 	private final Country country;
 	private Label label;
@@ -35,11 +35,11 @@
 	}
 
 	public void write(ImgFileWriter writer) {
-		writer.putChar(country.getIndex());
-		writer.put3(label.getOffset());
+		writer.put2u(country.getIndex());
+		writer.put3u(label.getOffset());
 	}
 
-	public char getIndex() {
+	public int getIndex() {
 		assert index > 0 : "Index not yet set";
 		return index;
 	}
@@ -49,7 +49,7 @@
 	}
 
 	public void setIndex(int index) {
-		this.index = (char)index;
+		this.index = index;
 	}
 
 	public void setLabel(Label label) {
Index: src/uk/me/parabola/imgfmt/app/lbl/Zip.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/lbl/Zip.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/lbl/Zip.java	(working copy)
@@ -31,7 +31,7 @@
 	private Label label;
 
 	public void write(ImgFileWriter writer) {
-		writer.put3(label.getOffset());
+		writer.put3u(label.getOffset());
 	}
 
 	public Label getLabel() {
Index: src/uk/me/parabola/imgfmt/app/map/Map.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/map/Map.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/map/Map.java	(working copy)
@@ -258,7 +258,7 @@
 	 * @param flags The POI flags.
 	 */
 	public void addPoiDisplayFlags(int flags) {
-		treFile.addPoiDisplayFlags((byte) flags);
+		treFile.addPoiDisplayFlags(flags);
 	}
 
 	public void addMapObject(MapObject item) {
Index: src/uk/me/parabola/imgfmt/app/mdr/MDRHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MDRHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/MDRHeader.java	(working copy)
@@ -57,10 +57,10 @@
 	 * Write out the application header.
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
-		writer.putChar((char) sort.getCodepage());
-		writer.putChar((char) sort.getId1());
-		writer.putChar((char) sort.getId2());
-		writer.putChar((char) 14);
+		writer.put2u(sort.getCodepage());
+		writer.put2u(sort.getId1());
+		writer.put2u(sort.getId2());
+		writer.put2u(14);
 
 		sections[1].writeSectionInfo(writer, true, true);
 		sections[2].writeSectionInfo(writer, true, true);
@@ -77,7 +77,7 @@
 		sections[13].writeSectionInfo(writer, true, true);
 		sections[14].writeSectionInfo(writer, true, true);
 		sections[15].writeSectionInfo(writer);
-		writer.put((byte) 0);
+		writer.put1u(0);
 
 		sections[16].writeSectionInfo(writer, true, true);
 		sections[17].writeSectionInfo(writer, false, true);
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr1.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr1.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr1.java	(working copy)
@@ -85,9 +85,9 @@
 	public void writeSectData(ImgFileWriter writer) {
 		boolean revIndex = (getExtraValue() & 1) != 0;
 		for (Mdr1Record rec : maps) {
-			writer.putInt(rec.getMapNumber());
+			writer.put4(rec.getMapNumber());
 			if (revIndex)
-				writer.putInt(rec.getIndexOffset());
+				writer.put4(rec.getIndexOffset());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr10.java	(working copy)
@@ -80,7 +80,7 @@
 				Mdr11Record mdr11ref = t.getMdr11ref();
 				addIndexPointer(mdr11ref.getMapIndex(), count);
 				
-				writer.put((byte) t.getSubtype());
+				writer.put1u(t.getSubtype());
 				int offset = mdr11ref.getRecordNumber();
 
 				// Top bit actually represents a non-repeated name.  ie if
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr11.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr11.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr11.java	(working copy)
@@ -82,9 +82,9 @@
 			poi.setRecordNumber(count++);
 
 			putMapIndex(writer, poi.getMapIndex());
-			writer.put((byte) poi.getPointIndex());
-			writer.putChar((char) poi.getSubdiv());
-			writer.put3(poi.getLblOffset());
+			writer.put1u(poi.getPointIndex());
+			writer.put2u(poi.getSubdiv());
+			writer.put3u(poi.getLblOffset());
 			if (poi.isCity())
 				putRegionIndex(writer, poi.getRegionIndex());
 			else
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr13.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr13.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr13.java	(working copy)
@@ -39,8 +39,8 @@
 
 		for (Mdr13Record region : regions) {
 			putMapIndex(writer, region.getMapIndex());
-			writer.putChar((char) region.getRegionIndex());
-			writer.putChar((char) region.getCountryIndex());
+			writer.put2u(region.getRegionIndex());
+			writer.put2u(region.getCountryIndex());
 			putStringOffset(writer, region.getStrOffset());
 		}
 	}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr14.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr14.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr14.java	(working copy)
@@ -35,7 +35,7 @@
 		
 		for (Mdr14Record country : countries) {
 			putMapIndex(writer, country.getMapIndex());
-			writer.putChar((char) country.getCountryIndex());
+			writer.put2u(country.getCountryIndex());
 			putStringOffset(writer, country.getStrOff());
 		}
 	}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr17.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr17.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr17.java	(working copy)
@@ -64,7 +64,7 @@
 			len <<= 1;
 			count++;
 		}
-		writer.putN(count, len);
+		writer.putNu(count, len);
 
 		// Calculate the header. This code is unlikely to survive the finding of another example!
 		// Have no idea what the real thinking behind this is.
@@ -73,7 +73,7 @@
 		header += (prefixLength + 1) * (prefixLength + 1);
 		header += (index.getItemSize() - prefixLength - 1) * 0xa;
 
-		writer.putChar((char) header);
+		writer.put2u(header);
 		index.writeSectData(writer);
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr18.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr18.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr18.java	(working copy)
@@ -34,8 +34,8 @@
 	public void writeSectData(ImgFileWriter writer) {
 		int poiSize = getSizes().getSize(19);
 		for (Mdr18Record pt : poiTypes) {
-			writer.putChar((char) (pt.getType() | 0x4000));
-			writer.putN(poiSize, pt.getRecord());
+			writer.put2u(pt.getType() | 0x4000);
+			writer.putNu(poiSize, pt.getRecord());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr19.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr19.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr19.java	(working copy)
@@ -69,7 +69,7 @@
 				index |= flag;
 				lastName = name;
 			}
-			writer.putN(n, index);
+			writer.putNu(n, index);
 
 			int type = MdrUtils.fullTypeToNaturalType(p.getType());
 			if (type != lastType) {
@@ -84,7 +84,7 @@
 
 		Mdr18Record m18 = new Mdr18Record();
 		m18.setRecord(record);
-		m18.setType(~0);
+		m18.setType(0xffff);
 		poiTypes.add(m18);
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr1MapIndex.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr1MapIndex.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr1MapIndex.java	(working copy)
@@ -44,7 +44,7 @@
 	}
 
 	public void addPointer(int recordNumber) {
-		subWriter.putN(pointerSize, recordNumber);
+		subWriter.putNu(pointerSize, recordNumber);
 	}
 	
 	private int sectionToSubsection(int n) {
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr1SubHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr1SubHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr1SubHeader.java	(working copy)
@@ -42,7 +42,7 @@
 	}
 
 	protected void writeFileHeader(ImgFileWriter writer) {
-		writer.putChar((char) HEADER_SIZE);
+		writer.put2u(HEADER_SIZE);
 		for (int n = 1; n <= MAX_SECTION; n++) {
 			Section section = sections[n];
 
@@ -49,15 +49,15 @@
 			// The second subsection does not have a length, because it always
 			// has the same length as subsection 1.
 			if (n == 2)
-				writer.putInt(section.getPosition());
+				writer.put4(section.getPosition());
 			else {
 				//section.writeSectionInfo(writer);
-				writer.putInt(section.getPosition());
+				writer.put4(section.getPosition());
 				int size = section.getSize();
 				if (size == 0)
-					writer.putInt(0);
+					writer.put4(0);
 				else
-					writer.putInt(size / section.getItemSize());
+					writer.put4(size / section.getItemSize());
 			}
 		}
 	}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr23.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr23.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr23.java	(working copy)
@@ -77,9 +77,9 @@
 				lastName = name;
 			}
 
-			writer.putChar((char) reg.getRegionIndex());
-			writer.putChar((char) reg.getCountryIndex());
-			writer.put3(reg.getLblOffset() | flag);
+			writer.put2u(reg.getRegionIndex());
+			writer.put2u(reg.getCountryIndex());
+			writer.put3u(reg.getLblOffset() | flag);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr24.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr24.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr24.java	(working copy)
@@ -79,8 +79,8 @@
 				lastName = name;
 			}
 
-			writer.putChar((char) c.getCountryIndex());
-			writer.put3(c.getLblOffset() | flag);
+			writer.put2u(c.getCountryIndex());
+			writer.put3u(c.getLblOffset() | flag);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr25.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr25.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr25.java	(working copy)
@@ -81,7 +81,7 @@
 	public void writeSectData(ImgFileWriter writer) {
 		int size = getItemSize();
 		for (Mdr5Record city : cities) {
-			writer.putN(size,  city.getGlobalCityIndex());
+			writer.putNu(size,  city.getGlobalCityIndex());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr26.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr26.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr26.java	(working copy)
@@ -74,7 +74,7 @@
 	public void writeSectData(ImgFileWriter writer) {
 		int size = getSizes().getSize(28);
 		for (Mdr28Record record : index) {
-			writer.putN(size, record.getIndex());
+			writer.putNu(size, record.getIndex());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr27.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr27.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr27.java	(working copy)
@@ -76,7 +76,7 @@
 	public void writeSectData(ImgFileWriter writer) {
 		int size = getItemSize();
 		for (Mdr5Record city : cities) {
-			writer.putN(size,  city.getGlobalCityIndex());
+			writer.putNu(size,  city.getGlobalCityIndex());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr28.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr28.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr28.java	(working copy)
@@ -73,10 +73,10 @@
 		int size27 = sizes.getSize(27);
 
 		for (Mdr28Record mdr28 : index) {
-			writer.putN(size23, mdr28.getMdr23());
+			writer.putNu(size23, mdr28.getMdr23());
 			putStringOffset(writer, mdr28.getStrOffset());
-			writer.putN(size21, mdr28.getMdr21());
-			writer.putN(size27, mdr28.getMdr27());
+			writer.putNu(size21, mdr28.getMdr21());
+			writer.putNu(size27, mdr28.getMdr27());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr29.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr29.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr29.java	(working copy)
@@ -85,15 +85,15 @@
 		int size26 = has26? sizes.getSize(26): 0;
 		int size17 = Utils.numberToPointerSize(max17);
 		for (Mdr29Record record : index) {
-			writer.putN(size24, record.getMdr24());
+			writer.putNu(size24, record.getMdr24());
 			if (hasString)
 				putStringOffset(writer, record.getStrOffset());
-			writer.putN(size22, record.getMdr22());
-			writer.putN(size25, record.getMdr25());
+			writer.putNu(size22, record.getMdr22());
+			writer.putNu(size25, record.getMdr25());
 			if (has26)
-				writer.putN(size26, record.getMdr26());
+				writer.putNu(size26, record.getMdr26());
 			if (has17)
-				writer.putN(size17, record.getMdr17());
+				writer.putNu(size17, record.getMdr17());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr2x.java	(working copy)
@@ -62,15 +62,15 @@
 				if (repeat != 0)
 					offset |= 0x800000;
 
-				writer.put3(offset);
+				writer.put3u(offset);
 				if (writeNameOffset)
-					writer.put(street.getOutNameOffset());
+					writer.put1u(street.getOutNameOffset());
 
 				if (partialInfoSize > 0) {
 					int trailingFlags = ((rr & 1) == 0) ? 1 : 0;
 					// trailingFlags |= s.getB() << 1;
 					// trailingFlags |= s.getS() << (1 + partialBShift);
-					writer.putN(partialInfoSize, trailingFlags);
+					writer.putNu(partialInfoSize, trailingFlags);
 				}
 			} else {
 				int rr = street.checkFullRepeat(prev, collator);
@@ -78,7 +78,7 @@
 					repeat = 0;
 
 				int index = street.getIndex();
-				writer.putN(size, (index << 1) | repeat);
+				writer.putNu(size, (index << 1) | repeat);
 			}
 
 			prev = street;
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr4.java	(working copy)
@@ -40,9 +40,9 @@
 		Collections.sort(list);
 
 		for (Mdr4Record r : list) {
-			writer.put((byte) r.getType());
-			writer.put((byte) r.getUnknown());
-			writer.put((byte) r.getSubtype());
+			writer.put1u(r.getType());
+			writer.put1u(r.getUnknown());
+			writer.put1u(r.getSubtype());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr5.java	(working copy)
@@ -212,12 +212,12 @@
 			// Write out the record
 			putMapIndex(writer, mapIndex);
 			putLocalCityIndex(writer, city.getCityIndex());
-			writer.put3(flag | city.getLblOffset());
+			writer.put3u(flag | city.getLblOffset());
 			if (hasRegion)
-				writer.putChar((char) region);
+				writer.put2u(region);
 			if (hasString)
 				putStringOffset(writer, city.getStringOffset());
-			writer.putN(size20, city.getMdr20());
+			writer.putNu(size20, city.getMdr20());
 		}
 	}
 
@@ -226,7 +226,7 @@
 	 * and not the global city index used in mdr11.
 	 */
 	private void putLocalCityIndex(ImgFileWriter writer, int cityIndex) {
-		writer.putN(localCitySize, cityIndex);
+		writer.putNu(localCitySize, cityIndex);
 	}
 
 	/**
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr6.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr6.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr6.java	(working copy)
@@ -56,7 +56,7 @@
 			addIndexPointer(z.getMapIndex(), record++);
 
 			putMapIndex(writer, z.getMapIndex());
-			writer.putN(zipSize, z.getZipIndex());
+			writer.putNu(zipSize, z.getZipIndex());
 			if (hasString)
 				putStringOffset(writer, z.getStringOffset());
 		}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr7.java	(working copy)
@@ -357,17 +357,17 @@
 			if (rr != 3)
 				lab |= 0x800000;
 			
-			writer.put3(lab);
+			writer.put3u(lab);
 			if (hasStrings)
 				putStringOffset(writer, s.getStringOffset());
 
 			if (hasNameOffset)
-				writer.put(s.getOutNameOffset());
+				writer.put1u(s.getOutNameOffset());
 			if (partialInfoSize > 0) {
 				int trailingFlags = ((rr & 1) == 0) ? 1 : 0;
 				// trailingFlags |= s.getB() << 1;
 				// trailingFlags |= s.getS() << (1 + partialBShift);
-				writer.putN(partialInfoSize, trailingFlags);
+				writer.putNu(partialInfoSize, trailingFlags);
 			}
 			last = s;
 		}
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr8.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr8.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr8.java	(working copy)
@@ -42,9 +42,9 @@
 		int size = associatedSize();
 		for (Mdr8Record s : index) {
 			for (int i = 0; i< STRING_WIDTH; i++) {
-				writer.put((byte) s.getPrefix()[i]);
+				writer.put1u(s.getPrefix()[i]);
 			}
-			writer.putN(size, s.getRecordNumber());
+			writer.putNu(size, s.getRecordNumber());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/Mdr9.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/Mdr9.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/Mdr9.java	(working copy)
@@ -35,8 +35,8 @@
 		int poiSize = getSizes().getPoiSize();
 		for (Map.Entry<Integer, Integer> ent : index.entrySet()) {
 			int group = ent.getKey();
-			writer.put((byte) group);
-			writer.putN(poiSize, ent.getValue());
+			writer.put1u(group);
+			writer.putNu(poiSize, ent.getValue());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/MdrMapSection.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MdrMapSection.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/MdrMapSection.java	(working copy)
@@ -53,18 +53,18 @@
 
 	protected void putCityIndex(ImgFileWriter writer, int cityIndex, boolean isNew) {
 		int flag = (isNew && cityIndex > 0)? getSizes().getCityFlag(): 0;
-		writer.putN(getSizes().getCitySizeFlagged(), cityIndex | flag);
+		writer.putNu(getSizes().getCitySizeFlagged(), cityIndex | flag);
 	}
 
 	protected void putRegionIndex(ImgFileWriter writer, int region) {
 		// This is only called when putCityIndex might also be called and so has to be
 		// the same size (probably ;)
-		writer.putN(getSizes().getCitySizeFlagged(), region);
+		writer.putNu(getSizes().getCitySizeFlagged(), region);
 	}
 
 	protected void putPoiIndex(ImgFileWriter writer, int poiIndex, boolean isNew) {
 		int flag = isNew? getSizes().getPoiFlag(): 0;
-		writer.putN(getSizes().getPoiSizeFlagged(), poiIndex | flag);
+		writer.putNu(getSizes().getPoiSizeFlagged(), poiIndex | flag);
 	}
 
 	protected boolean hasFlag(int val) {
Index: src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/MdrSection.java	(working copy)
@@ -49,11 +49,11 @@
 	}
 
 	protected void putMapIndex(ImgFileWriter writer, int mapIndex) {
-		writer.putN(sizes.getMapSize(), mapIndex);
+		writer.putNu(sizes.getMapSize(), mapIndex);
 	}
 
 	protected void putStringOffset(ImgFileWriter writer, int strOff) {
-		writer.putN(sizes.getStrOffSize(), strOff);
+		writer.putNu(sizes.getStrOffSize(), strOff);
 	}
 
 	/**
Index: src/uk/me/parabola/imgfmt/app/mdr/PrefixIndex.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/PrefixIndex.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/PrefixIndex.java	(working copy)
@@ -118,9 +118,9 @@
 		int size = Utils.numberToPointerSize(maxIndex);
 		for (Mdr8Record s : index) {
 			for (int i = 0; i< prefixLength; i++) {
-				writer.put((byte) s.getPrefix()[i]);
+				writer.put1u(s.getPrefix()[i]);
 			}
-			writer.putN(size, s.getRecordNumber());
+			writer.putNu(size, s.getRecordNumber());
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/mdr/RecordBase.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/mdr/RecordBase.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/mdr/RecordBase.java	(working copy)
@@ -19,7 +19,7 @@
  * @author Steve Ratcliffe
  */
 public abstract class RecordBase {
-	private short mapIndex;
+	private int mapIndex;
 
 	public int getMapIndex() {
 		return mapIndex;
@@ -27,6 +27,6 @@
 
 	public void setMapIndex(int mapIndex) {
 		assert mapIndex > 0;
-		this.mapIndex = (short) mapIndex;
+		this.mapIndex = mapIndex;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/net/NETFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/NETFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/NETFileReader.java	(working copy)
@@ -91,13 +91,13 @@
 			RoadDef road = new RoadDef(++record, off, null);
 			readLabels(reader, road);
 			byte netFlags = reader.get();
-			/*int len =*/ reader.getu3();
+			/*int len =*/ reader.get3u();
 
 			int[] counts = new int[24];
 			int level = 0;
 			while (level < 24) {
 				int n = reader.get();
-				counts[level++] = (n & 0x7f);
+				counts[level++] = n & 0x7f;
 				if ((n & 0x80) != 0)
 					break;
 			}
@@ -106,12 +106,12 @@
 				int c = counts[i];
 				for (int j = 0; j < c; j++) {
 					/*byte b =*/ reader.get();
-					/*char sub =*/ reader.getChar();
+					/*char sub =*/ reader.get2u();
 				}
 			}
 
 			if ((netFlags & RoadDef.NET_FLAG_ADDRINFO) != 0) {
-				char flags2 = reader.getChar();
+				int flags2 = reader.get2u();
 
 				int zipFlag = (flags2 >> 10) & 0x3;
 				int cityFlag = (flags2 >> 12) & 0x3;
@@ -130,10 +130,10 @@
 			}
 
 			if ((netFlags & RoadDef.NET_FLAG_NODINFO) != 0) {
-				int nodFlags = reader.get();
+				int nodFlags = reader.get1u();
 				int nbytes = nodFlags & 0x3;
 				if (nbytes > 0) {
-					/*int nod = */reader.getUint(nbytes+1);
+					/*int nod = */reader.getNu(nbytes+1);
 				}
 			}
 
@@ -153,16 +153,16 @@
 		indexes.clear();
 		if (flag == 2) {
 			// fetch city/zip index
-			int ind = reader.getUint(size);
+			int ind = reader.getNu(size);
 			if (ind != 0)
 				indexes.add(ind-1);
 		} else if (flag == 3) {
 			// there is no item
 		} else if (flag == 0) {
-			int n = reader.get() & 0xff;
+			int n = reader.get1u();
 			parseList(reader, n, size, indexes);
 		} else if (flag == 1) {
-			int n = reader.getChar();
+			int n = reader.get2u();
 			parseList(reader, n, size, indexes);
 		} else {
 			assert false : "flag is " + flag;
@@ -174,13 +174,13 @@
 		long endPos = reader.position() + n;
 		int node = 0; // not yet used
 		while (reader.position() < endPos) {
-			int initFlag = reader.get() & 0xff;
-			int skip = (initFlag & 0x1f);
+			int initFlag = reader.get1u();
+			int skip = initFlag & 0x1f;
 			initFlag >>= 5;
 			if (initFlag == 7) {
 				// Need to read another byte
-				initFlag = reader.get() & 0xff;
-				skip |= ((initFlag & 0x1f) << 5);
+				initFlag = reader.get1u();
+				skip |= (initFlag & 0x1f) << 5;
 				initFlag >>= 5;
 			}
 			node += skip + 1;
@@ -210,7 +210,7 @@
 			assert false : "ERRROR overflow";
 			return 0;
 		}
-		int cnum = reader.getUint(size);
+		int cnum = reader.getNu(size);
 		return cnum;
 	}
 
@@ -222,9 +222,9 @@
 	private void fetchNumber(ImgFileReader reader, int numberFlag) {
 		int n = 0;
 		if (numberFlag == 0) {
-			n = reader.get();
+			n = reader.get1u();
 		} else if (numberFlag == 1) {
-			n = reader.getChar();
+			n = reader.get2u();
 		} else if (numberFlag == 3) {
 			// There is no block
 			return;
@@ -238,7 +238,7 @@
 
 	private void readLabels(ImgFileReader reader, RoadDef road) {
 		for (int i = 0; i < 4; i++) {
-			int lab = reader.getu3();
+			int lab = reader.get3u();
 			Label label = labels.fetchLabel(lab & 0x7fffff);
 			road.addLabel(label);
 			if ((lab & 0x800000) != 0)
@@ -257,7 +257,7 @@
 		int start = netHeader.getRoadDefinitionsStart();
 		for (int off : offsets) {
 			reader.position(start + off);
-			int labelOffset = reader.getu3();
+			int labelOffset = reader.get3u();
 			// TODO what if top bit is not set?, there can be more than one name and we will miss them
 			offsetLabelMap.put(off, labelOffset & 0x7fffff);
 		}
@@ -277,7 +277,7 @@
 
 		Set<Integer> allOffsets = new HashSet<>();
 		while (reader.position() < end) {
-			int net1 = reader.getu3();
+			int net1 = reader.get3u();
 
 			// The offset is stored in the bottom 22 bits. The top 2 bits are an index into the list
 			// of lbl pointers in the net1 entry. 
Index: src/uk/me/parabola/imgfmt/app/net/NETHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/NETHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/NETHeader.java	(working copy)
@@ -37,8 +37,8 @@
 	private final Section segmentedRoads = new Section(roadDefinitions);
 	private final Section sortedRoads = new Section(segmentedRoads, SORTED_ROAD_RECSIZE);
 
-	private byte roadShift;
-	private byte segmentShift;
+	private int roadShift;
+	private int segmentShift;
 
 	public NETHeader() {
 		super(HEADER_LEN, "GARMIN NET");
@@ -53,14 +53,14 @@
 	 */
 	protected void readFileHeader(ImgFileReader reader) throws ReadFailedException {
 		roadDefinitions.readSectionInfo(reader, false);
-		roadShift = reader.get();
+		roadShift = reader.get1u();
 
 		segmentedRoads.readSectionInfo(reader, false);
-		segmentShift = reader.get();
+		segmentShift = reader.get1u();
 
 		sortedRoads.readSectionInfo(reader, true);
 
-		reader.getInt();
+		reader.get4();
 		reader.get();
 		reader.get();
 	}
@@ -74,17 +74,17 @@
 	protected void writeFileHeader(ImgFileWriter writer) {
 		roadDefinitions.writeSectionInfo(writer);
 
-		writer.put(roadShift); // offset multiplier
+		writer.put1u(roadShift); // offset multiplier
 
 		segmentedRoads.writeSectionInfo(writer);
 
-		writer.put(segmentShift); // offset multiplier
+		writer.put1u(segmentShift); // offset multiplier
 
 		sortedRoads.writeSectionInfo(writer);
 
-		writer.putInt(0);
-		writer.put((byte) 1);
-		writer.put((byte) 0);
+		writer.put4(0);
+		writer.put1u(1);
+		writer.put1u(0);
 	}
 
 	ImgFileWriter makeRoadWriter(ImgFileWriter writer) {
@@ -110,6 +110,6 @@
 	}
 
 	public int getRoadShift() {
-		return roadShift & 0xff;
+		return roadShift;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/net/NODFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/NODFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/NODFile.java	(working copy)
@@ -164,7 +164,7 @@
 		pos = (pos + 0x200) & ~0x1ff; // align on 0x200  
 		int numBytesToWrite = pos - section.getPosition();
 		for (int i = 0; i < numBytesToWrite; i++)
-			getWriter().put((byte)0); 
+			getWriter().put1u(0);
 		section.setPosition(pos);
 		ImgFileWriter writer = new SectionWriter(getWriter(), section);
 		
Index: src/uk/me/parabola/imgfmt/app/net/NODHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/NODHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/NODHeader.java	(working copy)
@@ -63,23 +63,23 @@
 	 */
 	protected void readFileHeader(ImgFileReader reader) throws ReadFailedException {
         nodes.readSectionInfo(reader, false);
-        flags = reader.getChar();
-        reader.getChar();
-        align = reader.get();
-        mult1 = reader.get();
-        tableARecordLen = reader.getChar();
+        flags = reader.get2u();
+        reader.get2u();
+        align = reader.get1u();
+        mult1 = reader.get1u();
+        tableARecordLen = reader.get2u();
         roads.readSectionInfo(reader, false);
-        reader.getInt();
+        reader.get4();
         boundary.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 		if (getHeaderLength() > 0x3f) {
 			highClassBoundary.readSectionInfo(reader, false);
 
-			classBoundaries[0] = reader.getInt();
-			classBoundaries[1] = classBoundaries[0] + reader.getInt();
-			classBoundaries[2] = classBoundaries[1] + reader.getInt();
-			classBoundaries[3] = classBoundaries[2] + reader.getInt();
-			classBoundaries[4] = classBoundaries[3] + reader.getInt();
+			classBoundaries[0] = reader.get4();
+			classBoundaries[1] = classBoundaries[0] + reader.get4();
+			classBoundaries[2] = classBoundaries[1] + reader.get4();
+			classBoundaries[3] = classBoundaries[2] + reader.get4();
+			classBoundaries[4] = classBoundaries[3] + reader.get4();
 		}
 	}
 
@@ -109,23 +109,23 @@
 		if(driveOnLeft)
 			flags |= 0x0100;
 		
-		writer.putInt(flags);
+		writer.put4(flags);
 
-		byte align = DEF_ALIGN;
-		writer.put(align);
-		writer.put((byte) 0); // pointer multiplier
-		writer.putChar((char) 5);
+		int align = DEF_ALIGN;
+		writer.put1u(align);
+		writer.put1u(0); // pointer multiplier
+		writer.put2u(5);
 
 		roads.writeSectionInfo(writer);
-		writer.putInt(0);
+		writer.put4(0);
 
 		boundary.writeSectionInfo(writer);
 		// new fields for header length > 0x3f
-		writer.putInt(2); // no other value spotted, meaning ?
+		writer.put4(2); // no other value spotted, meaning ?
 		highClassBoundary.writeSectionInfo(writer);
-		writer.putInt(classBoundaries[0]);
+		writer.put4(classBoundaries[0]);
 		for (int i = 1; i < classBoundaries.length; i++){
-			writer.putInt(classBoundaries[i] - classBoundaries[i-1]);
+			writer.put4(classBoundaries[i] - classBoundaries[i-1]);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/net/RoadDef.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RoadDef.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RoadDef.java	(working copy)
@@ -223,8 +223,8 @@
 		if (numbers != null && numbers.getSwapped()) {
 			netFlags |= 0x20; // swapped default; left=even, right=odd
 		}
-		writer.put((byte) netFlags);
-		writer.put3(roadLength);
+		writer.put1u(netFlags);
+		writer.put3u(roadLength);
 
 		int maxlevel = writeLevelCount(writer);
 
@@ -235,9 +235,9 @@
 			if (nodeCount + 2 != nnodes){
 				log.error("internal error? The nodeCount doesn't match value calculated by RoadNetWork:",this);
 			}
-			writer.put((byte) (nodeCount & 0xff)); // lo bits of node count
+			writer.put1u(nodeCount); // lo bits of node count
 
-			int code = ((nodeCount >> 8) & 0x3); // top bits of node count
+			int code = (nodeCount >> 8) & 0x3; // top bits of node count
 			int len, flag;
 			
 			ByteArrayOutputStream zipBuf = null, cityBuf = null;
@@ -264,32 +264,32 @@
 				flag = 3;
 			code |= flag << 6;
 			
-			writer.put((byte)code);
+			writer.put1u(code);
 //			System.out.printf("%d %d %d\n", (code >> 2 & 0x3), (code >> 4 & 0x3), (code >> 6 & 0x3));  
 			
 			if (zipBuf != null){
 				len = zipBuf.size();
-				writer.putN(Utils.numberToPointerSize(len), len);
+				writer.putNu(Utils.numberToPointerSize(len), len);
 				writer.put(zipBuf.toByteArray());
 			} else {
 				if(zip != null) {
-					char zipIndex = (char)zip.getIndex();
-					writer.putN(Utils.numberToPointerSize(numZips), zipIndex);
+					int zipIndex = zip.getIndex();
+					writer.putNu(Utils.numberToPointerSize(numZips), zipIndex);
 				}
 			}
 			if (cityBuf != null){
 				len = cityBuf.size();
-				writer.putN(Utils.numberToPointerSize(len), len);
+				writer.putNu(Utils.numberToPointerSize(len), len);
 				writer.put(cityBuf.toByteArray());
 			} else {
 				if(city != null) {
-					char cityIndex = (char)city.getIndex();
-					writer.putN(Utils.numberToPointerSize(numCities), cityIndex);
+					int cityIndex = city.getIndex();
+					writer.putNu(Utils.numberToPointerSize(numCities), cityIndex);
 				}
 			}
 			if (numbers != null) {
 				BitWriter bw = numbers.fetchBitStream();
-				writer.putN(Utils.numberToPointerSize(bw.getLength()), bw.getLength());
+				writer.putNu(Utils.numberToPointerSize(bw.getLength()), bw.getLength());
 				writer.put(bw.getBytes(), 0, bw.getLength());
 			}
 		}
@@ -298,11 +298,11 @@
 			// This is the offset of an entry in NOD2
 			int val = offsetNod2;
 			if (val < 0x7fff) {
-				writer.put((byte) 1);
-				writer.putChar((char) val);
+				writer.put1u(1);
+				writer.put2u(val);
 			} else {
-				writer.put((byte) 2);
-				writer.put3(val);
+				writer.put1u(2);
+				writer.put3u(val);
 			}
 		}
 	}
@@ -313,7 +313,7 @@
 			int ptr = l.getOffset();
 			if (i == (numlabels-1))
 				ptr |= 0x800000;
-			writer.put3(ptr);
+			writer.put3u(ptr);
 		}
 	}
 
@@ -320,7 +320,7 @@
 	public void putSortedRoadEntry(ImgFileWriter writer, Label label) {
 		for(int i = 0; i < labels.length && labels[i] != null; ++i) {
 			if(labels[i].equals(label)) {
-				writer.put3((i << 22) | offsetNet1);
+				writer.put3u((i << 22) | offsetNet1);
 				return;
 			}
 		}
@@ -334,7 +334,7 @@
 			assert b < 0x80 : "too many polylines at level " + i;
 			if (i == maxlevel)
 				b |= 0x80;
-			writer.put((byte) b);
+			writer.put1u(b);
 		}
 		return maxlevel;
 	}
@@ -479,7 +479,7 @@
 
 		for (Offset off : rgnOffsets) {
 			rgn.position(off.getPosition());
-			rgn.put3(offsetNet1 | off.getFlags());
+			rgn.put3u(offsetNet1 | off.getFlags());
 		}
 	}
 
@@ -561,8 +561,8 @@
 
 		offsetNod2 = writer.position();
 
-		writer.put((byte) nod2Flags);
-		writer.put3(node.getOffsetNod1()); // offset in nod1
+		writer.put1u(nod2Flags);
+		writer.put3u(node.getOffsetNod1()); // offset in nod1
 
 		// this is related to the number of nodes, but there
 		// is more to it...
@@ -573,7 +573,7 @@
 		int nbits = nnodes;
 		if (!startsWithNode)
 			nbits++;
-		writer.putChar((char) nbits);
+		writer.put2u(nbits);
 		boolean[] bits = new boolean[nbits];
 		
 		if (hasHouseNumbers()){
@@ -593,7 +593,7 @@
             for (int j = 0; j < 8 && j < bits.length - i; j++)
 				if (bits[i+j])
 					b |= 1 << j;
-			writer.put((byte) b);
+			writer.put1u(b);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/net/RoadIndex.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RoadIndex.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RoadIndex.java	(working copy)
@@ -43,8 +43,8 @@
 	void write(ImgFileWriter writer) {
 		int roadnum = linkedRoad.getNumber();
 		assert roadnum < 256;
-		writer.put((byte) roadnum);
-		char subdivnum = (char) getSubdiv().getNumber();
-		writer.putChar(subdivnum);
+		writer.put1u(roadnum);
+		int subdivnum = getSubdiv().getNumber();
+		writer.put2u(subdivnum);
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/net/RouteArc.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RouteArc.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RouteArc.java	(working copy)
@@ -52,12 +52,12 @@
 	private final RouteNode dest;
 
 	// The index in Table A describing this arc.
-	private byte indexA;
+	private int indexA;
 	// The index in Table B that this arc goes via, if external.
-	private byte indexB;
+	private int indexB;
 	
-	private byte flagA;
-	private byte flagB;
+	private int flagA;
+	private int flagB;
 
 	private final boolean haveCurve;
 	private final int length;
@@ -192,7 +192,7 @@
 	/**
 	 * Set this arc's index into Table A.
 	 */
-	public void setIndexA(byte indexA) {
+	public void setIndexA(int indexA) {
 		this.indexA = indexA;
 	}
 
@@ -201,7 +201,7 @@
 	 *
 	 * Required for writing restrictions (Table C).
 	 */
-	public byte getIndexA() {
+	public int getIndexA() {
 		return indexA;
 	}
 
@@ -208,7 +208,7 @@
 	/**
 	 * Set this arc's index into Table B. Applies to external arcs only.
 	 */
-	public void setIndexB(byte indexB) {
+	public void setIndexB(int indexB) {
 		assert !isInternal() : "Trying to set index on internal arc.";
 		this.indexB = indexB;
 	}
@@ -219,7 +219,7 @@
 	 * Required for writing restrictions (Table C).
 	 */
 	public int getIndexB() {
-		return indexB & 0xff;
+		return indexB; // ??? & 0xff;
 	}
 	 
 	public int getArcDestClass(){
@@ -258,23 +258,23 @@
 		// determine how to write length and curve bit
 		int[] lendat = encodeLength();
 
-		writer.put(flagA);
+		writer.put1u(flagA);
 		if (isInternal()) {
 			// space for 14 bit node offset, written in writeSecond.
-			writer.put(flagB);
-			writer.put((byte) 0);
+			writer.put1u(flagB);
+			writer.put1u(0);
 		} else {
 			if(indexB < 0 || indexB >= 0x3f) {
-				writer.put((byte) (flagB | 0x3f));
-				writer.put(indexB);
+				writer.put1u(flagB | 0x3f);
+				writer.put1u(indexB);
 			}
 			else
-				writer.put((byte) (flagB | indexB));
+				writer.put1u(flagB | indexB);
 		}
 		
 		 // only write out the local net index if it is the first arc or else if newDir is set.
 		if (first || lastArc.indexA != this.indexA)
-			writer.put(indexA);
+			writer.put1u(indexA);
 
 		if(log.isDebugEnabled())
 			log.debug("writing length", length);
@@ -285,7 +285,7 @@
 			if (useCompactDirs){
 				// determine if we have to write direction info
 				if (compactedDir != null)
-					writer.put(compactedDir);
+					writer.put(compactedDir); // composite byte = dont check
 			} else 
 				writer.put(directionFromDegrees(initialHeading));
 		} else {
@@ -294,7 +294,7 @@
 		if (haveCurve) {
 			int[] curvedat = encodeCurve();
 			for (int aCurvedat : curvedat)
-				writer.put((byte) aCurvedat);
+			    writer.put((byte) aCurvedat);
 		}
 	}
 
@@ -308,7 +308,7 @@
 			return;
 
 		writer.position(offset + 1);
-		char val = (char) (flagB << 8);
+		int val = flagB << 8;
 		int diff = dest.getOffsetNod1() - source.getOffsetNod1();
 		assert diff < 0x2000 && diff >= -0x2000
 			: "relative pointer too large for 14 bits (source offset = " + source.getOffsetNod1() + ", dest offset = " + dest.getOffsetNod1() + ")";
@@ -317,8 +317,8 @@
 		// We write this big endian
 		if(log.isDebugEnabled())
 			log.debug("val is", Integer.toHexString((int)val));
-		writer.put((byte) (val >> 8));
-		writer.put((byte) val);
+		writer.put1u(val >> 8);
+		writer.put1u(val & 0xff);
 	}
 
 	/*
Index: src/uk/me/parabola/imgfmt/app/net/RouteCenter.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RouteCenter.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RouteCenter.java	(working copy)
@@ -124,7 +124,7 @@
 
 			writer.position(pos);
 			log.debug("rewrite taba offset", writer.position(), bo);
-			writer.put(bo);
+			writer.put1u(bo);
 
 			// fill in arc pointers
 			node.writeSecond(writer);
@@ -133,11 +133,11 @@
 		writer.position(tablesOffset);
 
 		// Write the tables header
-		writer.put(tabC.getFormat());
-		writer.put3(centralPoint.getLongitude());
-		writer.put3(centralPoint.getLatitude());
-		writer.put(tabA.getNumberOfItems());
-		writer.put(tabB.getNumberOfItems());
+		writer.put1u(tabC.getFormat());
+		writer.put3s(centralPoint.getLongitude());
+		writer.put3s(centralPoint.getLatitude());
+		writer.put1u(tabA.getNumberOfItems());
+		writer.put1u(tabB.getNumberOfItems());
 
 		tabA.write(writer);
 		tabB.write(writer);
Index: src/uk/me/parabola/imgfmt/app/net/RouteNode.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RouteNode.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RouteNode.java	(working copy)
@@ -61,8 +61,8 @@
 	private int flags;
 
 	private final CoordNode coord;
-	private char latOff;
-	private char lonOff;
+	private int latOff;
+	private int lonOff;
 	private List<RouteArc[]> throughRoutes;
 
 	// contains the maximum of roads this node is on, written with the flags
@@ -195,14 +195,14 @@
 
 		assert (flags & F_DISCARDED) == 0 : "attempt to write discarded node";
 
-		writer.put((byte) 0);  // will be overwritten later
+		writer.put1u(0);  // will be overwritten later
 		flags |= (nodeClass & MAX_DEST_CLASS_MASK); // max. road class of any outgoing road
-		writer.put((byte) flags);
+		writer.put1u(flags);
 
 		if (haveLargeOffsets()) {
-			writer.putInt((latOff << 16) | (lonOff & 0xffff));
+			writer.put4((latOff << 16) | (lonOff & 0xffff));
 		} else {
-			writer.put3((latOff << 12) | (lonOff & 0xfff));
+			writer.put3s((latOff << 12) | (lonOff & 0xfff));
 		}
 
 		if (!arcs.isEmpty()) {
@@ -253,9 +253,9 @@
 	public void writeNod3OrNod4(ImgFileWriter writer) {
 		assert isBoundary() : "trying to write nod3 for non-boundary node";
 
-		writer.put3(coord.getLongitude());
-		writer.put3(coord.getLatitude()); 
-		writer.put3(offsetNod1);
+		writer.put3s(coord.getLongitude());
+		writer.put3s(coord.getLatitude()); 
+		writer.put3u(offsetNod1);
 	}
 
 	public void discard() {
@@ -294,7 +294,7 @@
 	private void setLatOff(int latOff) {
 		if(log.isDebugEnabled())
 			log.debug("lat off", Integer.toHexString(latOff));
-		this.latOff = (char) latOff;
+		this.latOff = latOff;
 		checkOffSize(latOff);
 	}
 
@@ -301,7 +301,7 @@
 	private void setLonOff(int lonOff) {
 		if(log.isDebugEnabled())
 			log.debug("long off", Integer.toHexString(lonOff));
-		this.lonOff = (char) lonOff;
+		this.lonOff = lonOff;
 		checkOffSize(lonOff);
 	}
 
Index: src/uk/me/parabola/imgfmt/app/net/RouteRestriction.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/RouteRestriction.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/RouteRestriction.java	(working copy)
@@ -53,7 +53,7 @@
 
 	private final RouteNode viaNode; 
 	// offset in Table C
-	private byte offsetSize;
+	private int offsetSize;
 	private int offsetC;
 
 	// last restriction in a node
@@ -147,13 +147,13 @@
 	 * 
 	 */
 	public void write(ImgFileWriter writer, int tableOffset) {
-		writer.put(RESTRICTION_TYPE); 
+		writer.put1u(RESTRICTION_TYPE);
 
 		writer.put(flags);
-		writer.put((byte)0); // meaning ?
+		writer.put1u(0); // meaning ?
 
 		if(exceptMask != 0)
-			writer.put(exceptMask);
+			writer.put1u(exceptMask);
 
 		int numArcs = arcs.size();
 		int[] offsets = new int[numArcs+1];
@@ -180,10 +180,10 @@
 		}
 
 		for (int offset : offsets)
-			writer.putChar((char) offset);
+			writer.put2u(offset);
 
 		for (RouteArc arc: arcs)
-			writer.put(arc.getIndexA());
+			writer.put1u(arc.getIndexA());
 	}
 
 	/**
@@ -196,12 +196,12 @@
 			assert offset < 0x80;
 			if (last)
 				offset |= 0x80;
-			writer.put((byte) offset);
+			writer.put1u(offset);
 		} else {
 			assert offset < 0x8000;
 			if (last)
 				offset |= 0x8000;
-			writer.putChar((char) offset);
+			writer.put2u(offset);
 		}
 	}
 
@@ -224,7 +224,7 @@
 		return offsetC;
 	}
 
-	public void setOffsetSize(byte size) {
+	public void setOffsetSize(int size) {
 		offsetSize = size;
 	}
 
Index: src/uk/me/parabola/imgfmt/app/net/TableA.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/TableA.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/TableA.java	(working copy)
@@ -100,7 +100,7 @@
 	 * Retrieve an arc's index.
 	 * Order in table A: roundabouts, unpaved, ferry, paved 
 	 */
-	public byte getIndex(RouteArc arc) {
+	public int getIndex(RouteArc arc) {
 		frozen = true;			// don't allow any more arcs to be added
 		int i;
 		RoadDef rd = arc.getRoadDef();
@@ -125,7 +125,7 @@
 			i = roundaboutArcs.size() + unpavedArcs.get(rd);
 		}
 		assert i < 0x100 : "Table A index too large: " + rd;
-		return (byte) i;
+		return i;
 	}
 
 	/**
@@ -159,9 +159,9 @@
 	 * be fit for writing, so at this point we check
 	 * it isn't too large.
 	 */
-	public byte getNumberOfItems() {
+	public int getNumberOfItems() {
 		assert size() < 0x100 : "Table A too large";
-		return (byte)size();
+		return size();
 	}
 
 	/**
@@ -174,7 +174,7 @@
 		log.debug("tab a offset", offset, "tab a size", size);
 	
 		for (int i = 0; i < size; i++)
-			writer.put((byte) 0);
+			writer.put1u(0);
 	}
 
 	/**
@@ -208,8 +208,8 @@
 		final int ACCESS_TOP_BITS = 0xc000;
 		pos |= (access & ACCESS_TOP_BITS) << 8;
 		access &= ~ACCESS_TOP_BITS;
-		writer.put3(pos);
-		writer.put((byte) rd.getTabAInfo());
-		writer.put((byte) access);
+		writer.put3u(pos);
+		writer.put1u(rd.getTabAInfo());
+		writer.put1u(access);
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/net/TableB.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/TableB.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/TableB.java	(working copy)
@@ -50,9 +50,9 @@
          * be fit for writing, so at this point we check
          * it isn't too large.
          */
-	public byte getNumberOfItems() {
+	public int getNumberOfItems() {
 		assert nodes.size() < 0x100 : "Table B too large.";
-		return (byte) nodes.size();
+		return nodes.size();
 	}
 
 	/**
@@ -72,11 +72,11 @@
 	/**
 	 * Retrieve a nodes index. Checked for correct bounds.
 	 */
-	public byte getIndex(RouteNode node) {
+	public int getIndex(RouteNode node) {
 		int i = nodes.indexOf(node);
 		assert i >= 0 : "Trying to read Table B index for non-registered node.";
 		assert i < 0x100 : "Table B index too large.";
-		return (byte) i;
+		return i;
 	}
 
 	/**
@@ -87,7 +87,7 @@
 		offset = writer.position();
 		int size = nodes.size() * ITEM_SIZE;
 		for (int i = 0; i < size; i++)
-			writer.put((byte) 0);
+			writer.put1u(0);
 	}
 
 	/**
@@ -96,6 +96,6 @@
 	public void writePost(ImgFileWriter writer) {
 		writer.position(offset);
 		for (RouteNode node : nodes)
-			writer.put3(node.getOffsetNod1());
+			writer.put3u(node.getOffsetNod1());
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/net/TableC.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/net/TableC.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/net/TableC.java	(working copy)
@@ -43,18 +43,18 @@
 	public void write(ImgFileWriter writer, int tablesOffset) {
 		if (!restrictions.isEmpty()) {
 			if (size < 0x100)
-				writer.put((byte) size);
+				writer.put1u(size);
 			else
-				writer.putChar((char) size);
+				writer.put2u(size);
 			for (RouteRestriction restr : restrictions)
 				restr.write(writer, tablesOffset);
 		}
 		if(tabA.numRoundaboutArcs() > 0)
-			writer.put((byte)tabA.numRoundaboutArcs());
+			writer.put1u(tabA.numRoundaboutArcs());
 		if(tabA.numUnpavedArcs() > 0)
-			writer.put((byte)tabA.numUnpavedArcs());
+			writer.put1u(tabA.numUnpavedArcs());
 		if(tabA.numFerryArcs() > 0)
-			writer.put((byte)tabA.numFerryArcs());
+			writer.put1u(tabA.numFerryArcs());
 	}
 
 	/**
@@ -74,7 +74,7 @@
 	/**
 	 * The size of restriction indices in the nodes area.
 	 */
-	private byte getOffsetSize() {
+	private int getOffsetSize() {
 		if (size < 0x80)
 			return 1; // allows 7 bit index (8th bit is flag)
 		else if (size < 0x8000)
@@ -85,12 +85,12 @@
 	}
 
 	public void propagateSizeBytes() {
-		byte b = getOffsetSize();
+		int b = getOffsetSize();
 		for (RouteRestriction restr : restrictions)
 			restr.setOffsetSize(b);
 	}
 
-	public byte getFormat() {
+	public int getFormat() {
 		// Table C format bitmask
 		// 0x01 = 1-255 bytes of restrictions
 		// 0x02 = 256-65535 bytes of restrictions
@@ -108,6 +108,6 @@
 			format |= 0x08;
 		if(tabA.numFerryArcs() > 0)
 			format |= 0x10;
-		return (byte)format;
+		return format;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/srt/SRTFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/srt/SRTFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/srt/SRTFile.java	(working copy)
@@ -84,7 +84,7 @@
 	private void writeDescription(ImgFileWriter writer) {
 		writer.position(header.getHeaderLength() + SRTHeader.HEADER2_LEN);
 		writer.put(description.getBytes(Charset.forName("ascii")));
-		writer.put((byte) 0);
+		writer.put1u( 0);
 		header.endDescription(writer.position());
 	}
 
@@ -95,7 +95,7 @@
 	 */
 	private void writeSrt4Chars(ImgFileWriter writer) {
 		for (int i = 1; i < 256; i++) {
-			writer.put(sort.getFlags(i));
+			writer.put1u(sort.getFlags(i));
 			writeWeights(writer, i);
 		}
 		header.endCharTable(writer.position());
@@ -109,15 +109,15 @@
 			assert primary <= 0xffff;
 			assert secondary <= 0xff;
 			assert tertiary <= 0xff;
-			writer.putChar((char) primary);
-			writer.put((byte) secondary);
-			writer.put((byte) tertiary);
+			writer.put2u(primary);
+			writer.put1u(secondary);
+			writer.put1u(tertiary);
 		} else {
 			assert primary <= 0xff;
 			assert secondary <= 0xf;
 			assert tertiary <= 0xf;
-			writer.put((byte) primary);
-			writer.put((byte) ((tertiary << 4) | (secondary & 0xf)));
+			writer.put1u(primary);
+			writer.put1u((tertiary << 4) | (secondary & 0xf));
 		}
 	}
 
@@ -133,12 +133,12 @@
 		for (int j = 1; j <= size; j++) {
 			CodePosition b = sort.getExpansion(j);
 			if (isMulti) {
-				writer.putChar(b.getPrimary());
-				writer.put(b.getSecondary());
-				writer.put(b.getTertiary());
+				writer.put2u(b.getPrimary());
+				writer.put1u(b.getSecondary());
+				writer.put1u(b.getTertiary());
 			} else {
-				writer.put((byte) b.getPrimary());
-				writer.put((byte) ((b.getTertiary() << 4) | (b.getSecondary() & 0xf)));
+				writer.put1u(b.getPrimary());
+				writer.put1u((b.getTertiary() << 4) | (b.getSecondary() & 0xf));
 			}
 		}
 
@@ -148,7 +148,7 @@
 	private void writeSrt7(SectionWriter writer) {
 		assert sort.isMulti();
 		for (int i = 1; i <= sort.getMaxPage(); i++) {
-			writer.putInt(srt8Starts.get(i));
+			writer.put4(srt8Starts.get(i));
 		}
 		header.endSrt7(writer.position());
 	}
@@ -162,7 +162,7 @@
 				srt8Starts.set(p, offset);
 				for (int j = 0; j < 256; j++) {
 					int ch = p * 256 + j;
-					writer.put(sort.getFlags(ch));
+					writer.put1u(sort.getFlags(ch));
 					writeWeights(writer, ch);
 					offset += 5;
 				}
Index: src/uk/me/parabola/imgfmt/app/srt/SRTHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/srt/SRTHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/srt/SRTHeader.java	(working copy)
@@ -60,9 +60,9 @@
 	}
 
 	protected void readFileHeader(ImgFileReader reader) throws ReadFailedException {
-		reader.getChar(); // expected: 1
-		header2.setPosition(reader.getInt());
-		header2.setSize(reader.getChar());
+		reader.get2u(); // expected: 1
+		header2.setPosition(reader.get4());
+		header2.setSize(reader.get2u());
 	}
 
 	/**
@@ -71,18 +71,18 @@
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
 		if (getHeaderLength() <= 29) {
-			writer.putChar((char) 1);
+			writer.put2u(1);
 
-			writer.putInt(header2.getPosition());
-			writer.putChar((char) header2.getSize());
+			writer.put4(header2.getPosition());
+			writer.put2u(header2.getSize());
 		} else {
 			// this appears in unicode maps dated 2016 and 2017
-			writer.putChar((char) 0);
-			writer.putInt(header2.getPosition());
-			writer.putChar((char) header2.getSize());
-			writer.putChar((char) 1);
-			writer.putInt(header2.getPosition());
-			writer.putChar((char) header2.getSize());
+			writer.put2u(0);
+			writer.put4(header2.getPosition());
+			writer.put2u(header2.getSize());
+			writer.put2u(1);
+			writer.put4(header2.getPosition());
+			writer.put2u(header2.getSize());
 			
 			// older maps contain this variant (note the different order)
 //			writer.putChar((char) 1);
@@ -122,40 +122,40 @@
 	 */
 	protected void writeHeader3(ImgFileWriter writer) {
 		if (sort.isMulti()) {
-			writer.putChar((char) HEADER3_MULTI_LEN);
+			writer.put2u(HEADER3_MULTI_LEN);
 		} else {
-			writer.putChar((char) HEADER3_LEN);
+			writer.put2u(HEADER3_LEN);
 		}
 
-		writer.putChar((char) sort.getId1());
-		writer.putChar((char) sort.getId2());
-		writer.putChar((char) sort.getCodepage());
+		writer.put2u(sort.getId1());
+		writer.put2u(sort.getId2());
+		writer.put2u(sort.getCodepage());
 		if (sort.isMulti())
-			writer.putInt(0x6f02);
+			writer.put4(0x6f02);
 		else
-			writer.putInt(0x2002);
+			writer.put4(0x2002);
 
 		chartab.writeSectionInfo(writer, true, true);
-		writer.putChar((char) 0);
+		writer.put2u(0);
 
 		expansions.writeSectionInfo(writer, true, true);
-		writer.putChar((char) 0);
+		writer.put2u(0);
 
 		// SRT6 A repeat pointer to the single byte character table
-		writer.putInt(chartab.getPosition());
-		writer.putInt(0);
+		writer.put4(chartab.getPosition());
+		writer.put4(0);
 
 		if (sort.isMulti()) {
-			writer.putInt(1);
-			writer.putInt(sort.getMaxPage());  // max block in srt7
+			writer.put4(1);
+			writer.put4(sort.getMaxPage());  // max block in srt7
 
 			srt7.writeSectionInfo(writer, true);
-			writer.putChar((char) 0);
-			writer.putInt(0);
+			writer.put2u(0);
+			writer.put4(0);
 			srt8.writeSectionInfo(writer, true);
 
-			writer.putChar((char) 0);
-			writer.putInt(0);
+			writer.put2u(0);
+			writer.put4(0);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/srt/SrtFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/srt/SrtFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/srt/SrtFileReader.java	(working copy)
@@ -71,14 +71,14 @@
 	private void readTableHeader() {
 		ImgFileReader reader = getReader();
 		reader.position(tableHeader.getPosition());
-		int len = reader.getChar();
+		int len = reader.get2u();
 		sort.setHeader3Len(len);
-		sort.setId1(reader.getChar());
-		sort.setId2(reader.getChar());
-		sort.setCodepage(reader.getChar());
+		sort.setId1(reader.get2u());
+		sort.setId2(reader.get2u());
+		sort.setCodepage(reader.get2u());
 		if (sort.getCodepage() == 65001)
 			sort.setMulti(true);
-		reader.getInt(); //?
+		reader.get4(); //?
 		characterTable.readSectionInfo(reader, true);
 		reader.position(reader.position() + 6); // padding?
 		srt5.readSectionInfo(reader, true);
@@ -87,8 +87,8 @@
 			srt6.readSectionInfo(reader, false);
 		}
 		if (len > 0x34) {
-			reader.getInt();
-			int maxCodeBlock = reader.getInt();
+			reader.get4();
+			int maxCodeBlock = reader.get4();
 			sort.setMaxPage(maxCodeBlock);
 			srt7.readSectionInfo(reader, true);
 			reader.position(reader.position() + 6); // padding?
@@ -110,7 +110,7 @@
 
 		int block = 1;
 		for (int i = 0; i < srt7.getNumItems(); i++) {
-			int val = reader.getInt();
+			int val = reader.get4();
 			if (val >= 0)
 				offsetToBlock.put(val/srt8.getItemSize(), block);
 			block++;
@@ -127,7 +127,7 @@
 			Integer nblock = offsetToBlock.get(i);
 			if (nblock != null) 
 				block = nblock;
-			int flags = reader.get() & 0xff;
+			int flags = reader.get1u();
 			CodePosition cp = readCharPosition(reclen-1);
 			int ch = block*256 + (i % 256);
 			
@@ -149,7 +149,7 @@
 		long start = tableHeader.getPosition() + characterTable.getPosition();
 		reader.position(start);
 		for (int ch = 1; ch <= characterTable.getNumItems(); ch++) {
-			int flags = reader.get() & 0xff;
+			int flags = reader.get1u();
 			CodePosition cp = readCharPosition(rs-1);
 			if ((flags & 0xf0) != 0) { 
 				sort.add(ch, countExp + 1, 0, 0, flags);
@@ -172,18 +172,18 @@
 		CodePosition cp = new CodePosition();
 		int rec;
 		if (posLength == 2) {
-			rec = reader.getChar();
+			rec = reader.get2u();
 			cp.setPrimary((char) (rec & 0xff));
 			cp.setSecondary((byte) ((rec >> 8) & 0xf));
 			cp.setTertiary((byte) ((rec >> 12) & 0xf));
 			
 		} else if (posLength == 3) {
-			rec = reader.get3();
+			rec = reader.get3u();
 			cp.setPrimary((char) (rec & 0xff));
 			cp.setSecondary((byte) ((rec >> 8) & 0xf));
 			cp.setTertiary((byte) ((rec >> 12) & 0xf));
 		} else if (posLength == 4) {
-			rec = reader.getInt();
+			rec = reader.get4();
 			cp.setPrimary((char) (rec & 0xffff));
 			cp.setSecondary((byte) ((rec >> 16) & 0xff));
 			cp.setTertiary((byte) ((rec >> 24) & 0xff));
Index: src/uk/me/parabola/imgfmt/app/trergn/Overview.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Overview.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/Overview.java	(working copy)
@@ -33,9 +33,9 @@
 	public static final int SHAPE_KIND = 3;
 
 	private final int kind; // The kind of overview; point, line etc.
-	private final char extType;
-	private final char type;
-	private final char subType;
+	private final int extType;
+	private final int type;
+	private final int subType;
 	private final int minResolution;
 	private final int size;
 
@@ -44,9 +44,9 @@
 	protected Overview(int kind, int fullType, int minres) {
 		this.kind = kind;
 
-		this.extType = (char)((fullType >> 16) & 0xff);
-		this.type = (char) (fullType >> 8 & 0xff);
-		this.subType = (char) (fullType & 0xff);
+		this.extType =  fullType >> 16;
+		this.type =    (fullType >> 8) & 0xff;
+		this.subType =  fullType       & 0xff;
 		this.minResolution = minres;
 
 		if (kind == POINT_KIND)
@@ -57,15 +57,15 @@
 
 	public void write(ImgFileWriter file) {
 		if (extType == 0) {
-			file.put((byte) (type & 0xff));
-			file.put((byte) maxLevel);
+			file.put1u(type);
+			file.put1u(maxLevel);
 			if (size > 2)
-				file.put((byte) (subType & 0xff));
+				file.put1u(subType);
 		} else {
-			file.put((byte) type);
-			file.put((byte) maxLevel);
-			file.put((byte) subType);
-			file.put((byte) 0);
+			file.put1u(type);
+			file.put1u(maxLevel);
+			file.put1u(subType);
+			file.put1u(0);
 		}
 	}
 
Index: src/uk/me/parabola/imgfmt/app/trergn/Point.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Point.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/Point.java	(working copy)
@@ -49,16 +49,16 @@
 	public void write(ImgFileWriter file) {
 		boolean hasSubtype = false;
 		int type = getType();
-		byte subtype = 0;
+		int subtype = 0;
 		if (type > 0xff) {
 			if((type & 0xff) != 0) {
 			    hasSubtype = true;
-			    subtype = (byte) type;
+			    subtype = type & 0xff;
 			}
 			type >>= 8;
 		}
 
-		file.put((byte) type);
+		file.put1u(type);
 
 		int off = getLabel().getOffset();
 		if (poi != null) {
@@ -68,11 +68,11 @@
 		if (hasSubtype)
 			off |= 0x800000;
 
-		file.put3(off);
-		file.putChar((char) getDeltaLong());
-		file.putChar((char) getDeltaLat());
+		file.put3u(off);
+		file.put2s(getDeltaLong());
+		file.put2s(getDeltaLat());
 		if (hasSubtype)
-			file.put(subtype);
+			file.put1u(subtype);
 	}
 
 	/*
Index: src/uk/me/parabola/imgfmt/app/trergn/Polyline.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Polyline.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/Polyline.java	(working copy)
@@ -101,7 +101,7 @@
 		}
 
 		// The type of feature, also contains a couple of flags hidden inside.
-		byte b1 = (byte) getType();
+		int b1 = getType();
 		if (direction)
 			b1 |= FLAG_DIR;  // Polylines only.
 
@@ -111,7 +111,7 @@
 		if (blen >= 0x100)
 			b1 |= FLAG_2BYTE_LEN;
 
-		file.put(b1);
+		file.put1u(b1);
 
 		// The label, contains a couple of flags within it.
 		int loff = getLabel().getOffset();
@@ -130,19 +130,16 @@
 					roaddef.addLabel(rl);
 		}
 
-		file.put3(loff);
+		file.put3u(loff);
 
 		// The delta of the longitude from the subdivision centre point
 		// note that this has already been calculated.
-		file.putChar((char) getDeltaLong());
-		file.putChar((char) getDeltaLat());
+		file.put2s(getDeltaLong());
+		file.put2s(getDeltaLat());
 		if(log.isDebugEnabled())
 			log.debug("out center", getDeltaLat(), getDeltaLong());
 
-		if (blen < 0x100)
-			file.put((byte) (blen & 0xff));
-		else
-			file.putChar((char) (blen & 0xffff));
+		file.putNu(blen < 0x100 ? 1 : 2, blen);
 
 		file.put(bw.getBytes(), 0, blen+1);
 	}
Index: src/uk/me/parabola/imgfmt/app/trergn/RGNFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/RGNFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/RGNFile.java	(working copy)
@@ -149,7 +149,7 @@
 			if (off > 0xffff)
 				throw new IllegalStateException("IndPoint offset too large: " + off);
 
-			getWriter().putChar((char) off);
+			getWriter().put2u((int) off);
 			position(currPos);
 		}
 	}
@@ -164,7 +164,7 @@
 
 			if (log.isDebugEnabled())
 				log.debug("setting polyline offset to", off);
-			getWriter().putChar((char) off);
+			getWriter().put2u((int) off);
 
 			position(currPos);
 		}
@@ -181,7 +181,7 @@
 			if (log.isDebugEnabled())
 				log.debug("setting polygon offset to ", off, " @", polygonPtrOff);
 			position(polygonPtrOff);
-			getWriter().putChar((char) off);
+			getWriter().put2u((int) off);
 			position(currPos);
 		}
 	}
@@ -203,8 +203,8 @@
 	}
 
 	public boolean haveExtendedTypes() {
-		return (extTypePointsData != null ||
+		return extTypePointsData != null ||
 				extTypeLinesData != null ||
-				extTypeAreasData != null);
+				extTypeAreasData != null;
 	}
 }
Index: src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/RGNFileReader.java	(working copy)
@@ -100,8 +100,8 @@
 		while (position() < end) {
 			Point p = new Point(sd);
 
-			byte t = reader.get();
-			int val = reader.getu3();
+			int t = reader.get1u();
+			int val = reader.get3u();
 			boolean hasSubtype = false;
 			if ((val & 0x800000) != 0)
 				hasSubtype = true;
@@ -124,15 +124,15 @@
 			}
 			p.setLabel(l);
 
-			p.setDeltaLong((short)reader.getChar());
-			p.setDeltaLat((short)reader.getChar());
+			p.setDeltaLong(reader.get2s());
+			p.setDeltaLat(reader.get2s());
 
 			if (hasSubtype) {
-				byte st = reader.get();
-				p.setType(((t & 0xff) << 8) | (st & 0xff));
+				int st = reader.get1u();
+				p.setType((t << 8) | st);
 				//p.setHasSubtype(true);
 			} else {
-				p.setType(t & 0xff);
+				p.setType(t);
 			}
 
 			p.setNumber(number++);
@@ -151,15 +151,15 @@
 		while (position() < end) {
 			Point p = new Point(sd);
 
-			int type = reader.get() << 8;
+			int type = reader.get1u() << 8;
 			byte b = reader.get();
 			type |= 0x10000  +  (b & 0x1f);
 			p.setType(type);
-			p.setDeltaLong((short)reader.getChar());
-			p.setDeltaLat((short)reader.getChar());
+			p.setDeltaLong(reader.get2s());
+			p.setDeltaLat(reader.get2s());
 			Label l;
 			if ((b & 0x20) != 0 ){
-				int labelOffset = reader.getu3();
+				int labelOffset = reader.get3u();
 				boolean hasPoi = (labelOffset & 0x400000) != 0;
 				if (hasPoi) {
 					POIRecord record = lblFile.fetchPoi(labelOffset);
@@ -269,7 +269,7 @@
 			line.setType(type & 0x3f);
 			line.setDirection((type & 0x40) != 0);
 		}
-		int labelOffset = reader.getu3();
+		int labelOffset = reader.get3u();
 		// Extra bit (for bit stream)
 		boolean extra = (labelOffset & 0x400000) != 0;
 		Label label;
@@ -285,13 +285,13 @@
 		line.setLabel(label);
 
 
-		line.setDeltaLong((short)reader.getChar());
-		line.setDeltaLat((short)reader.getChar());
+		line.setDeltaLong(reader.get2s());
+		line.setDeltaLat(reader.get2s());
 		int len;
 		if ((type & 0x80) == 0)
-			len = reader.get() & 0xff;
+			len = reader.get1u();
 		else
-			len = reader.getChar();
+			len = reader.get2u();
 
 		int base = reader.get();
 
@@ -309,15 +309,15 @@
 	 * @param line The line or shape that is to be populated.
 	 */
 	private void readLineCommonExtType(ImgFileReader reader, Subdivision div, Polyline line) {
-		int type = reader.get();
-		type = (type & 0xff) << 8;
-		byte b1 = reader.get();
+		int type = reader.get1u();
+		type <<= 8;
+		int b1 = reader.get1u();
 		boolean hasExtraBytes = (b1 & 0x80) != 0;
 		boolean hasLabel = (b1 & 0x20) != 0;
 		type |= 0x10000  + (b1 & 0x1f);
 		line.setType(type);
-		line.setDeltaLong((short)reader.getChar());
-		line.setDeltaLat((short)reader.getChar());
+		line.setDeltaLong(reader.get2s());
+		line.setDeltaLat(reader.get2s());
 		b1 = reader.get();
 		int len;
 		// one byte or two byte length field?
@@ -326,13 +326,13 @@
 			assert len < 0x7f;
 		}
 		else {
-			byte b2 = reader.get();
-			len = (((b2 & 0xff) << 8) + (b1 & 0xff)) >> 2;
+			int b2 = reader.get1u();
+			len = ((b2 << 8) + b1) >> 2;
 			assert len >= 0x7f;
 		}
 		--len; // the encoded value includes the base field 
 		assert len > 0;
-		int base = reader.get();
+		int base = reader.get1u();
 		byte[] bitstream = reader.get(len);
 		BitReader br = new BitReader(bitstream);
 	
@@ -340,7 +340,7 @@
 		readBitStream(br, div, line, false, len, base);
 	
 		if (hasLabel){
-			int labelOffset = reader.getu3();
+			int labelOffset = reader.get3u();
 			Label label;			
 			if ((labelOffset & 0x800000) == 0) {
 				label = lblFile.fetchLabel(labelOffset & 0x7fffff);
@@ -546,17 +546,17 @@
 			pointOffset = 0;
 
 			if (sd.needsIndPointPtr()) {
-				indPointOffset = reader.getChar();
+				indPointOffset = reader.get2u();
 				headerLen += 2;
 			}
 			
 			if (sd.needsPolylinePtr()) {
-				lineOffset = reader.getChar();
+				lineOffset = reader.get2u();
 				headerLen += 2;
 			}
 
 			if (sd.needsPolygonPtr()) {
-				polygonOffset = reader.getChar();
+				polygonOffset = reader.get2u();
 				headerLen += 2;
 			}
 
Index: src/uk/me/parabola/imgfmt/app/trergn/RGNHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/RGNHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/RGNHeader.java	(working copy)
@@ -57,27 +57,27 @@
 		data.readSectionInfo(reader, false);
 
 		if (getHeaderLength() > 29){
-			extTypeAreasOffset = reader.getInt();
-			extTypeAreasSize = reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			extTypeLinesOffset = reader.getInt();
-			extTypeLinesSize = reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			extTypePointsOffset = reader.getInt();
-			extTypePointsSize = reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
-			reader.getInt();
+			extTypeAreasOffset = reader.get4();
+			extTypeAreasSize = reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			extTypeLinesOffset = reader.get4();
+			extTypeLinesSize = reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			extTypePointsOffset = reader.get4();
+			extTypePointsSize = reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
+			reader.get4();
 		}
 	}
 
@@ -91,32 +91,32 @@
 		data.writeSectionInfo(writer, false);
 
 		if (getHeaderLength() > 29) {
-			writer.putInt(extTypeAreasOffset);
-			writer.putInt(extTypeAreasSize);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
+			writer.put4(extTypeAreasOffset);
+			writer.put4(extTypeAreasSize);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
 
-			writer.putInt(extTypeLinesOffset);
-			writer.putInt(extTypeLinesSize);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
+			writer.put4(extTypeLinesOffset);
+			writer.put4(extTypeLinesSize);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
 
-			writer.putInt(extTypePointsOffset);
-			writer.putInt(extTypePointsSize);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
+			writer.put4(extTypePointsOffset);
+			writer.put4(extTypePointsSize);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
 		}
 	}
 
@@ -165,4 +165,4 @@
 	public int getExtTypePointsSize() {
 		return extTypePointsSize;
 	}
-}
\ No newline at end of file
+}
Index: src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/Subdivision.java	(working copy)
@@ -127,11 +127,19 @@
 			log.warn("Subdivision width is " + w + " at " + getCenter());
 			w = 0x7fff;
 		}
+		if (w <= 0) { // think can get this from empty/unbounded maps
+			log.error("Subdivision neg width ", w, "min=", area.getMinLong(), "mid=", longitude, "max=", area.getMaxLong(), "shift=", shift, "mask=", mask, "@", getCenter());
+			w = 0x7fff;
+		}
 
 		if (h > 0xffff) {
 			log.warn("Subdivision height is " + h + " at " + getCenter());
 			h = 0xffff;
 		}
+		if (h <= 0) { // think can get this from empty/unbounded maps
+			log.error("Subdivision neg height ", h, "min=", area.getMinLat(), "mid=", latitude, "max=", area.getMaxLat(), "shift=", shift, "mask=", mask, "@", getCenter());
+			h = 0xffff;
+		}
 
 		this.width = w;
 		this.height = h;
@@ -259,18 +267,18 @@
 	 */
 	public void write(ImgFileWriter file) {
 		log.debug("write subdiv", latitude, longitude);
-		file.put3(startRgnPointer);
-		file.put(getType());
-		file.put3(longitude);
-		file.put3(latitude);
+		file.put3u(startRgnPointer);
+		file.put1u(getType());
+		file.put3s(longitude);
+		file.put3s(latitude);
 		
 		assert width <= 0x7fff;
 		assert height <= 0xffff;
-		file.putChar((char) (width | ((last) ? 0x8000 : 0)));
-		file.putChar((char) height);
+		file.put2u(width | ((last) ? 0x8000 : 0));
+		file.put2u(height);
 
 		if (!divisions.isEmpty()) {
-			file.putChar((char) getNextLevel());
+			file.put2u(getNextLevel());
 		}
 	}
 
@@ -441,8 +449,8 @@
 	 *
 	 * @return A code showing what kinds of element are in this subdivision.
 	 */
-	private byte getType() {
-		byte b = 0;
+	private int getType() {
+		int b = 0;
 		if (hasPoints)
 			b |= 0x10;
 		if (hasIndPoints)
@@ -511,9 +519,9 @@
 	}
 
 	public void writeExtTypeOffsetsRecord(ImgFileWriter file) {
-		file.putInt(extTypeAreasOffset);
-		file.putInt(extTypeLinesOffset);
-		file.putInt(extTypePointsOffset);
+		file.put4(extTypeAreasOffset);
+		file.put4(extTypeLinesOffset);
+		file.put4(extTypePointsOffset);
 		int kinds = 0;
 		if(extTypeAreasSize != 0)
 			++kinds;
@@ -521,14 +529,14 @@
 			++kinds;
 		if(extTypePointsSize != 0)
 			++kinds;
-		file.put((byte)kinds);
+		file.put1u(kinds);
 	}
 
 	public void writeLastExtTypeOffsetsRecord(ImgFileWriter file) {
-		file.putInt(rgnFile.getExtTypeAreasSize());
-		file.putInt(rgnFile.getExtTypeLinesSize());
-		file.putInt(rgnFile.getExtTypePointsSize());
-		file.put((byte)0);
+		file.put4(rgnFile.getExtTypeAreasSize());
+		file.put4(rgnFile.getExtTypeLinesSize());
+		file.put4(rgnFile.getExtTypePointsSize());
+		file.put1u(0);
 	}
 
 	/**
@@ -539,11 +547,11 @@
 	 */
 	public void readExtTypeOffsetsRecord(ImgFileReader reader,
 			Subdivision sdPrev, int size) {
-		extTypeAreasOffset = reader.getInt();
-		extTypeLinesOffset = reader.getInt();
-		extTypePointsOffset = reader.getInt();
+		extTypeAreasOffset = reader.get4();
+		extTypeLinesOffset = reader.get4();
+		extTypePointsOffset = reader.get4();
 		if (size > 12) {
-			int kinds = reader.get();
+			reader.get();  // kinds
 		}
 		if (size > 13)
 			reader.get(size-13);
@@ -564,9 +572,9 @@
 	 * Set the sizes for the extended type data. See {@link #writeLastExtTypeOffsetsRecord(ImgFileWriter)} 
 	 */
 	public void readLastExtTypeOffsetsRecord(ImgFileReader reader, int size) {
-		extTypeAreasSize = reader.getInt() - extTypeAreasOffset;
-		extTypeLinesSize = reader.getInt() - extTypeLinesOffset;
-		extTypePointsSize = reader.getInt() - extTypePointsOffset;
+		extTypeAreasSize = reader.get4() - extTypeAreasOffset;
+		extTypeLinesSize = reader.get4() - extTypeLinesOffset;
+		extTypePointsSize = reader.get4() - extTypePointsOffset;
 		assert extTypeAreasSize >= 0;
 		assert extTypeLinesSize >= 0;
 		assert extTypePointsSize >= 0;
Index: src/uk/me/parabola/imgfmt/app/trergn/TREFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/TREFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/TREFile.java	(working copy)
@@ -91,7 +91,7 @@
 
 		header.setMapInfoSize(header.getMapInfoSize() + enc.getLength() + 1);
 		getWriter().put(val);
-		getWriter().put((byte) 0);
+		getWriter().put1u(0);
 	}
 
 	public void addCopyright(Label cr) {
@@ -175,7 +175,7 @@
 					header.setSubdivSize(header.getSubdivSize() + TREHeader.SUBDIV_REC_SIZE);
 			}
 		}
-		getWriter().putInt(lastRgnPos);
+		getWriter().put4(lastRgnPos);
 		header.setSubdivSize(header.getSubdivSize() + 4);
 	}
 
@@ -330,7 +330,7 @@
 		ImgFileWriter writer = getWriter();
 		for (Label l : copyrights) {
 			header.incCopyrightSize();
-			writer.put3(l.getOffset());
+			writer.put3u(l.getOffset());
 		}
 	}
 
@@ -354,10 +354,14 @@
 	}
 
 	public void setBounds(Area area) {
+		assert Math.abs(area.getMinLat())  <= 0x7fffff : "minlat=" + area.getMinLat();
+		assert Math.abs(area.getMaxLat())  <= 0x7fffff : "maxlat=" + area.getMaxLat();
+		assert Math.abs(area.getMinLong()) <= 0x7fffff : "minlong=" + area.getMinLong();
+		assert Math.abs(area.getMaxLong()) <= 0x7fffff : "maxlong=" + area.getMaxLong();
 		header.setBounds(area);
 	}
 
-	public void addPoiDisplayFlags(byte b) {
+	public void addPoiDisplayFlags(int b) {
 		header.addPoiDisplayFlags(b);
 	}
 
Index: src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/TREFileReader.java	(working copy)
@@ -94,7 +94,7 @@
 		reader.position(start);
 
 		int subdivNum = 1;
-		int lastRgnOffset = reader.getu3();
+		int lastRgnOffset = reader.get3u();
 		for (int count = 0; count < levelDivs.length && reader.position() < end; count++) {
 
 			Subdivision[] divs = levelDivs[count];
@@ -103,19 +103,20 @@
 				break;
 
 			for (int i = 0; i < divs.length; i++) {
-				int flags = reader.get();
-				int lon = reader.get3();
-				int lat = reader.get3();
-				int width = reader.getChar() & 0x7fff;
-				int height = reader.getChar() & 0xffff;
+				int flags = reader.get1u();
+				int lon = reader.get3s();
+				int lat = reader.get3s();
+				int width = reader.get2u() & 0x7fff;
+				int height = reader.get2u();
 
 				if (count < levelDivs.length-1)
-					reader.getChar();
+					reader.get2u();
 
-				int endRgnOffset = reader.getu3();
+				int endRgnOffset = reader.get3u();
 
 				SubdivData subdivData = new SubdivData(flags,
-						lat, lon, 2*width, 2*height,
+// why???					lat, lon, 2*width, 2*height,
+						lat, lon, width, height,
 						lastRgnOffset, endRgnOffset);
 
 				Subdivision subdiv = Subdivision.readSubdivision(mapLevels[count], subdivData);
@@ -174,9 +175,9 @@
 		List<Zoom> mapLevels = new ArrayList<Zoom>();
 		int end = levelsPos + levelsSize;
 		while (reader.position() < end) {
-			int level = reader.get();
-			int nbits = reader.get();
-			int ndivs = reader.getChar();
+			int level = reader.get1u();
+			int nbits = reader.get1u();
+			int ndivs = reader.get2u();
 
 			Subdivision[] divs = new Subdivision[ndivs];
 			levelDivs.add(divs);
@@ -227,7 +228,7 @@
 		long pos = sect.getPosition();
 		while (pos < sect.getEndPos()) {
 			reader.position(pos);
-			int offset = reader.get3();
+			int offset = reader.get3s();
 			Label label = lblReader.fetchLabel(offset);
 			if (label != null) {
 				msgs.add(label.getText());
Index: src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/TREHeader.java	(working copy)
@@ -72,7 +72,7 @@
 	private int subdivPos;
 	private int subdivSize;
 
-	private byte poiDisplayFlags;
+	private int poiDisplayFlags;
 
 	private int displayPriority = DEFAULT_DISPLAY_PRIORITY;
 
@@ -104,10 +104,10 @@
 	 */
 	protected void readFileHeader(ImgFileReader reader) throws ReadFailedException {
 		assert reader.position() == COMMON_HEADER_LEN;
-		int maxLat = reader.get3();
-		int maxLon = reader.get3();
-		int minLat = reader.get3();
-		int minLon = reader.get3();
+		int maxLat = reader.get3s();
+		int maxLon = reader.get3s();
+		int minLat = reader.get3s();
+		int minLon = reader.get3s();
 		// fix problem with value 0x800000 that is interpreted as a negative value
 		if (maxLon <  minLon && maxLon == -8388608 )
 			maxLon = 8388608; // its 180 degrees, not -180
@@ -116,26 +116,26 @@
 		log.info("read area is", getBounds());
 
 		// more to do...
-		mapLevelPos = reader.getInt();
-		mapLevelsSize = reader.getInt();
-		subdivPos = reader.getInt();
-		subdivSize = reader.getInt();
+		mapLevelPos = reader.get4();
+		mapLevelsSize = reader.get4();
+		subdivPos = reader.get4();
+		subdivSize = reader.get4();
 
 		copyright.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
-		poiDisplayFlags = reader.get();
-		displayPriority = reader.get3();
-		reader.getInt();
-		reader.getChar();
+		poiDisplayFlags = reader.get1u();
+		displayPriority = reader.get3u();
+		reader.get4();
+		reader.get2u();
 		reader.get();
 
 		polyline.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 		polygon.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 		points.readSectionInfo(reader, true);
-		reader.getInt();
+		reader.get4();
 
 		int mapInfoOff = mapLevelPos;
 		if (subdivPos < mapInfoOff)
@@ -146,10 +146,10 @@
 		mapInfoSize = mapInfoOff - getHeaderLength();
 		if (getHeaderLength() > 116) {
 			reader.position(116);
-			mapId = reader.getInt();
+			mapId = reader.get4();
 		}
 		if (getHeaderLength() > 120) {
-			reader.getInt();
+			reader.get4();
 			extTypeOffsets.readSectionInfo(reader, true);
 		}
 	}
@@ -161,44 +161,44 @@
 	 * @param writer The header is written here.
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
-		writer.put3(area.getMaxLat());
-		writer.put3(area.getMaxLong());
-		writer.put3(area.getMinLat());
-		writer.put3(area.getMinLong());
+		writer.put3s(area.getMaxLat());
+		writer.put3s(area.getMaxLong());
+		writer.put3s(area.getMinLat());
+		writer.put3s(area.getMinLong());
 
-		writer.putInt(getMapLevelsPos());
-		writer.putInt(getMapLevelsSize());
+		writer.put4(getMapLevelsPos());
+		writer.put4(getMapLevelsSize());
 
-		writer.putInt(getSubdivPos());
-		writer.putInt(getSubdivSize());
+		writer.put4(getSubdivPos());
+		writer.put4(getSubdivSize());
 
 		copyright.writeSectionInfo(writer);
-		writer.putInt(0);
+		writer.put4(0);
 
-		writer.put(getPoiDisplayFlags());
+		writer.put1u(getPoiDisplayFlags());
 
-		writer.put3(displayPriority);
+		writer.put3u(displayPriority);
 		if (custom)
-			writer.putInt(0x170401);
+			writer.put4(0x170401);
 		else
-			writer.putInt(0x110301);
+			writer.put4(0x110301);
 		
-		writer.putChar((char) 1);
-		writer.put((byte) 0);
+		writer.put2u(1);
+		writer.put1u(0);
 
 		polyline.writeSectionInfo(writer);
-		writer.putInt(0);
+		writer.put4(0);
 		polygon.writeSectionInfo(writer);
-		writer.putInt(0);
+		writer.put4(0);
 		points.writeSectionInfo(writer);
-		writer.putInt(0);
+		writer.put4(0);
 
 		// There are a number of versions of the header with increasing lengths
 		if (getHeaderLength() > 116)
-			writer.putInt(getMapId());
+			writer.put4(getMapId());
 
 		if (getHeaderLength() > 120) {
-			writer.putInt(0);
+			writer.put4(0);
 
 			// The record size must be zero if the section is empty for compatibility
 			// with cpreview.
@@ -213,27 +213,27 @@
 			// bottom byte could possibly be a bitmask to say which
 			// types are present (line, area, point) but this is just
 			// conjecture
-			writer.putInt(0x0607);
+			writer.put4(0x0607);
 
 			extTypeOverviews.writeSectionInfo(writer);
-			writer.putChar((char)numExtTypeLineTypes);
-			writer.putChar((char)numExtTypeAreaTypes);
-			writer.putChar((char)numExtTypePointTypes);
+			writer.put2u(numExtTypeLineTypes);
+			writer.put2u(numExtTypeAreaTypes);
+			writer.put2u(numExtTypePointTypes);
 		}
 
 		if (getHeaderLength() > 154) {
 			MapValues mv = new MapValues(mapId, getHeaderLength());
 			mv.calculate();
-			writer.putInt(mv.value(0));
-			writer.putInt(mv.value(1));
-			writer.putInt(mv.value(2));
-			writer.putInt(mv.value(3));
+			writer.put4(mv.value(0));
+			writer.put4(mv.value(1));
+			writer.put4(mv.value(2));
+			writer.put4(mv.value(3));
 
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putInt(0);
-			writer.putChar((char) 0);
-			writer.putInt(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put4(0);
+			writer.put2u(0);
+			writer.put4(0);
 		}
 		
 		writer.position(getHeaderLength());
@@ -271,7 +271,7 @@
 			this.poiDisplayFlags |= POI_FLAG_DRIVE_ON_LEFT; 
 	}
 
-	public void addPoiDisplayFlags(byte poiDisplayFlags) {
+	public void addPoiDisplayFlags(int poiDisplayFlags) {
 		this.poiDisplayFlags |= poiDisplayFlags;
 	}	
 
@@ -324,7 +324,7 @@
 		copyright.inc();
 	}
 
-	protected byte getPoiDisplayFlags() {
+	protected int getPoiDisplayFlags() {
 		return poiDisplayFlags;
 	}
 
Index: src/uk/me/parabola/imgfmt/app/trergn/Zoom.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/trergn/Zoom.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/trergn/Zoom.java	(working copy)
@@ -76,9 +76,9 @@
 	}
 
 	public void write(ImgFileWriter file) {
-		file.put((byte) ((level & 0xf) | (inherited ? 0x80 : 0)));
-		file.put((byte) resolution);
-		file.putChar((char) subdivs.size());
+		file.put1u((level & 0xf) | (inherited ? 0x80 : 0));
+		file.put1u(resolution);
+		file.put2u(subdivs.size());
 	}
 
 	public String toString() {
Index: src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/DrawOrder.java	(working copy)
@@ -21,8 +21,8 @@
 	}
 
 	public void write(ImgFileWriter writer) {
-		writer.put(type);
-		writer.putInt(subTypes);
+		writer.put1u(type);
+		writer.put4(subTypes);
 	}
 
 	public void addSubtype(int subtype) {
Index: src/uk/me/parabola/imgfmt/app/typ/Rgb.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/Rgb.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/Rgb.java	(working copy)
@@ -53,9 +53,9 @@
 	public void write(ImgFileWriter writer, byte type) {
 		if (type != 0x10)
 			throw new FormatException("Invalid color deep");
-		writer.put((byte) b);
-		writer.put((byte) g);
-		writer.put((byte) r);
+		writer.put1u(b);
+		writer.put1u(g);
+		writer.put1u(r);
 	}
 
 	public boolean isTransparent() {
Index: src/uk/me/parabola/imgfmt/app/typ/TYPFile.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TYPFile.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TYPFile.java	(working copy)
@@ -104,7 +104,7 @@
 		Collections.sort(keys);
 
 		// Offset 0 is reserved to mean no label.
-		writer.put((byte) 0);
+		writer.put1u((byte) 0);
 
 		for (SortKey<TypIconSet> key : keys) {
 			int off = writer.position();
@@ -127,7 +127,7 @@
 					String name = encoder.charset().name();
 					throw new TypLabelException(name);
 				}
-				writer.put((byte) 0);
+				writer.put1u((byte) 0);
 			}
 		}
 		Utils.closeFile(writer);
@@ -139,8 +139,8 @@
 		header.getStringIndex().setItemSize((char) (3 + psize));
 
 		for (Map.Entry<Integer, Integer> ent : strToType.entrySet()) {
-			writer.putN(psize, ent.getKey());
-			writer.put3(ent.getValue());
+			writer.putNu(psize, ent.getKey());
+			writer.put3u(ent.getValue());
 		}
 		Utils.closeFile(writer);
 	}
@@ -151,8 +151,8 @@
 		header.getTypeIndex().setItemSize((char) (3 + psize));
 
 		for (Map.Entry<Integer, Integer> ent : typeToStr.entrySet()) {
-			writer.put3(ent.getKey());
-			writer.putN(psize, ent.getValue());
+			writer.put3u(ent.getKey());
+			writer.putNu(psize, ent.getValue());
 		}
 		Utils.closeFile(writer);
 	}
@@ -178,8 +178,8 @@
 		for (TypElement elem : elementData) {
 			int offset = elem.getOffset();
 			int type = elem.getTypeForFile();
-			subWriter.putN(typeSize, type);
-			subWriter.putN(psize, offset);
+			subWriter.putNu(typeSize, type);
+			subWriter.putNu(psize, offset);
 		}
 		Utils.closeFile(subWriter);
 
Index: src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TYPHeader.java	(working copy)
@@ -37,14 +37,14 @@
 	private final Section lineData = new Section(pointData);
 	private final Section polygonData = new Section(lineData);
 
-	private final Section pointIndex = new Section(polygonData, (char) 2);
-	private final Section lineIndex = new Section(pointIndex, (char) 2);
-	private final Section polygonIndex = new Section(lineIndex, (char) 2);
+	private final Section pointIndex = new Section(polygonData, 2);
+	private final Section lineIndex = new Section(pointIndex, 2);
+	private final Section polygonIndex = new Section(lineIndex, 2);
 
-	private final Section shapeStacking = new Section(polygonIndex, (char) 5);
+	private final Section shapeStacking = new Section(polygonIndex, 5);
 
 	private final Section iconData = new Section(polygonIndex);
-	private final Section iconIndex = new Section(iconData, (char) 3);
+	private final Section iconIndex = new Section(iconData, 3);
 
 	private final Section labels = new Section(iconIndex);
 	private final Section stringIndex = new Section(labels);
@@ -64,34 +64,34 @@
 	protected void readFileHeader(ImgFileReader reader) {
 		// Reset position for the real header reading code.
 		reader.position(COMMON_HEADER_LEN);
-		codePage = reader.getChar();	// 1252
-		pointData.setPosition(reader.getInt());
-		pointData.setSize(reader.getInt());
+		codePage = (char) reader.get2u();	// 1252
+		pointData.setPosition(reader.get4());
+		pointData.setSize(reader.get4());
 
-		lineData.setPosition(reader.getInt());
-		lineData.setSize(reader.getInt());
+		lineData.setPosition(reader.get4());
+		lineData.setSize(reader.get4());
 
-		polygonData.setPosition(reader.getInt());
-		polygonData.setSize(reader.getInt());
+		polygonData.setPosition(reader.get4());
+		polygonData.setSize(reader.get4());
 
-		familyId = reader.getChar();
-		productId = reader.getChar();
+		familyId = (char) reader.get2u();
+		productId = (char) reader.get2u();
 
-		pointIndex.setPosition(reader.getInt());
-		pointIndex.setItemSize(reader.getChar());
-		pointIndex.setSize(reader.getInt());
+		pointIndex.setPosition(reader.get4());
+		pointIndex.setItemSize(reader.get2u());
+		pointIndex.setSize(reader.get4());
 
-		lineIndex.setPosition(reader.getInt());
-		lineIndex.setItemSize(reader.getChar());
-		lineIndex.setSize(reader.getInt());
+		lineIndex.setPosition(reader.get4());
+		lineIndex.setItemSize(reader.get2u());
+		lineIndex.setSize(reader.get4());
 
-		polygonIndex.setPosition(reader.getInt());
-		polygonIndex.setItemSize(reader.getChar());
-		polygonIndex.setSize(reader.getInt());
+		polygonIndex.setPosition(reader.get4());
+		polygonIndex.setItemSize(reader.get2u());
+		polygonIndex.setSize(reader.get4());
 
-		shapeStacking.setPosition(reader.getInt());
-		shapeStacking.setItemSize(reader.getChar());
-		shapeStacking.setSize(reader.getInt());
+		shapeStacking.setPosition(reader.get4());
+		shapeStacking.setItemSize(reader.get2u());
+		shapeStacking.setSize(reader.get4());
 	}
 
 	/**
@@ -103,14 +103,14 @@
 	 * @param writer The header is written here.
 	 */
 	protected void writeFileHeader(ImgFileWriter writer) {
-		writer.putChar(codePage);
+		writer.put2u(codePage);
 
 		pointData.writeSectionInfo(writer);
 		lineData.writeSectionInfo(writer);
 		polygonData.writeSectionInfo(writer);
 
-		writer.putChar(familyId);
-		writer.putChar(productId);
+		writer.put2u(familyId);
+		writer.put2u(productId);
 
 		// Can't use Section.writeSectionInfo here as there is an unusual layout.
 		writeSectionInfo(writer, pointIndex);
@@ -120,9 +120,9 @@
 
 		if (getHeaderLength() > 0x5b) {
 			writeSectionInfo(writer, iconIndex);
-			writer.put((byte) 0x13);
+			writer.put1u(0x13);
 			iconData.writeSectionInfo(writer);
-			writer.putInt(0);
+			writer.put4(0);
 		}
 
 		if (getHeaderLength() > 0x6e) {
@@ -129,17 +129,17 @@
 			labels.writeSectionInfo(writer);
 
 			// not known, guessing. Different layout to other files.
-			writer.putInt(stringIndex.getItemSize());
-			writer.putInt(0x1b);
-			writer.putInt(stringIndex.getPosition());
-			writer.putInt(stringIndex.getSize());
+			writer.put4(stringIndex.getItemSize());
+			writer.put4(0x1b);
+			writer.put4(stringIndex.getPosition());
+			writer.put4(stringIndex.getSize());
 
-			writer.putInt(typeIndex.getItemSize());
-			writer.putInt(0x1b);
-			writer.putInt(typeIndex.getPosition());
-			writer.putInt(typeIndex.getSize());
+			writer.put4(typeIndex.getItemSize());
+			writer.put4(0x1b);
+			writer.put4(typeIndex.getPosition());
+			writer.put4(typeIndex.getSize());
 
-			writer.putChar((char) 0);
+			writer.put2u(0);
 		}
 	}
 
@@ -148,9 +148,9 @@
 	 * that have an item size.
 	 */
 	private void writeSectionInfo(ImgFileWriter writer, Section section) {
-		writer.putInt(section.getPosition());
-		writer.putChar(section.getItemSize());
-		writer.putInt(section.getSize());
+		writer.put4(section.getPosition());
+		writer.put2u(section.getItemSize());
+		writer.put4(section.getSize());
 	}
 
 	void setCodePage(char codePage) {
Index: src/uk/me/parabola/imgfmt/app/typ/TrueImage.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TrueImage.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TrueImage.java	(working copy)
@@ -51,9 +51,9 @@
 
 		// For mode 16, the transparent pixel precedes the pixmap data.
 		if (mode == 16) {
-			writer.put((byte) (transparentPixel>>8));
-			writer.put((byte) (transparentPixel>>16));
-			writer.put((byte) (transparentPixel>>24));
+			writer.put1u(transparentPixel>>8);
+			writer.put1u(transparentPixel>>16);
+			writer.put1u(transparentPixel>>24);
 		}
 
 		boolean hasAlpha = mode == 32;
Index: src/uk/me/parabola/imgfmt/app/typ/TypElement.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypElement.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TypElement.java	(working copy)
@@ -159,9 +159,9 @@
 
 		// write out the length, I'm assuming that it will be 1 or 2 bytes
 		if (len > 0xff)
-			writer.putChar((char) len);
+			writer.put2u(len);
 		else
-			writer.put((byte) len);
+			writer.put1u(len);
 
 		// Prepare and write buffer
 		out.flip();
@@ -181,7 +181,7 @@
 		if (nightFontColour != null)
 			fontExt |= 0x10;
 
-		writer.put(fontExt);
+		writer.put1u(fontExt);
 
 		if (dayFontColour != null)
 			dayFontColour.write(writer, (byte) 0x10);
@@ -199,8 +199,8 @@
 	protected void writeImage(ImgFileWriter writer, Xpm xpm) {
 		ColourInfo colourInfo = xpm.getColourInfo();
 
-		writer.put((byte) colourInfo.getNumberOfSColoursForCM());
-		writer.put((byte) colourInfo.getColourMode());
+		writer.put1u(colourInfo.getNumberOfSColoursForCM());
+		writer.put1u(colourInfo.getColourMode());
 
 		colourInfo.write(writer);
 		xpm.writeImage(writer);
Index: src/uk/me/parabola/imgfmt/app/typ/TypIconSet.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypIconSet.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TypIconSet.java	(working copy)
@@ -31,15 +31,15 @@
 		offset = writer.position();
 
 		// Start with the number of icons
-		writer.put((byte) icons.size());
+		writer.put1u(icons.size());
 
 		for (Xpm xpm : icons) {
 			ColourInfo colourInfo = xpm.getColourInfo();
 			int nbits = calcBits(colourInfo);
-			writer.putChar((char) (nbits/2));
-			writer.put((byte) 1);
-			writer.put((byte) colourInfo.getWidth());
-			writer.put((byte) colourInfo.getHeight());
+			writer.put2u(nbits/2);
+			writer.put1u(1);
+			writer.put1u(colourInfo.getWidth());
+			writer.put1u(colourInfo.getHeight());
 			writeImage(writer, xpm);
 		}
 	}
Index: src/uk/me/parabola/imgfmt/app/typ/TypLine.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypLine.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TypLine.java	(working copy)
@@ -60,8 +60,8 @@
 		ColourInfo colourInfo = xpm.getColourInfo();
 		int scheme = colourInfo.getColourScheme() & 0x7;
 
-		writer.put((byte) ((scheme & 0x7) | (height << 3)));
-		writer.put(flags);
+		writer.put1u((scheme & 0x7) | (height << 3));
+		writer.put1u(flags);
 
 		colourInfo.write(writer);
 		if (xpm.hasImage())
@@ -68,9 +68,9 @@
 			xpm.writeImage(writer);
 
 		if (height == 0) {
-			writer.put(lineWidth);
+			writer.put1u(lineWidth);
 			if ((scheme&~1) != 6)
-				writer.put((byte) (lineWidth + 2*borderWidth));
+				writer.put1u(lineWidth + 2*borderWidth);
 		}
 
 		// The labels have a length byte to show the number of bytes following. There is
Index: src/uk/me/parabola/imgfmt/app/typ/TypPoint.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypPoint.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TypPoint.java	(working copy)
@@ -42,12 +42,12 @@
 		if (fontStyle != 0 || dayFontColour != null || nightFontColour != null)
 			flags |= F_EXTENDED_FONT;
 
-		writer.put(flags);
+		writer.put1u(flags);
 
 		// Width and height is the same for day and night images, so it is written once only.
 		ColourInfo colourInfo = xpm.getColourInfo();
-		writer.put((byte) colourInfo.getWidth());
-		writer.put((byte) colourInfo.getHeight());
+		writer.put1u(colourInfo.getWidth());
+		writer.put1u(colourInfo.getHeight());
 
 		// Day or only image
 		writeImage(writer, xpm);
Index: src/uk/me/parabola/imgfmt/app/typ/TypPolygon.java
===================================================================
--- src/uk/me/parabola/imgfmt/app/typ/TypPolygon.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/app/typ/TypPolygon.java	(working copy)
@@ -36,7 +36,7 @@
 		if (fontStyle != 0 || dayFontColour != null)
 			scheme |= F_EXTENDED;
 
-		writer.put((byte) scheme);
+		writer.put1u(scheme);
 
 		colourInfo.write(writer);
 		if (xpm.hasImage())
Index: src/uk/me/parabola/imgfmt/mdxfmt/MdxFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/mdxfmt/MdxFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/mdxfmt/MdxFileReader.java	(working copy)
@@ -41,19 +41,19 @@
 	private void readMaps() {
 		for (int i = 0; i < numberOfMaps; i++) {
 			MapInfo info = new MapInfo();
-			info.setHexMapname(reader.getInt());
-			info.setProductId(reader.getChar());
-			info.setFamilyId(reader.getChar());
-			info.setMapname(reader.getInt());
+			info.setHexMapname(reader.get4());
+			info.setProductId((char) reader.get2u());
+			info.setFamilyId((char) reader.get2u());
+			info.setMapname(reader.get4());
 			maps.add(info);
 		}
 	}
 
 	private void readHeader() {
-		reader.getInt();
-		reader.getChar();
-		reader.getInt();
-		numberOfMaps = reader.getInt();
+		reader.get4();
+		reader.get2u();
+		reader.get4();
+		numberOfMaps = reader.get4();
 	}
 
 	public List<MapInfo> getMaps() {
Index: src/uk/me/parabola/imgfmt/mps/MpsFileReader.java
===================================================================
--- src/uk/me/parabola/imgfmt/mps/MpsFileReader.java	(revision 4130)
+++ src/uk/me/parabola/imgfmt/mps/MpsFileReader.java	(working copy)
@@ -60,7 +60,7 @@
 	private void readBlocks() {
 		byte type;
 		while ((type = reader.get()) > 0) {
-			int len = reader.getChar();
+			int len = reader.get2u();
 
 			switch (type) {
 			case 0x4c:
@@ -79,23 +79,23 @@
 
 	private void readMapBlock() {
 		MapBlock block = new MapBlock(codePage);
-		int val = reader.getInt();
+		int val = reader.get4();
 		block.setIds(val >>> 16, val & 0xffff);
-		block.setMapNumber(reader.getInt());
+		block.setMapNumber(reader.get4());
 
 		byte[] zString = reader.getZString();
 		block.setSeriesName(decodeToString(zString));
 		block.setMapDescription(decodeToString(reader.getZString()));
 		block.setAreaName(decodeToString(reader.getZString()));
-		block.setHexNumber(reader.getInt());
-		reader.getInt();
+		block.setHexNumber(reader.get4());
+		reader.get4();
 		maps.add(block);
 	}
 
 	private void readProductBlock() {
 		ProductBlock block = new ProductBlock(codePage);
-		block.setProductId(reader.getChar());
-		block.setFamilyId(reader.getChar());
+		block.setProductId(reader.get2u());
+		block.setFamilyId(reader.get2u());
 		block.setDescription(decodeToString(reader.getZString()));
 		products.add(block);
 	}
Index: src/uk/me/parabola/mkgmap/build/MapBuilder.java
===================================================================
--- src/uk/me/parabola/mkgmap/build/MapBuilder.java	(revision 4130)
+++ src/uk/me/parabola/mkgmap/build/MapBuilder.java	(working copy)
@@ -1136,7 +1136,7 @@
 					if(pointIndex > 255) {
 						System.err.println("Can't set city point index for " + name + " (too many indexed points in division)\n");
 					} else {
-						c.setPointIndex((byte)pointIndex);
+						c.setPointIndex(pointIndex);
 						c.setSubdivision(div);
 					}
 				}
Index: src/uk/me/parabola/mkgmap/combiners/FileInfo.java
===================================================================
--- src/uk/me/parabola/mkgmap/combiners/FileInfo.java	(revision 4130)
+++ src/uk/me/parabola/mkgmap/combiners/FileInfo.java	(working copy)
@@ -195,7 +195,7 @@
 		try (ImgChannel chan = new FileImgChannel(filename, "r"); BufferedImgFileReader fr = new BufferedImgFileReader(chan))
 		{
 			fr.position(0x15);
-			info.setCodePage(fr.getChar());
+			info.setCodePage(fr.get2u());
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
Index: src/uk/me/parabola/mkgmap/general/MapDetails.java
===================================================================
--- src/uk/me/parabola/mkgmap/general/MapDetails.java	(revision 4130)
+++ src/uk/me/parabola/mkgmap/general/MapDetails.java	(working copy)
@@ -159,6 +159,8 @@
 	 * @return An area covering all the points in the map.
 	 */
 	public Area getBounds() {
+		if (minLatHp == Integer.MAX_VALUE) // nothing called addToBounds
+			return new Area(1, 1, -1, -1); // return invalid bbox that doesn't break signed 3 byte IO in img file
 		int minLat = minLatHp >> Coord.DELTA_SHIFT;
 		int maxLat = maxLatHp >> Coord.DELTA_SHIFT;
 		int minLon = minLonHp >> Coord.DELTA_SHIFT;
Index: test/func/lib/ArrayImgWriter.java
===================================================================
--- test/func/lib/ArrayImgWriter.java	(revision 4130)
+++ test/func/lib/ArrayImgWriter.java	(working copy)
@@ -41,44 +41,66 @@
 		out.write(b);
 	}
 
-	public void putChar(char c) {
-		out.write(c & 0xff);
-		out.write((c >> 8) & 0xff);
+	public void put1s(int val) {
+		assert val >= -128 && val <= 127 : val;
+		out.write(val);
 	}
 
-	public void put1(int val) {
-		out.write(val & 0xff);
+	public void put2s(int val) {
+		assert val >= -32768 && val <= 32767 : val;
+		out.write(val);
+		out.write(val >> 8);
 	}
 
-	public void put2(int val) {
-		out.write(val & 0xff);
-		out.write((val >> 8) & 0xff);
+	public void put3s(int val) {
+		assert val >= -0x800000 && val <= 0x7fffff : val;
+		out.write(val);
+		out.write(val >> 8);
+		out.write(val >> 16);
 	}
 
-	public void put3(int val) {
-		out.write(val & 0xff);
-		out.write((val >> 8) & 0xff);
-		out.write((val >> 16) & 0xff);
+	public void put1u(int val) {
+		assert val >= 0 && val <= 255 : val;
+		out.write(val);
 	}
 
-	public void putN(int nBytes, int val) {
-		out.write(val & 0xff);
-		if (nBytes <= 1)
+	public void put2u(int val) {
+		assert val >= 0 && val <= 65535 : val;
+		out.write(val);
+		out.write(val >> 8);
+	}
+
+	public void put3u(int val) {
+		assert val >= 0 && val <= 0xffffff : val;
+		out.write(val);
+		out.write(val >> 8);
+		out.write(val >> 16);
+	}
+
+	public void putNu(int nBytes, int val) {
+		out.write(val);
+		if (nBytes <= 1) {
+			assert val >= 0 && val <= 255 : val;
 			return;
-		out.write((val >> 8) & 0xff);
-		if (nBytes <= 2)
+		}
+		out.write(val >> 8);
+		if (nBytes <= 2) {
+			assert val >= 0 && val <= 65535 : val;
 			return;
-		out.write((val >> 16) & 0xff);
-		if (nBytes <= 3)
+		}
+		out.write(val >> 16);
+		if (nBytes <= 3) {
+			assert val >= 0 && val <= 0xffffff : val;
 			return;
-		out.write((val >> 24) & 0xff);
+		}
+		out.write(val >> 24);
 	}
 
-	public void putInt(int val) {
-		out.write(val & 0xff);
-		out.write((val >> 8) & 0xff);
-		out.write((val >> 16) & 0xff);
-		out.write((val >> 24) & 0xff);
+	public void put4(int val) {
+		out.write(val);
+		out.write(val >> 8);
+		out.write(val >> 16);
+		out.write(val >> 24);
 	}
 
 	public void put(byte[] val) {
