aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2012-03-10 21:46:32 +0100
committerBananeweizen <bananeweizen@gmx.de>2012-03-10 21:46:32 +0100
commit491fdefaf2ab8adff5c62898fa00f9af2220b214 (patch)
tree9091734e7f8786b8fcc5f1adc3cf23e822c9eae8
parentd40313cf48a9956487afd2b591b34d588bb4ae82 (diff)
downloadcgeo-491fdefaf2ab8adff5c62898fa00f9af2220b214.zip
cgeo-491fdefaf2ab8adff5c62898fa00f9af2220b214.tar.gz
cgeo-491fdefaf2ab8adff5c62898fa00f9af2220b214.tar.bz2
fix #1262: icon decoding does not work well
-rw-r--r--main/src/cgeo/geocaching/connector/gc/GCBase.java136
-rw-r--r--main/src/cgeo/geocaching/connector/gc/IconDecoder.java156
-rw-r--r--main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java22
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/GCBaseTest.java16
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java89
-rw-r--r--tests/src/cgeo/geocaching/connector/gc/IconDecoderTest.java52
6 files changed, 259 insertions, 212 deletions
diff --git a/main/src/cgeo/geocaching/connector/gc/GCBase.java b/main/src/cgeo/geocaching/connector/gc/GCBase.java
index 7780ba2..127b773 100644
--- a/main/src/cgeo/geocaching/connector/gc/GCBase.java
+++ b/main/src/cgeo/geocaching/connector/gc/GCBase.java
@@ -30,8 +30,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
/**
* GC.com/Groundspeak (GS) specific stuff
@@ -47,25 +45,6 @@ public class GCBase {
protected final static long GC_BASE31 = 31;
protected final static long GC_BASE16 = 16;
- // Pixel colors in tile
- private final static int BORDER_GRAY = 0x5F5F5F;
- private final static int DARK_GREEN = 0x316013; // Tradi 14
- private final static int LIGHT_GREEN = 0x80AF64; // Tradi 13
- private final static int DARK_BLUE = 0x243C97; // Mystery
- private final static int YELLOW = 0xFFDE19; // Multi 14,13
- private final static int FOUND = 0xFBEA5D; // Found
-
- // Offset inside cache icon
- private final static int POSX_TRADI = 7;
- private final static int POSY_TRADI = -12;
- private final static int POSX_MULTI = 5; // for orange 8
- private final static int POSY_MULTI = -9; // for orange 10
- private final static int POSX_MYSTERY = 5;
- private final static int POSY_MYSTERY = -13;
- private final static int POSX_FOUND = 10;
- private final static int POSY_FOUND = -8;
-
- private final static Pattern PATTERN_JSON_KEY = Pattern.compile("[^\\d]*" + "(\\d+),\\s*(\\d+)" + "[^\\d]*"); // (12, 34)
/**
* Searches the view port on the live map with Strategy.AUTO
*
@@ -235,7 +214,7 @@ public class GCBase {
for (int i = 1; i < keys.length(); i++) { // index 0 is empty
String key = keys.getString(i);
if (StringUtils.isNotBlank(key)) {
- int[] xy = splitJSONKey(key);
+ UTFGridPosition pos = UTFGridPosition.fromString(key);
JSONArray dataForKey = dataObject.getJSONArray(key);
for (int j = 0; j < dataForKey.length(); j++) {
JSONObject cacheInfo = dataForKey.getJSONObject(j);
@@ -245,14 +224,10 @@ public class GCBase {
List<UTFGridPosition> listOfPositions = positions.get(id);
if (listOfPositions == null) {
listOfPositions = new ArrayList<UTFGridPosition>();
+ positions.put(id, listOfPositions);
}
- /*
- * Optimization
- * UTFGridPosition pos = keyPositions.get(key);
- */
- UTFGridPosition pos = new UTFGridPosition(xy[0], xy[1]);
+
listOfPositions.add(pos);
- positions.put(id, listOfPositions);
}
}
}
@@ -269,9 +244,9 @@ public class GCBase {
cache.setCoords(tile.getCoord(xy));
if (strategy.flags.contains(StrategyFlag.PARSE_TILES)) {
if (tile.getZoomlevel() >= 14) {
- parseMapPNG14(cache, bitmap, xy);
+ IconDecoder.parseMapPNG14(cache, bitmap, xy);
} else {
- parseMapPNG13(cache, bitmap, xy);
+ IconDecoder.parseMapPNG13(cache, bitmap, xy);
}
} else {
cache.setType(CacheType.UNKNOWN);
@@ -287,89 +262,6 @@ public class GCBase {
return searchResult;
}
- // Try to get the cache type from the PNG image for a tile */
- public static void parseMapPNG14(cgCache cache, Bitmap bitmap, UTFGridPosition xy) {
- int x = xy.getX() * 4 + 2;
- int y = xy.getY() * 4 + 2;
- int countX = 0;
- int countY = 0;
-
- // search for left border
- while ((bitmap.getPixel(x, y) & 0x00FFFFFF) != BORDER_GRAY) {
- if (--x < 0 || ++countX > 20) {
- return;
- }
- }
- // search for bottom border
- while ((bitmap.getPixel(x, y) & 0x00FFFFFF) != 0x000000) {
- if (++y >= Tile.TILE_SIZE || ++countY > 20) {
- return;
- }
- }
-
- try {
- if ((bitmap.getPixel(x + POSX_TRADI, y + POSY_TRADI) & 0x00FFFFFF) == DARK_GREEN) {
- cache.setType(CacheType.TRADITIONAL);
- return;
- }
- if ((bitmap.getPixel(x + POSX_MYSTERY, y + POSY_MYSTERY) & 0x00FFFFFF) == DARK_BLUE) {
- cache.setType(CacheType.MYSTERY);
- return;
- }
- if ((bitmap.getPixel(x + POSX_MULTI, y + POSY_MULTI) & 0x00FFFFFF) == YELLOW) {
- cache.setType(CacheType.MULTI);
- return;
- }
- if ((bitmap.getPixel(x + POSX_FOUND, y + POSY_FOUND) & 0x00FFFFFF) == FOUND) {
- cache.setFound(true);
- return;
- }
- } catch (IllegalArgumentException e) {
- // intentionally left blank
- }
-
- return;
- }
-
- // Try to get the cache type from the PNG image for a tile */
- public static void parseMapPNG13(cgCache cache, Bitmap bitmap, UTFGridPosition xy) {
-
- int x = xy.getX() * 4 + 2;
- int y = xy.getY() * 4 + 2;
- int countY = 0;
-
- // search for top border
- while ((bitmap.getPixel(x, y) & 0x00FFFFFF) != BORDER_GRAY) {
- if (--y < 0 || ++countY > 12) {
- return;
- }
- }
-
- try {
- int color = bitmap.getPixel(x, y + 2) & 0x00FFFFFF;
-
- switch (color) {
- case LIGHT_GREEN:
- cache.setType(CacheType.TRADITIONAL);
- return;
- case YELLOW:
- cache.setType(CacheType.MULTI);
- return;
- }
- if ((color | 0x00FFFF) == 0x00FFFF) { // BLUE
- cache.setType(CacheType.MYSTERY);
- return;
- }
- // Found consists out of too many different colors
- }
- catch (IllegalArgumentException e) {
- // intentionally left blank
- }
-
- return;
- }
-
-
/**
* Calculate needed tiles for the given viewport
@@ -478,22 +370,4 @@ public class GCBase {
return new String[] { userSession, sessionToken };
}
- /**
- * @param key
- * Key in the format (xx, xx)
- * @return
- */
- static int[] splitJSONKey(String key) {
- final Matcher matcher = PATTERN_JSON_KEY.matcher(key);
- try {
- if (matcher.matches()) {
- final int x = Integer.parseInt(matcher.group(1));
- final int y = Integer.parseInt(matcher.group(2));
- return new int[] { x, y };
- }
- } catch (NumberFormatException e) {
- }
- return new int[] { 0, 0 };
- }
-
}
diff --git a/main/src/cgeo/geocaching/connector/gc/IconDecoder.java b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
new file mode 100644
index 0000000..2935ef0
--- /dev/null
+++ b/main/src/cgeo/geocaching/connector/gc/IconDecoder.java
@@ -0,0 +1,156 @@
+package cgeo.geocaching.connector.gc;
+
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.enumerations.CacheType;
+
+import android.graphics.Bitmap;
+
+/**
+ * icon decoder for cache icons
+ *
+ */
+public abstract class IconDecoder {
+
+ private static final int[] OFFSET_X = new int[] { 0, -1, -1, 0, 1, 1, 1, 0, -1, -2, -2, -2, -2, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2 };
+ private static final int[] OFFSET_Y = new int[] { 0, 0, 1, 1, 1, 0, -1, -1, -1, -1, 0, 1, 2, 2, 2, 2, 2, 1, 0, -1, -2, -2, -2, -2, -2 };
+
+ /**
+ * The icon decoder walks a spiral around the center pixel position of the cache
+ * and searches for characteristic colors.
+ *
+ * @param cache
+ * @param bitmap
+ * @param xy
+ */
+ public static void parseMapPNG13(final cgCache cache, Bitmap bitmap, UTFGridPosition xy) {
+ final int xCenter = xy.getX() * 4 + 2;
+ final int yCenter = xy.getY() * 4 + 2;
+ final int bitmapWidth = bitmap.getWidth();
+ final int bitmapHeight = bitmap.getHeight();
+
+ int countMulti = 0;
+ int countFound = 0;
+
+ for (int i = 0; i < OFFSET_X.length; i++) {
+
+ // assert that we are still in the tile
+ final int x = xCenter + OFFSET_X[i];
+ if (x < 0 || x >= bitmapWidth) {
+ continue;
+ }
+
+ final int y = yCenter + OFFSET_Y[i];
+ if (y < 0 || y >= bitmapHeight) {
+ continue;
+ }
+
+ int color = bitmap.getPixel(x, y) & 0x00FFFFFF;
+
+ // transparent pixels are not interesting
+ if (color == 0) {
+ continue;
+ }
+
+ int red = (color & 0xFF0000) >> 16;
+ int green = (color & 0xFF00) >> 8;
+ int blue = color & 0xFF;
+
+ // these are quite sure, so one pixel is enough for matching
+ if (green > 0x80 && green > red && green > blue) {
+ cache.setType(CacheType.TRADITIONAL);
+ return;
+ }
+ if (blue > 0x80 && blue > red && blue > green) {
+ cache.setType(CacheType.MYSTERY);
+ return;
+ }
+ if (red > 0x90 && blue < 0x10 && green < 0x10) {
+ cache.setType(CacheType.EVENT);
+ return;
+ }
+
+ // next two are hard to distinguish, therefore we sample all pixels of the spiral
+ if (red > 0xFA && green > 0xD0) {
+ countMulti++;
+ }
+ if (red < 0xF3 && red > 0xa0 && green > 0x20 && blue < 0x80) {
+ countFound++;
+ }
+ }
+
+ // now check whether we are sure about found/multi
+ if (countFound > countMulti && countFound >= 2) {
+ cache.setFound(true);
+ }
+ if (countMulti > countFound && countMulti >= 5) {
+ cache.setType(CacheType.MULTI);
+ }
+ }
+
+ // Pixel colors in tile
+ private final static int COLOR_BORDER_GRAY = 0x5F5F5F;
+ private final static int COLOR_TRADITIONAL = 0x316013;
+ private final static int COLOR_MYSTERY = 0x243C97;
+ private final static int COLOR_MULTI = 0xFFDE19;
+ private final static int COLOR_FOUND = 0xFBEA5D;
+
+ // Offset inside cache icon
+ private final static int POSX_TRADI = 7;
+ private final static int POSY_TRADI = -12;
+ private final static int POSX_MULTI = 5; // for orange 8
+ private final static int POSY_MULTI = -9; // for orange 10
+ private final static int POSX_MYSTERY = 5;
+ private final static int POSY_MYSTERY = -13;
+ private final static int POSX_FOUND = 10;
+ private final static int POSY_FOUND = -8;
+
+ /**
+ * For level 14 find the borders of the icons and then use a single pixel and color to match.
+ *
+ * @param cache
+ * @param bitmap
+ * @param xy
+ */
+ public static void parseMapPNG14(cgCache cache, Bitmap bitmap, UTFGridPosition xy) {
+ int x = xy.getX() * 4 + 2;
+ int y = xy.getY() * 4 + 2;
+
+ // search for left border
+ int countX = 0;
+ while ((bitmap.getPixel(x, y) & 0x00FFFFFF) != COLOR_BORDER_GRAY) {
+ if (--x < 0 || ++countX > 20) {
+ return;
+ }
+ }
+ // search for bottom border
+ int countY = 0;
+ while ((bitmap.getPixel(x, y) & 0x00FFFFFF) != 0x000000) {
+ if (++y >= Tile.TILE_SIZE || ++countY > 20) {
+ return;
+ }
+ }
+
+ try {
+ if ((bitmap.getPixel(x + POSX_TRADI, y + POSY_TRADI) & 0x00FFFFFF) == COLOR_TRADITIONAL) {
+ cache.setType(CacheType.TRADITIONAL);
+ return;
+ }
+ if ((bitmap.getPixel(x + POSX_MYSTERY, y + POSY_MYSTERY) & 0x00FFFFFF) == COLOR_MYSTERY) {
+ cache.setType(CacheType.MYSTERY);
+ return;
+ }
+ if ((bitmap.getPixel(x + POSX_MULTI, y + POSY_MULTI) & 0x00FFFFFF) == COLOR_MULTI) {
+ cache.setType(CacheType.MULTI);
+ return;
+ }
+ if ((bitmap.getPixel(x + POSX_FOUND, y + POSY_FOUND) & 0x00FFFFFF) == COLOR_FOUND) {
+ cache.setFound(true);
+ return;
+ }
+ } catch (IllegalArgumentException e) {
+ // intentionally left blank
+ }
+
+ return;
+ }
+}
diff --git a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
index e88a425..1aae560 100644
--- a/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
+++ b/main/src/cgeo/geocaching/connector/gc/UTFGridPosition.java
@@ -1,5 +1,8 @@
package cgeo.geocaching.connector.gc;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
/**
* Representation of a position inside an UTFGrid
@@ -11,6 +14,7 @@ public final class UTFGridPosition {
public final int x;
public final int y;
+ private final static Pattern PATTERN_JSON_KEY = Pattern.compile("[^\\d]*" + "(\\d+),\\s*(\\d+)" + "[^\\d]*"); // (12, 34)
public UTFGridPosition(final int x, final int y) {
assert x >= 0 && x <= UTFGrid.GRID_MAXX : "x outside bounds";
@@ -28,4 +32,22 @@ public final class UTFGridPosition {
return y;
}
+ /**
+ * @param key
+ * Key in the format (xx, xx)
+ * @return
+ */
+ static UTFGridPosition fromString(String key) {
+ final Matcher matcher = UTFGridPosition.PATTERN_JSON_KEY.matcher(key);
+ try {
+ if (matcher.matches()) {
+ final int x = Integer.parseInt(matcher.group(1));
+ final int y = Integer.parseInt(matcher.group(2));
+ return new UTFGridPosition(x, y);
+ }
+ } catch (NumberFormatException e) {
+ }
+ return new UTFGridPosition(0, 0);
+ }
+
}
diff --git a/tests/src/cgeo/geocaching/connector/gc/GCBaseTest.java b/tests/src/cgeo/geocaching/connector/gc/GCBaseTest.java
index 5f07f60..32ab1f2 100644
--- a/tests/src/cgeo/geocaching/connector/gc/GCBaseTest.java
+++ b/tests/src/cgeo/geocaching/connector/gc/GCBaseTest.java
@@ -1,14 +1,18 @@
package cgeo.geocaching.connector.gc;
-import java.util.Arrays;
-
import junit.framework.TestCase;
public class GCBaseTest extends TestCase {
public static void testSplitJSONKey() {
- assertTrue(Arrays.equals(new int[] { 1, 2 }, GCBase.splitJSONKey("(1, 2)")));
- assertTrue(Arrays.equals(new int[] { 12, 34 }, GCBase.splitJSONKey("(12, 34)")));
- assertTrue(Arrays.equals(new int[] { 1234, 56 }, GCBase.splitJSONKey("(1234,56)")));
- assertTrue(Arrays.equals(new int[] { 1234, 567 }, GCBase.splitJSONKey("(1234, 567)")));
+ assertKey("(1, 2)", 1, 2);
+ assertKey("(12, 34)", 12, 34);
+ assertKey("(1234,56)", 1234, 56);
+ assertKey("(1234, 567)", 1234, 567);
+ }
+
+ private static void assertKey(String key, int x, int y) {
+ UTFGridPosition pos = UTFGridPosition.fromString(key);
+ assertEquals(x, pos.getX());
+ assertEquals(y, pos.getY());
}
}
diff --git a/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java b/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
index 3696568..dfa9a8b 100644
--- a/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
+++ b/tests/src/cgeo/geocaching/connector/gc/GCConnectorTest.java
@@ -1,19 +1,11 @@
package cgeo.geocaching.connector.gc;
import cgeo.geocaching.SearchResult;
-import cgeo.geocaching.Settings;
-import cgeo.geocaching.cgCache;
import cgeo.geocaching.connector.ConnectorFactory;
-import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.geopoint.Geopoint;
import cgeo.geocaching.geopoint.Viewport;
import cgeo.geocaching.network.Login;
import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase;
-import cgeo.geocaching.test.R;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.util.Log;
public class GCConnectorTest extends AbstractResourceInstrumentationTestCase {
@@ -50,78 +42,25 @@ public class GCConnectorTest extends AbstractResourceInstrumentationTestCase {
/** Tile computation with different zoom levels */
public static void testTile() {
- {
- // http://coord.info/GC2CT8K = N 52° 30.462 E 013° 27.906
- Tile tile = new Tile(new Geopoint(52.5077, 13.4651), 14);
- assertEquals(8804, tile.getX());
- assertEquals(5374, tile.getY());
- }
- {
- // (8633, 5381); N 52° 24,516 E 009° 42,592
- Tile tile = new Tile(new Geopoint("N 52° 24,516 E 009° 42,592"), 14);
- assertEquals(8633, tile.getX());
- assertEquals(5381, tile.getY());
- }
- {
- // Hannover, GC22VTB UKM Memorial Tour
- Tile tile = new Tile(new Geopoint("N 52° 22.177 E 009° 45.385"), 12);
- assertEquals(2159, tile.getX());
- assertEquals(1346, tile.getY());
- }
- {
- // Seatle, GCK25B Groundspeak Headquarters
- Tile tile = new Tile(new Geopoint("N 47° 38.000 W 122° 20.000"), 15);
- assertEquals(5248, tile.getX());
- assertEquals(11440, tile.getY());
- }
- {
- // Sydney, GCXT2R Victoria Cross
- Tile tile = new Tile(new Geopoint("S 33° 50.326 E 151° 12.426"), 13);
- assertEquals(7536, tile.getX());
- assertEquals(4915, tile.getY());
- }
- }
+ // http://coord.info/GC2CT8K = N 52° 30.462 E 013° 27.906
+ assertTileAt(8804, 5374, new Tile(new Geopoint(52.5077, 13.4651), 14));
- public void testparseMapPNG() {
- // createApplication();
- // cgBase.initialize(getApplication());
+ // (8633, 5381); N 52° 24,516 E 009° 42,592
+ assertTileAt(8633, 5381, new Tile(new Geopoint("N 52° 24,516 E 009° 42,592"), 14));
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inScaled = false;
- Bitmap bitmap = BitmapFactory.decodeStream(getInstrumentation().getContext().getResources().openRawResource(R.raw.tile14));
- assert bitmap.getWidth() == Tile.TILE_SIZE : "Wrong size";
+ // Hannover, GC22VTB UKM Memorial Tour
+ assertTileAt(2159, 1346, new Tile(new Geopoint("N 52° 22.177 E 009° 45.385"), 12));
- Log.d(Settings.tag, "Bitmap=" + bitmap.getWidth() + "x" + bitmap.getHeight());
+ // Seattle, GCK25B Groundspeak Headquarters
+ assertTileAt(5248, 11440, new Tile(new Geopoint("N 47° 38.000 W 122° 20.000"), 15));
- cgCache cache = new cgCache();
-
- // Tradi
- GCBase.parseMapPNG14(cache, bitmap, new UTFGridPosition(97 / 4, 136 / 4));
- assertEquals(CacheType.TRADITIONAL, cache.getType());
- // Mystery
- GCBase.parseMapPNG14(cache, bitmap, new UTFGridPosition(226 / 4, 104 / 4));
- assertEquals(CacheType.MYSTERY, cache.getType());
- // Multi
- GCBase.parseMapPNG14(cache, bitmap, new UTFGridPosition(54 / 4, 97 / 4));
- assertEquals(CacheType.MULTI, cache.getType());
- // Found
- GCBase.parseMapPNG14(cache, bitmap, new UTFGridPosition(119 / 4, 108 / 4));
- assertTrue(cache.isFound());
- cache.setFound(false); // reset
-
- bitmap = BitmapFactory.decodeStream(getInstrumentation().getContext().getResources().openRawResource(R.raw.tile13));
-
- // Tradi
- GCBase.parseMapPNG13(cache, bitmap, new UTFGridPosition(146 / 4, 225 / 4));
- assertEquals(CacheType.TRADITIONAL, cache.getType());
- // Mystery
- GCBase.parseMapPNG13(cache, bitmap, new UTFGridPosition(181 / 4, 116 / 4));
- assertEquals(CacheType.MYSTERY, cache.getType());
- // Multi
- GCBase.parseMapPNG13(cache, bitmap, new UTFGridPosition(118 / 4, 230 / 4));
- assertEquals(CacheType.MULTI, cache.getType());
- // Found - not available in parseMapPNG13
+ // Sydney, GCXT2R Victoria Cross
+ assertTileAt(7536, 4915, new Tile(new Geopoint("S 33° 50.326 E 151° 12.426"), 13));
}
+ private static void assertTileAt(int x, int y, final Tile tile) {
+ assertEquals(x, tile.getX());
+ assertEquals(y, tile.getY());
+ }
}
diff --git a/tests/src/cgeo/geocaching/connector/gc/IconDecoderTest.java b/tests/src/cgeo/geocaching/connector/gc/IconDecoderTest.java
new file mode 100644
index 0000000..db6dc44
--- /dev/null
+++ b/tests/src/cgeo/geocaching/connector/gc/IconDecoderTest.java
@@ -0,0 +1,52 @@
+package cgeo.geocaching.connector.gc;
+
+import cgeo.geocaching.Settings;
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.enumerations.CacheType;
+import cgeo.geocaching.test.AbstractResourceInstrumentationTestCase;
+import cgeo.geocaching.test.R;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+
+public class IconDecoderTest extends AbstractResourceInstrumentationTestCase {
+
+ public void testparseMapPNG14() {
+ final Bitmap bitmap = getBitmap(R.raw.tile14);
+ Log.d(Settings.tag, "Bitmap=" + bitmap.getWidth() + "x" + bitmap.getHeight());
+
+ assertEquals(CacheType.TRADITIONAL, parse14(bitmap, 97 / 4, 136 / 4).getType());
+ assertEquals(CacheType.MYSTERY, parse14(bitmap, 226 / 4, 104 / 4).getType());
+ assertEquals(CacheType.MULTI, parse14(bitmap, 54 / 4, 97 / 4).getType());
+ assertTrue(parse14(bitmap, 119 / 4, 108 / 4).isFound());
+ }
+
+ private Bitmap getBitmap(int resourceId) {
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inScaled = false;
+ final Bitmap bitmap = BitmapFactory.decodeStream(getInstrumentation().getContext().getResources().openRawResource(resourceId));
+ assert bitmap.getWidth() == Tile.TILE_SIZE : "Wrong size";
+ return bitmap;
+ }
+
+ private static cgCache parse14(Bitmap bitmap, int x, int y) {
+ final cgCache cache = new cgCache();
+ IconDecoder.parseMapPNG14(cache, bitmap, new UTFGridPosition(x, y));
+ return cache;
+ }
+
+ public void testParseMap13() {
+ final Bitmap bitmap = getBitmap(R.raw.tile13);
+
+ assertEquals(CacheType.TRADITIONAL, parse13(bitmap, 146 / 4, 225 / 4).getType());
+ assertEquals(CacheType.MYSTERY, parse13(bitmap, 181 / 4, 116 / 4).getType());
+ assertEquals(CacheType.MULTI, parse13(bitmap, 118 / 4, 230 / 4).getType());
+ }
+
+ private static cgCache parse13(Bitmap bitmap, int x, int y) {
+ final cgCache cache = new cgCache();
+ IconDecoder.parseMapPNG13(cache, bitmap, new UTFGridPosition(x, y));
+ return cache;
+ }
+}