diff --git a/assets/tiled_base64_zlib_infinite.tmx b/assets/tiled_base64_zlib_infinite.tmx
new file mode 100644
index 0000000000000000000000000000000000000000..f8398d24127df606ea7d149f1f9754a950b505ce
--- /dev/null
+++ b/assets/tiled_base64_zlib_infinite.tmx
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<map version="1.2" tiledversion="2020.05.20" orientation="orthogonal" renderorder="right-down" width="100" height="100" tilewidth="32" tileheight="32" infinite="1" backgroundcolor="#ff00ff" nextlayerid="6" nextobjectid="5">
+ <editorsettings>
+  <chunksize width="32" height="32"/>
+ </editorsettings>
+ <tileset firstgid="1" name="tilesheet" tilewidth="32" tileheight="32" tilecount="84" columns="14">
+  <image source="tilesheet.png" width="448" height="192"/>
+  <tile id="1">
+   <properties>
+    <property name="a tile property" value="123"/>
+   </properties>
+  </tile>
+ </tileset>
+ <tileset firstgid="85" source="tilesheet.tsx"/>
+ <layer id="3" name="Background" width="100" height="100">
+  <data encoding="base64" compression="zlib">
+   <chunk x="-32" y="0" width="32" height="32">
+   eJztzTENAAAMw7BiGH+wg9CjryPldrJ142t8Pp/P5/P5fD6fz+fz+w/olSQB
+  </chunk>
+   <chunk x="0" y="0" width="32" height="32">
+   eJztwwEJAAAMBKHL8P3DrsdQcNVUVVXV1w/BwEgB
+  </chunk>
+   <chunk x="-32" y="32" width="32" height="32">
+   eJztzcEJAAAIA7HO4P7DOkRBEBK49yWdKWv5+/v7+/v73/8BgH8WAIoSAQ==
+  </chunk>
+   <chunk x="0" y="32" width="32" height="32">
+   eJztwwEJAAAAAqA29H9sQ1KwSaqqXgUA/gxxUCQB
+  </chunk>
+  </data>
+ </layer>
+ <layer id="4" name="Ground" width="100" height="100" locked="1">
+  <data encoding="base64" compression="zlib">
+   <chunk x="0" y="0" width="32" height="32">
+   eJztVLsOwjAQi4Af6MAnIBb4AgRiRUKw8+hMS2fg87mInGSdLk0ThgyNJYtXajvxBWMKCgoK4nAhXom3TN4dsSE+XY5/s/B+NErdB/FOfANryJKSw2o2HrYiZ+e+q4AvkSM2Az/PXMD7j5KzFc9jjlr5PYRKcCI+h/xRx66JPQN7rivi2r0ujd4/+/fpp5yB1Z0Dff3jnODsS3aBjJq/1ZRzLfvnvflmtW92Q/4zRzkL2D/efS0r34EU/yHr8fzlHWTKNUP9D6a/U+6V9/5RldL9pyau10pVSvPn/58NUOtWm0mfVmgdgrvbmd/92xu9W20mfVqhdRrQPwfG7n8knomnTP4W24zexX9c/l+dHlQo
+  </chunk>
+   <chunk x="0" y="32" width="32" height="32">
+   eJzt0KESABAQRdH9IwlJIlH8/9fYQKJ66Z6ZV5S7w+xWHm9Kpx99w5fE/by70xdM/x+nV/cdTdzv4h4AAAAA4L8FOaQDyA==
+  </chunk>
+  </data>
+ </layer>
+ <layer id="5" name="Overlay" width="100" height="100">
+  <data encoding="base64" compression="zlib">
+   <chunk x="0" y="0" width="32" height="32">
+   eJztwzENAAAIA7A5wb9L3hkgPG3SBAB+TQUA4MYCfd0AXg==
+  </chunk>
+  </data>
+ </layer>
+ <objectgroup id="2" name="Object group">
+  <object id="1" x="14" y="9" width="285" height="135"/>
+  <object id="2" x="329" y="217" width="102" height="109">
+   <ellipse/>
+  </object>
+  <object id="3" x="314" y="376">
+   <polyline points="0,0 -111,-63 -203,27 -205,-130 -78,-150 -6,-6"/>
+  </object>
+  <object id="4" x="479" y="84">
+   <polygon points="0,0 139,128 -55,64 -37,-49 159,47 138,126"/>
+  </object>
+ </objectgroup>
+</map>
diff --git a/src/lib.rs b/src/lib.rs
index cd201360dd4eddcb5dd8791913fbd5682f1e197c..e873e8519188ffca526257d9f4fc8d3917466909 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -236,6 +236,7 @@ pub struct Map {
     pub object_groups: Vec<ObjectGroup>,
     pub properties: Properties,
     pub background_colour: Option<Colour>,
+    pub infinite: bool,
 }
 
 impl Map {
@@ -244,10 +245,11 @@ impl Map {
         attrs: Vec<OwnedAttribute>,
         map_path: Option<&Path>,
     ) -> Result<Map, TiledError> {
-        let (c, (v, o, w, h, tw, th)) = get_attrs!(
+        let ((c, infinite), (v, o, w, h, tw, th)) = get_attrs!(
             attrs,
             optionals: [
                 ("backgroundcolor", colour, |v:String| v.parse().ok()),
+                ("infinite", infinite, |v:String| Some(v == "1")),
             ],
             required: [
                 ("version", version, |v| Some(v)),
@@ -272,7 +274,7 @@ impl Map {
                 Ok(())
             },
             "layer" => |attrs| {
-                layers.push(Layer::new(parser, attrs, w, layer_index)?);
+                layers.push(Layer::new(parser, attrs, w, layer_index, infinite.unwrap_or(false))?);
                 layer_index += 1;
                 Ok(())
             },
@@ -304,6 +306,7 @@ impl Map {
             object_groups,
             properties,
             background_colour: c,
+            infinite: infinite.unwrap_or(false)
         })
     }
 
@@ -666,7 +669,7 @@ pub struct Layer {
     pub visible: bool,
     /// The tiles are arranged in rows. Each tile is a number which can be used
     ///  to find which tileset it belongs to and can then be rendered.
-    pub tiles: Vec<Vec<LayerTile>>,
+    pub tiles: LayerData,
     pub properties: Properties,
     pub layer_index: u32,
 }
@@ -677,6 +680,7 @@ impl Layer {
         attrs: Vec<OwnedAttribute>,
         width: u32,
         layer_index: u32,
+        infinite: bool,
     ) -> Result<Layer, TiledError> {
         let ((o, v), n) = get_attrs!(
             attrs,
@@ -689,11 +693,15 @@ impl Layer {
             ],
             TiledError::MalformedAttributes("layer must have a name".to_string())
         );
-        let mut tiles = Vec::new();
+        let mut tiles: LayerData = LayerData::Finite(Default::default());
         let mut properties = HashMap::new();
         parse_tag!(parser, "layer", {
             "data" => |attrs| {
-                tiles = parse_data(parser, attrs, width)?;
+                if infinite {
+                    tiles = parse_infinite_data(parser, attrs, width)?;
+                } else {
+                    tiles = parse_data(parser, attrs, width)?;
+                }
                 Ok(())
             },
             "properties" => |_| {
@@ -712,6 +720,55 @@ impl Layer {
         })
     }
 }
+#[derive(Debug, PartialEq, Clone)]
+pub enum LayerData {
+    Finite(Vec<Vec<LayerTile>>),
+    Infinite(HashMap<(i32, i32), Chunk>)
+}
+
+#[derive(Debug, PartialEq, Clone)]
+pub struct Chunk {
+    pub x: i32,
+    pub y: i32,
+    pub width: u32,
+    pub height: u32,
+    pub tiles: Vec<Vec<LayerTile>>,
+}
+
+
+impl Chunk {
+    pub(crate) fn new<R: Read>(
+        parser: &mut EventReader<R>,
+        attrs: Vec<OwnedAttribute>,    
+        encoding: Option<String>,
+        compression: Option<String>,
+    ) -> Result<Chunk, TiledError> {
+        let ((), (x, y, width, height)) = get_attrs!(
+            attrs,
+            optionals: [],
+            required: [
+                ("x", x, |v: String| v.parse().ok()),
+                ("y", y, |v: String| v.parse().ok()),
+                ("width", width, |v: String| v.parse().ok()),
+                ("height", height, |v: String| v.parse().ok()),
+            ],
+            TiledError::MalformedAttributes("layer must have a name".to_string())
+        );
+
+       
+
+        let tiles = parse_data_line(encoding, compression, parser, width)?;
+        
+        Ok(Chunk {
+                x,
+                y,
+                width,
+                height,
+                tiles,
+            })
+    }
+}
+
 
 #[derive(Debug, PartialEq, Clone)]
 pub struct ImageLayer {
@@ -1007,11 +1064,38 @@ fn parse_animation<R: Read>(parser: &mut EventReader<R>) -> Result<Vec<Frame>, T
     Ok(animation)
 }
 
+fn parse_infinite_data<R: Read>(
+    parser: &mut EventReader<R>,
+    attrs: Vec<OwnedAttribute>,
+    width: u32,
+) -> Result<LayerData, TiledError> {
+    let ((e, c), ()) = get_attrs!(
+        attrs,
+        optionals: [
+            ("encoding", encoding, |v| Some(v)),
+            ("compression", compression, |v| Some(v)),
+        ],
+        required: [],
+        TiledError::MalformedAttributes("data must have an encoding and a compression".to_string())
+    );
+    
+    let mut chunks = HashMap::<(i32, i32), Chunk>::new();
+    parse_tag!(parser, "data", {
+        "chunk" => |attrs| {
+            let chunk = Chunk::new(parser, attrs, e.clone(), c.clone())?;            
+            chunks.insert((chunk.x, chunk.y), chunk);            
+            Ok(())
+        }
+    });
+
+    Ok(LayerData::Infinite(chunks))
+}
+
 fn parse_data<R: Read>(
     parser: &mut EventReader<R>,
     attrs: Vec<OwnedAttribute>,
     width: u32,
-) -> Result<Vec<Vec<LayerTile>>, TiledError> {
+) -> Result<LayerData, TiledError> {
     let ((e, c), ()) = get_attrs!(
         attrs,
         optionals: [
@@ -1022,7 +1106,13 @@ fn parse_data<R: Read>(
         TiledError::MalformedAttributes("data must have an encoding and a compression".to_string())
     );
 
-    match (e, c) {
+    let tiles = parse_data_line(e, c, parser, width)?;
+
+    Ok(LayerData::Finite(tiles))
+}
+
+fn parse_data_line<R: Read>(encoding: Option<String>, compression: Option<String>, parser: &mut EventReader<R>, width: u32) -> Result<Vec<Vec<LayerTile>>, TiledError> {
+    match (encoding, compression) {
         (None, None) => {
             return Err(TiledError::Other(
                 "XML format is currently not supported".to_string(),
diff --git a/tests/lib.rs b/tests/lib.rs
index 3aca62930f94318a4b77332b58fe5523821ec881..957fa8e2c9cd9819bf8d54081e73d8666385c4d5 100644
--- a/tests/lib.rs
+++ b/tests/lib.rs
@@ -1,6 +1,6 @@
 use std::fs::File;
 use std::path::Path;
-use tiled::{parse, parse_file, parse_tileset, Map, PropertyValue, TiledError};
+use tiled::{parse, parse_file, parse_tileset, Map, PropertyValue, TiledError, LayerData};
 
 fn read_from_file(p: &Path) -> Result<Map, TiledError> {
     let file = File::open(p).unwrap();
@@ -36,6 +36,24 @@ fn test_just_tileset() {
     assert_eq!(r.tilesets[0], t);
 }
 
+#[test]
+fn test_infinite_tileset() {
+    let r = read_from_file_with_path(&Path::new("assets/tiled_base64_zlib_infinite.tmx")).unwrap();    
+
+    if let LayerData::Infinite(chunks) = &r.layers[0].tiles {
+        assert_eq!(chunks.len(), 4);
+
+        assert_eq!(chunks[&(0, 0)].width, 32);
+        assert_eq!(chunks[&(0, 0)].height, 32);
+        assert_eq!(chunks[&(-32, 0)].width, 32);
+        assert_eq!(chunks[&(0, 32)].height, 32);
+        assert_eq!(chunks[&(-32, 32)].height, 32);
+    } else {
+        assert!(false, "It is wrongly recognized as a finite map");
+
+    }
+}
+
 #[test]
 fn test_image_layers() {
     let r = read_from_file(&Path::new("assets/tiled_image_layers.tmx")).unwrap();
@@ -104,23 +122,29 @@ fn test_tileset_property() {
 #[test]
 fn test_flipped_gid() {
     let r = read_from_file_with_path(&Path::new("assets/tiled_flipped.tmx")).unwrap();
-    let t1 = r.layers[0].tiles[0][0];
-    let t2 = r.layers[0].tiles[0][1];
-    let t3 = r.layers[0].tiles[1][0];
-    let t4 = r.layers[0].tiles[1][1];
-    assert_eq!(t1.gid, t2.gid);
-    assert_eq!(t2.gid, t3.gid);
-    assert_eq!(t3.gid, t4.gid);
-    assert!(t1.flip_d);
-    assert!(t1.flip_h);
-    assert!(t1.flip_v);
-    assert!(!t2.flip_d);
-    assert!(!t2.flip_h);
-    assert!(t2.flip_v);
-    assert!(!t3.flip_d);
-    assert!(t3.flip_h);
-    assert!(!t3.flip_v);
-    assert!(t4.flip_d);
-    assert!(!t4.flip_h);
-    assert!(!t4.flip_v);
+    
+    if let LayerData::Finite(tiles) = &r.layers[0].tiles {
+        let t1 = tiles[0][0];
+        let t2 = tiles[0][1];
+        let t3 = tiles[1][0];
+        let t4 = tiles[1][1];
+        assert_eq!(t1.gid, t2.gid);
+        assert_eq!(t2.gid, t3.gid);
+        assert_eq!(t3.gid, t4.gid);
+        assert!(t1.flip_d);
+        assert!(t1.flip_h);
+        assert!(t1.flip_v);
+        assert!(!t2.flip_d);
+        assert!(!t2.flip_h);
+        assert!(t2.flip_v);
+        assert!(!t3.flip_d);
+        assert!(t3.flip_h);
+        assert!(!t3.flip_v);
+        assert!(t4.flip_d);
+        assert!(!t4.flip_h);
+        assert!(!t4.flip_v);
+    } else {
+        assert!(false, "It is wrongly recognized as an infinite map");
+    }
+    
 }