This is an automated email from the git hooks/post-receive script. sebastic pushed a commit to branch master in repository mkgmap.
commit 8bcef4e1565c1a1328f311f033b36d369aba7211 Author: Bas Couwenberg <[email protected]> Date: Mon Aug 1 10:26:23 2016 +0200 Imported Upstream version 0.0.0+svn3686 --- resources/mkgmap-version.properties | 4 +- resources/styles/default/inc/landuse_polygons | 1 + src/uk/me/parabola/imgfmt/app/BitWriter.java | 23 +++ .../parabola/imgfmt/app/trergn/LinePreparer.java | 204 ++++++++++++--------- src/uk/me/parabola/imgfmt/app/trergn/Polyline.java | 4 +- .../parabola/mkgmap/combiners/OverviewBuilder.java | 72 +++++++- .../mkgmap/filters/PolygonSplitterBase.java | 2 +- .../filters/PolygonSubdivSizeSplitterFilter.java | 4 + .../mkgmap/filters/RemoveObsoletePointsFilter.java | 24 ++- .../mkgmap/reader/osm/MultiPolygonRelation.java | 12 +- test/uk/me/parabola/imgfmt/app/BitReaderTest.java | 21 +++ 11 files changed, 260 insertions(+), 111 deletions(-) diff --git a/resources/mkgmap-version.properties b/resources/mkgmap-version.properties index 491d833..9f219a3 100644 --- a/resources/mkgmap-version.properties +++ b/resources/mkgmap-version.properties @@ -1,2 +1,2 @@ -svn.version: 3677 -build.timestamp: 2016-07-06T10:48:34+0100 +svn.version: 3686 +build.timestamp: 2016-07-29T09:57:12+0100 diff --git a/resources/styles/default/inc/landuse_polygons b/resources/styles/default/inc/landuse_polygons index 7c6a7f4..c46085a 100644 --- a/resources/styles/default/inc/landuse_polygons +++ b/resources/styles/default/inc/landuse_polygons @@ -16,6 +16,7 @@ landuse=residential [0x10 resolution 23-19] landuse=retail [0x08 resolution 23-20] landuse=village_green [0x17 resolution 20] landuse=vineyard [0x4e resolution 20] +landuse=orchard [0x4e resolution 20] military=airfield [0x04 resolution 20] military=barracks [0x04 resolution 23] diff --git a/src/uk/me/parabola/imgfmt/app/BitWriter.java b/src/uk/me/parabola/imgfmt/app/BitWriter.java index 2c813f5..db090e9 100644 --- a/src/uk/me/parabola/imgfmt/app/BitWriter.java +++ b/src/uk/me/parabola/imgfmt/app/BitWriter.java @@ -110,11 +110,34 @@ public class BitWriter { buflen = (bitoff+7)/8; } + + /** + * Write a signed value. If the value doesn't fit into nb bits, write one or more 1 << (nb-1) + * as a flag for extended range. + */ + public void sputn(int bval, int nb) { + int top = 1 << (nb - 1); + int mask = top - 1; + int val = Math.abs(bval); + while (val > mask) { + putn(top, nb); + val -= mask; + } + if (bval < 0) { + putn((top - val) | top, nb); + } else { + putn(val, nb); + } + } + public byte[] getBytes() { return buf; } + public int getBitPosition() { + return bitoff; + } /** * Get the number of bytes actually used to hold the bit stream. This therefore can be and usually * is less than the length of the buffer returned by {@link #getBytes()}. diff --git a/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java b/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java index bbdd51a..2efc4b4 100644 --- a/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java +++ b/src/uk/me/parabola/imgfmt/app/trergn/LinePreparer.java @@ -69,25 +69,91 @@ public class LinePreparer { /** * Write the bit stream to a BitWriter and return it. + * Try different values for xBase and yBase to find the one + * that results in the shortest bit stream. + * + * @return A class containing the written byte stream. + */ + public BitWriter makeShortestBitStream(int minPointsRequired) { + BitWriter bsSimple = makeBitStream(minPointsRequired, xBase, yBase); + if (bsSimple == null) + return bsSimple; + BitWriter bsBest = bsSimple; + int xBestBase = xBase; + int yBestBase = yBase; + if (xBase > 0 || yBase > 0){ + if (log.isDebugEnabled()) + log.debug("start opt:", xBase, yBase, xSameSign, xSignNegative, ySameSign, ySignNegative); + } + if (xBase > 0){ + int notBetter = 0; + boolean xSameSignBak = xSameSign; + xSameSign = false; + for (int xTestBase = xBase-1; xTestBase >= 0; xTestBase--){ + BitWriter bstest = makeBitStream(minPointsRequired, xTestBase, yBase); +// System.out.println(xBase + " " + xTestBase + " -> " + bsBest.getBitPosition() + " " + bstest.getBitPosition()); + if (bstest.getBitPosition() >= bsBest.getBitPosition() ){ + if (++notBetter >= 2) + break; // give up + } else { + xBestBase = xTestBase; + bsBest = bstest; + xSameSignBak = false; + } + } + xSameSign = xSameSignBak; + } + if (yBase > 0){ + int notBetter = 0; + boolean ySameSignBak = ySameSign; + ySameSign = false; + for (int yTestBase = yBase-1; yTestBase >= 0; yTestBase--){ + BitWriter bstest = makeBitStream(minPointsRequired, xBestBase, yTestBase); +// System.out.println(yBase + " " + yTestBase + " -> " + bsBest.getBitPosition() + " " + bstest.getBitPosition()); + if (bstest.getBitPosition() >= bsBest.getBitPosition()){ + if (++notBetter >= 2) + break; // give up + } else { + yBestBase = yTestBase; + bsBest = bstest; + ySameSignBak = false; + } + } + ySameSign = ySameSignBak; + } + if (xBase != xBestBase || yBestBase != yBase){ + if (log.isInfoEnabled()){ + if (bsSimple.getLength() > bsBest.getLength()) + log.info("optimizer reduced bit stream byte length from",bsSimple.getLength(),"->",bsBest.getLength(),"(" + (bsSimple.getLength()-bsBest.getLength()), " byte(s)) for",polyline.getClass().getSimpleName(),"with",polyline.getPoints().size(),"points"); + else + log.info("optimizer only reduced bit stream bit length from",bsSimple.getBitPosition(),"->",bsBest.getBitPosition(),"bits for",polyline.getClass().getSimpleName(),"with",polyline.getPoints().size(),"points, using original bit stream"); + } + } + if (bsSimple.getLength() == bsBest.getLength()){ + // if the (byte) length was not improved, + // prefer the bit stream that doesn't need the special "trick" + // to encode large values, it is assumed that this can safe a + // few CPU cycles when reading the map + return bsSimple; + } + return bsBest; + } + /** + * Write the bit stream to a BitWriter and return it. * * @return A class containing the written byte stream. */ - public BitWriter makeBitStream(int minPointsRequired) { - - assert xBase >= 0 && yBase >= 0; - - int xbits = 2; - if (xBase < 10) - xbits += xBase; - else - xbits += (2 * xBase) - 9; - - int ybits = 2; - if (yBase < 10) - ybits += yBase; - else - ybits += (2 * yBase) - 9; + public BitWriter makeBitStream(int minPointsRequired, int xb, int yb) { + assert xb >= 0 && yb >= 0; + + int xbits = base2Bits(xb); + if (!xSameSign) + xbits++; + int ybits = base2Bits(yb); + if (!ySameSign) + ybits++; + // Note no sign included. if (log.isDebugEnabled()) log.debug("xbits", xbits, ", y=", ybits); @@ -96,8 +162,8 @@ public class LinePreparer { BitWriter bw = new BitWriter(); // Pre bit stream info - bw.putn(xBase, 4); - bw.putn(yBase, 4); + bw.putn(xb, 4); + bw.putn(yb, 4); bw.put1(xSameSign); if (xSameSign) @@ -133,28 +199,18 @@ public class LinePreparer { if (log.isDebugEnabled()) log.debug("x delta", dx, "~", xbits); - assert dx >> xbits == 0 || dx >> xbits == -1; if (xSameSign) { bw.putn(Math.abs(dx), xbits); } else { - // catch inadvertent output of "magic" value that has - // sign bit set but other bits all 0 - assert dx >= 0 || (dx & ((1 << xbits) - 1)) != 0; - bw.putn(dx, xbits); - bw.put1(dx < 0); + bw.sputn(dx, xbits); } if (log.isDebugEnabled()) log.debug("y delta", dy, ybits); - assert dy >> ybits == 0 || dy >> ybits == -1; if (ySameSign) { bw.putn(Math.abs(dy), ybits); } else { - // catch inadvertent output of "magic" value that has - // sign bit set but other bits all 0 - assert dy >= 0 || (dy & ((1 << ybits) - 1)) != 0; - bw.putn(dy, ybits); - bw.put1(dy < 0); + bw.sputn(dy, ybits); } if (extraBit) bw.put1(nodes[i/2+1]); @@ -191,7 +247,6 @@ public class LinePreparer { Subdivision subdiv = polyline.getSubdiv(); if(log.isDebugEnabled()) log.debug("label offset", polyline.getLabel().getOffset()); - int shift = subdiv.getShift(); List<Coord> points = polyline.getPoints(); // Space to hold the deltas @@ -209,10 +264,6 @@ public class LinePreparer { // OK go through the points int lastLat = 0; int lastLong = 0; - boolean xDiffSign = false; // The long values have different sign - boolean yDiffSign = false; // The lat values have different sign - int xSign = 0; // If all the same sign, then this 1 or -1 depending on +ve or -ve - int ySign = 0; // As above for lat. int minDx = Integer.MAX_VALUE, maxDx = 0; int minDy = Integer.MAX_VALUE, maxDy = 0; // index of first point in a series of identical coords (after shift) @@ -231,14 +282,8 @@ public class LinePreparer { continue; } - // compute normalized differences - // -2^(shift-1) <= dx, dy < 2^(shift-1) - // XXX: relies on the fact that java integers are 32 bit signed - final int offset = 8+shift; - int dx = (lon - lastLong) << offset >> offset; - int dy = (lat - lastLat) << offset >> offset; - assert (dx == 0 && lon != lastLong) == false: ("delta lon too large: " + (lon - lastLong)); - assert (dy == 0 && lat != lastLat) == false: ("delta lat too large: " + (lat - lastLat)); + int dx = lon - lastLong; + int dy = lat - lastLat; lastLong = lon; lastLat = lat; boolean isSpecialNode = false; @@ -280,26 +325,6 @@ public class LinePreparer { nodes[firstsame] = nodes[firstsame] || extra; } - // See if they can all be the same sign. - if (!xDiffSign) { - int thisSign = (dx >= 0)? 1: -1; - if (xSign == 0) { - xSign = thisSign; - } else if (thisSign != xSign) { - // The signs are different - xDiffSign = true; - } - } - if (!yDiffSign) { - int thisSign = (dy >= 0)? 1: -1; - if (ySign == 0) { - ySign = thisSign; - } else if (thisSign != ySign) { - // The signs are different - yDiffSign = true; - } - } - // find largest delta values if (dx < minDx) minDx = dx; @@ -323,43 +348,25 @@ public class LinePreparer { // adjustments to get the final value. We need to try and work // backwards from this. // - // I don't care about getting the smallest possible file size so - // err on the side of caution. - // // Note that the sign bit is already not included so there is // no adjustment needed for it. if (log.isDebugEnabled()) log.debug("initial xBits, yBits", xBits, yBits); - if (xBits < 2) - xBits = 2; - int tmp = xBits - 2; - if (tmp > 10) { - if ((tmp & 0x1) == 0) - tmp++; - tmp = 9 + (tmp - 9) / 2; - } - this.xBase = tmp; - - if (yBits < 2) - yBits = 2; - tmp = yBits - 2; - if (tmp > 10) { - if ((tmp & 0x1) == 0) - tmp++; - tmp = 9 + (tmp - 9) / 2; - } - this.yBase = tmp; + this.xBase = bits2Base(xBits); + this.yBase = bits2Base(yBits); if (log.isDebugEnabled()) log.debug("initial xBase, yBase", xBase, yBase); // Set flags for same sign etc. - this.xSameSign = !xDiffSign; - this.ySameSign = !yDiffSign; - this.xSignNegative = xSign < 0; - this.ySignNegative = ySign < 0; + this.xSameSign = !(minDx < 0 && maxDx > 0); + this.ySameSign = !(minDy < 0 && maxDy > 0); + if (this.xSameSign) + this.xSignNegative = minDx < 0; + if (this.ySameSign) + this.ySignNegative = minDy < 0; } /** @@ -371,16 +378,35 @@ public class LinePreparer { public static int bitsNeeded(int val) { int n = Math.abs(val); - int count = val < 0? 1: 0; + int count = 0; while (n != 0) { n >>>= 1; count++; } return count; +// count should be equal to Integer.SIZE - Integer.numberOfLeadingZeros(Math.abs(val)); + } public boolean isExtraBit() { return extraBit; } + private static int base2Bits(int base){ + int bits = 2; + if (base < 10) + return bits + base; + else + return bits + (2 * base) - 9; + } + + private static int bits2Base(int bits){ + int base = Math.max(0, bits - 2); + if (base > 10) { + if ((base & 0x1) == 0) + base++; + base = 9 + (base - 9) / 2; + } + return base; + } } diff --git a/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java b/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java index e8f9ce4..6e4550d 100644 --- a/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java +++ b/src/uk/me/parabola/imgfmt/app/trergn/Polyline.java @@ -91,7 +91,7 @@ public class Polyline extends MapObject { } int minPointsRequired = (this instanceof Polygon)? 3 : 2; - BitWriter bw = w.makeBitStream(minPointsRequired); + BitWriter bw = w.makeShortestBitStream(minPointsRequired); if(bw == null) { log.error("Level " + getSubdiv().getZoom().getLevel() + " " + ((this instanceof Polygon)? "polygon" : "polyline") + " has less than " + minPointsRequired + " points, discarding"); return; @@ -171,7 +171,7 @@ public class Polyline extends MapObject { return; } int minPointsRequired = (this instanceof Polygon)? 3 : 2; - BitWriter bw = w.makeBitStream(minPointsRequired); + BitWriter bw = w.makeShortestBitStream(minPointsRequired); if(bw == null) { log.error("Level " + getSubdiv().getZoom().getLevel() + " " + ((this instanceof Polygon)? "polygon" : "polyline") + " has less than " + minPointsRequired + " points, discarding"); return; diff --git a/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java b/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java index 9f6fa08..5fa08ab 100644 --- a/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java +++ b/src/uk/me/parabola/mkgmap/combiners/OverviewBuilder.java @@ -55,12 +55,12 @@ public class OverviewBuilder implements Combiner { private String areaName; private String overviewMapname; private String overviewMapnumber; - private Zoom[] levels; private String outputDir; private Integer codepage; private Integer encodingType; private List<String[]> copyrightMsgs = new ArrayList<String[]>(); private List<String[]> licenseInfos = new ArrayList<String[]>(); + private LevelInfo[] wantedLevels; public OverviewBuilder(OverviewMap overviewSource) { @@ -87,9 +87,57 @@ public class OverviewBuilder implements Combiner { public void onFinish() { addBackground(); + calcLevels(); writeOverviewMap(); } + private void calcLevels() { + List<MapShape> shapes = overviewSource.getShapes(); + int maxRes = 16; // we can write a 0x4a polygon for planet in res 16 + if (wantedLevels != null) + maxRes = wantedLevels[wantedLevels.length-1].getBits(); + int maxSize = 0xffff << (24 - maxRes); + for (MapShape s : shapes){ + if (s.getType() != 0x4a) + continue; + int maxDimPoly = s.getBounds().getMaxDimension(); + if (maxDimPoly > maxSize){ + int oldMaxRes = maxRes; + while (maxDimPoly > maxSize){ + maxRes--; + maxSize = 0xffff << (24 - maxRes); + } + String[] name = s.getName().split("\u001d"); + String msg = "Tile selection (0x4a) polygon for "; + if (name != null && name.length == 2) + msg += "tile " + name[1].trim(); + else + msg += s.getBounds(); + log.error(msg,"cannot be written in level 0 resolution",oldMaxRes + ", using",maxRes,"instead"); + + } + } + if (wantedLevels == null) + setRes(maxRes); + else { + // make sure that the wanted levels for the overview map + // can store the largest 0x4a polygon at level 0 + int n = wantedLevels.length-1; + while (n > 0 && wantedLevels[n].getBits() > maxRes) + n--; + if (n > 0){ + int l = 0; + while (n >= 0){ + wantedLevels[n] = new LevelInfo(l++, wantedLevels[n].getBits()); + n--; + } + wantedLevels = Arrays.copyOfRange(wantedLevels, 0, l); + overviewSource.setMapLevels(wantedLevels); + } else + setRes(maxRes); + } + } + /** * Add background polygon that covers the whole area of the overview map. */ @@ -187,8 +235,8 @@ public class OverviewBuilder implements Combiner { licenseInfos.add(msgs); - levels = mapReader.getLevels(); - if (overviewSource.mapLevels() == null){ + Zoom[] levels = mapReader.getLevels(); + if (wantedLevels == null){ LevelInfo[] mapLevels; if (isOverviewImg(filename)){ mapLevels = new LevelInfo[levels.length-1]; @@ -199,7 +247,7 @@ public class OverviewBuilder implements Combiner { mapLevels = new LevelInfo[1]; mapLevels[0] = new LevelInfo(levels[1].getLevel(), levels[1].getResolution()); } - overviewSource.setMapLevels(mapLevels); + wantedLevels = mapLevels; } if (isOverviewImg(filename)){ readPoints(mapReader); @@ -221,6 +269,7 @@ public class OverviewBuilder implements Combiner { */ private void readPoints(MapReader mapReader) { Area bounds = overviewSource.getBounds(); + Zoom[] levels = mapReader.getLevels(); for (int l = 1; l < levels.length; l++){ int min = levels[l].getLevel(); int res = levels[l].getResolution(); @@ -251,6 +300,7 @@ public class OverviewBuilder implements Combiner { * @param mapReader Map reader on the detailed .img file. */ private void readLines(MapReader mapReader) { + Zoom[] levels = mapReader.getLevels(); for (int l = 1; l < levels.length; l++){ int min = levels[l].getLevel(); int res = levels[l].getResolution(); @@ -286,6 +336,7 @@ public class OverviewBuilder implements Combiner { * @param mapReader Map reader on the detailed .img file. */ private void readShapes(MapReader mapReader) { + Zoom[] levels = mapReader.getLevels(); for (int l = 1; l < levels.length; l++){ int min = levels[l].getLevel(); int res = levels[l].getResolution(); @@ -332,7 +383,7 @@ public class OverviewBuilder implements Combiner { for (Coord co: points){ overviewSource.addToBounds(co); } - // Create the background rectangle + // Create the tile coverage rectangle MapShape bg = new MapShape(); bg.setType(0x4a); bg.setPoints(points); @@ -385,4 +436,15 @@ public class OverviewBuilder implements Combiner { } return list; } + + /** + * Set the highest resolution + * @param resolution + */ + private void setRes(int resolution) { + LevelInfo[] mapLevels = new LevelInfo[1]; + mapLevels[0] = new LevelInfo(0, resolution); + overviewSource.setMapLevels(mapLevels); + } + } diff --git a/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java b/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java index 4a19c52..b908c85 100644 --- a/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java +++ b/src/uk/me/parabola/mkgmap/filters/PolygonSplitterBase.java @@ -28,7 +28,7 @@ import uk.me.parabola.util.Java2DConverter; * @author Steve Ratcliffe */ public class PolygonSplitterBase extends BaseFilter { - protected static final int MAX_SIZE = 0x7fff; + protected static final int MAX_SIZE = 0xffff; // larger value causes problem in delta encoding of lines private int shift; public void init(FilterConfig config) { diff --git a/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java b/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java index 961278d..760adb5 100644 --- a/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java +++ b/src/uk/me/parabola/mkgmap/filters/PolygonSubdivSizeSplitterFilter.java @@ -89,6 +89,10 @@ public class PolygonSubdivSizeSplitterFilter extends PolygonSplitterBase impleme } private boolean isSizeOk(MapShape shape) { + // do not cut the background shape + if (shape.getType() == 0x4a) + return true; + // Estimate the size taken by lines and shapes as a constant plus // a factor based on the number of points. int numPoints = shape.getPoints().size(); diff --git a/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java b/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java index ba2d583..3c2224d 100644 --- a/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java +++ b/src/uk/me/parabola/mkgmap/filters/RemoveObsoletePointsFilter.java @@ -105,13 +105,25 @@ public class RemoveObsoletePointsFilter implements MapFilter { points = newPoints; newPoints = new ArrayList<Coord>(points.size()); } - if (line instanceof MapShape && newPoints.size() > 3){ - // check special case: shape starts with spike - if (Utils.isStraight(newPoints.get(0), newPoints.get(1), newPoints.get(newPoints.size()-2)) == Utils.STRICTLY_STRAIGHT){ - newPoints.remove(0); - newPoints.set(newPoints.size()-1, newPoints.get(0)); - if (newPoints.get(newPoints.size()-2).equals(newPoints.get(newPoints.size()-1))) + if (line instanceof MapShape){ + // Check special cases caused by the fact that the first and last point + // in a shape are identical. + while (newPoints.size() > 3){ + int nPoints = newPoints.size(); + switch(Utils.isStraight(newPoints.get(newPoints.size()-2), newPoints.get(0), newPoints.get(1))){ + case Utils.STRAIGHT_SPIKE: + newPoints.remove(0); + newPoints.set(newPoints.size()-1, newPoints.get(0)); + if (newPoints.get(newPoints.size()-2).equals(newPoints.get(newPoints.size()-1))) + newPoints.remove(newPoints.size()-1); + break; + case Utils.STRICTLY_STRAIGHT: newPoints.remove(newPoints.size()-1); + newPoints.set(0, newPoints.get(newPoints.size()-1)); + break; + } + if (nPoints == newPoints.size()) + break; } } diff --git a/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java b/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java index 62202dd..4d357b9 100644 --- a/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java +++ b/src/uk/me/parabola/mkgmap/reader/osm/MultiPolygonRelation.java @@ -2071,11 +2071,11 @@ public class MultiPolygonRelation extends Relation { */ private boolean linesCutEachOther(Coord p1_1, Coord p1_2, Coord p2_1, Coord p2_2) { - int width1 = p1_2.getLongitude() - p1_1.getLongitude(); - int width2 = p2_2.getLongitude() - p2_1.getLongitude(); + int width1 = p1_2.getHighPrecLon() - p1_1.getHighPrecLon(); + int width2 = p2_2.getHighPrecLon() - p2_1.getHighPrecLon(); - int height1 = p1_2.getLatitude() - p1_1.getLatitude(); - int height2 = p2_2.getLatitude() - p2_1.getLatitude(); + int height1 = p1_2.getHighPrecLat() - p1_1.getHighPrecLat(); + int height2 = p2_2.getHighPrecLat() - p2_1.getHighPrecLat(); int denominator = ((height2 * width1) - (width2 * height1)); if (denominator == 0) { @@ -2084,8 +2084,8 @@ public class MultiPolygonRelation extends Relation { return false; } - int x1Mx3 = p1_1.getLongitude() - p2_1.getLongitude(); - int y1My3 = p1_1.getLatitude() - p2_1.getLatitude(); + int x1Mx3 = p1_1.getHighPrecLon() - p2_1.getHighPrecLon(); + int y1My3 = p1_1.getHighPrecLat() - p2_1.getHighPrecLat(); double isx = (double)((width2 * y1My3) - (height2 * x1Mx3)) / denominator; diff --git a/test/uk/me/parabola/imgfmt/app/BitReaderTest.java b/test/uk/me/parabola/imgfmt/app/BitReaderTest.java index 6ab84c1..f50dc1b 100644 --- a/test/uk/me/parabola/imgfmt/app/BitReaderTest.java +++ b/test/uk/me/parabola/imgfmt/app/BitReaderTest.java @@ -46,6 +46,13 @@ public class BitReaderTest { int s = br.sget2(3); assertEquals(-12, s); } + @Test + public void testSpecialNegative2() { + BitReader br = new BitReader(new byte[]{0x2c, 0x0}); + + int s = br.sget2(3); + assertEquals(-6, s); + } @Test public void testSpecialPositive() { @@ -54,4 +61,18 @@ public class BitReaderTest { int s = br.sget2(3); assertEquals(8, s); } + + @Test + public void testWriteRead() { + for (int i = -20; i <= 20; i++){ + BitWriter bw = new BitWriter(); + bw.sputn(i,3); + BitReader br = new BitReader(bw.getBytes()); + + int s = br.sget2(3); + assertEquals(i, s); + } + } + + } -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mkgmap.git _______________________________________________ Pkg-grass-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-grass-devel

