[mapnik] 01/06: Imported Upstream version 3.0.5+ds

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Sun Sep 20 11:36:55 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository mapnik.

commit f4e16e9c89f476958f042cd5499fb3074e97c113
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Sun Sep 20 11:57:30 2015 +0200

    Imported Upstream version 3.0.5+ds
---
 .gitignore                                         |   1 +
 CHANGELOG.md                                       |  21 +
 benchmark/data/polygon_rendering_clip.xml          |   2 +-
 benchmark/data/polygon_rendering_no_clip.xml       |   2 +-
 benchmark/data/roads.xml                           |   2 +-
 benchmark/test_array_allocation.cpp                |  29 +-
 benchmark/test_expression_parse.cpp                |   2 +-
 benchmark/test_numeric_cast_vs_static_cast.cpp     |   7 +-
 benchmark/test_offset_converter.cpp                |   5 +-
 benchmark/test_polygon_clipping.cpp                |   9 +-
 benchmark/test_polygon_clipping_rendering.cpp      |  11 +-
 benchmark/test_proj_transform1.cpp                 |  10 +-
 benchmark/test_rendering.cpp                       |   5 +-
 benchmark/test_rendering_shared_map.cpp            |   5 +-
 benchmark/test_utf_encoding.cpp                    |   8 +-
 include/mapnik/csv/csv_grammar.hpp                 |   2 +-
 include/mapnik/debug.hpp                           | 447 +++++++++++----------
 include/mapnik/image.hpp                           |  31 +-
 include/mapnik/image_filter.hpp                    |  13 +-
 include/mapnik/image_filter_types.hpp              |  15 +-
 include/mapnik/image_impl.hpp                      |  39 +-
 include/mapnik/json/topojson_grammar_impl.hpp      |   2 +-
 include/mapnik/json/topojson_utils.hpp             |   6 -
 include/mapnik/json/topology.hpp                   |   5 +-
 .../renderer_common/process_markers_symbolizer.hpp |   6 +-
 .../renderer_common/process_polygon_symbolizer.hpp |   2 +-
 include/mapnik/text/placement_finder.hpp           |   2 +-
 include/mapnik/util/singleton.hpp                  |   4 +-
 include/mapnik/version.hpp                         |   3 +-
 plugins/input/csv/build.py                         |  79 ++--
 plugins/input/csv/csv_datasource.cpp               |  98 +++--
 plugins/input/csv/csv_datasource.hpp               |   4 +-
 plugins/input/csv/csv_featureset.cpp               |  22 +-
 plugins/input/csv/csv_featureset.hpp               |  14 +-
 plugins/input/csv/csv_utils.hpp                    |   8 +-
 plugins/input/topojson/topojson_datasource.cpp     |  13 +-
 src/agg/process_line_pattern_symbolizer.cpp        |   4 +-
 src/agg/process_polygon_pattern_symbolizer.cpp     |   4 +-
 src/cairo/process_line_pattern_symbolizer.cpp      |   2 +-
 src/cairo/process_polygon_pattern_symbolizer.cpp   |   2 +-
 src/debug.cpp                                      |  50 +--
 src/grid/process_line_pattern_symbolizer.cpp       |   2 +-
 src/grid/process_polygon_pattern_symbolizer.cpp    |   2 +-
 src/image.cpp                                      |  39 +-
 src/svg/svg_parser.cpp                             |   5 +
 src/text/placement_finder.cpp                      |   2 +
 src/text/symbolizer_helpers.cpp                    |  16 +-
 src/unicode.cpp                                    |   2 +-
 test/standalone/csv_test.cpp                       |   1 +
 test/unit/imaging/image.cpp                        | 106 ++++-
 test/unit/imaging/image_filter.cpp                 |  92 ++++-
 test/unit/imaging/image_io_test.cpp                |   5 +
 52 files changed, 767 insertions(+), 501 deletions(-)

diff --git a/.gitignore b/.gitignore
index 9b10ae8..816bc0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@
 *.a
 *.swp
 *.dylib
+mapnik-gyp
 plugins/input/*.input
 plugins/input/templates/*.input
 demo/c++/rundemo
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fb40544..538d4ca 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,27 @@ Released: YYYY XX, 2015
 
 (Packaged from xxxx)
 
+## 3.0.5
+
+Released: September 16, 2015
+
+(Packaged from 165c704)
+
+#### Summary
+
+- `scale-hsla` image filter: parameters are no longer limited by interval \[0, 1\] (https://github.com/mapnik/mapnik/pull/3054)
+- Windows: Fixed SVG file loading from unicode paths
+- `colorize-alpha` image filter: fixed normalization of color components (https://github.com/mapnik/mapnik/pull/3058)
+- `colorize-alpha` image filter: added support for transparent colors (https://github.com/mapnik/mapnik/pull/3061)
+- Enable reading optional `MAPNIK_LOG_FORMAT` environment variable(https://github.com/mapnik/mapnik/commit/6d1ffc8a93008b8c0a89d87d68b59afb2cb3757f)
+- CSV.input uses memory mapped file by default on *nix.
+- Updated bundled fonts to the latest version
+- Topojson.input - fixed geometry_index logic which was causing missing features
+- Fixed SVG file loading from unicode paths (https://github.com/mapnik/node-mapnik/issues/517)
+- CSV.input - improved support for LF/CR/CRLF line endings on all platforms (https://github.com/mapnik/mapnik/issues/3065)
+- Revive `zero allocation image interface` and add unit tests
+- Benchmark: use return values of test runner.
+
 ## 3.0.4
 
 Released: August 26, 2015
diff --git a/benchmark/data/polygon_rendering_clip.xml b/benchmark/data/polygon_rendering_clip.xml
index 98f0ec6..97847de 100644
--- a/benchmark/data/polygon_rendering_clip.xml
+++ b/benchmark/data/polygon_rendering_clip.xml
@@ -7,7 +7,7 @@
     <Layer name="world" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
         <StyleName>style</StyleName>
         <Datasource>
-            <Parameter name="file">../../tests/data/shp/world_merc.shp</Parameter>
+            <Parameter name="file">../../test/data/shp/world_merc.shp</Parameter>
             <Parameter name="type">shape</Parameter>
         </Datasource>
     </Layer>
diff --git a/benchmark/data/polygon_rendering_no_clip.xml b/benchmark/data/polygon_rendering_no_clip.xml
index 8d478e0..36570f1 100644
--- a/benchmark/data/polygon_rendering_no_clip.xml
+++ b/benchmark/data/polygon_rendering_no_clip.xml
@@ -7,7 +7,7 @@
     <Layer name="world" srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over">
         <StyleName>style</StyleName>
         <Datasource>
-            <Parameter name="file">../../tests/data/shp/world_merc.shp</Parameter>
+            <Parameter name="file">../../test/data/shp/world_merc.shp</Parameter>
             <Parameter name="type">shape</Parameter>
         </Datasource>
     </Layer>
diff --git a/benchmark/data/roads.xml b/benchmark/data/roads.xml
index bc0ad52..0ca938f 100644
--- a/benchmark/data/roads.xml
+++ b/benchmark/data/roads.xml
@@ -2,7 +2,7 @@
 <!DOCTYPE Map[]>
 <Map
   srs="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over"
-  font-directory="../../fonts/dejavu-fonts-ttf-2.34/ttf/DejaVuSans.ttf"
+  font-directory="../../fonts/dejavu-fonts-ttf-2.35/ttf/DejaVuSans.ttf"
   background-color="#dfd8c9">
 
 <Style name="marking" filter-mode="first">
diff --git a/benchmark/test_array_allocation.cpp b/benchmark/test_array_allocation.cpp
index 05da7ae..fda9bb6 100644
--- a/benchmark/test_array_allocation.cpp
+++ b/benchmark/test_array_allocation.cpp
@@ -386,61 +386,62 @@ public:
 
 int main(int argc, char** argv)
 {
+    int return_value = 0;
     mapnik::parameters params;
     benchmark::handle_args(argc,argv,params);
     {
         test4 test_runner4(params);
-        run(test_runner4,"calloc");
+        return_value = return_value | run(test_runner4,"calloc");
     }
     {
         test1 test_runner(params);
-        run(test_runner,"malloc/memcpy");
+        return_value = return_value | run(test_runner,"malloc/memcpy");
     }
     {
         test1b test_runner(params);
-        run(test_runner,"malloc/memset");
+        return_value = return_value | run(test_runner,"malloc/memset");
     }
     {
         test1c test_runner(params);
-        run(test_runner,"operator new/std::fill");
+        return_value = return_value | run(test_runner,"operator new/std::fill");
     }
     {
         test2 test_runner(params);
-        run(test_runner,"operator new/memcpy");
+        return_value = return_value | run(test_runner,"operator new/memcpy");
     }
     {
         test3 test_runner(params);
-        run(test_runner,"vector(N)");
+        return_value = return_value | run(test_runner,"vector(N)");
     }
     {
         test3b test_runner(params);
-        run(test_runner,"vector/resize");
+        return_value = return_value | run(test_runner,"vector/resize");
     }
     {
         test3c test_runner(params);
-        run(test_runner,"vector/assign");
+        return_value = return_value | run(test_runner,"vector/assign");
     }
     {
         test3d test_runner(params);
-        run(test_runner,"deque(N)");
+        return_value = return_value | run(test_runner,"deque(N)");
     }
     {
         test5 test_runner(params);
-        run(test_runner,"std::string range");
+        return_value = return_value | run(test_runner,"std::string range");
     }
     {
         test5b test_runner(params);
-        run(test_runner,"std::string &[0]");
+        return_value = return_value | run(test_runner,"std::string &[0]");
     }
     {
         test6 test_runner(params);
-        run(test_runner,"valarray");
+        return_value = return_value | run(test_runner,"valarray");
     }
 #if BOOST_VERSION >= 105400
     {
         test7 test_runner(params);
-        run(test_runner,"static_vector");
+        return_value = return_value | run(test_runner,"static_vector");
     }
 #endif
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_expression_parse.cpp b/benchmark/test_expression_parse.cpp
index 704a69c..7e39922 100644
--- a/benchmark/test_expression_parse.cpp
+++ b/benchmark/test_expression_parse.cpp
@@ -37,5 +37,5 @@ int main(int argc, char** argv)
     mapnik::parameters params;
     benchmark::handle_args(argc,argv,params);
     test test_runner(params);
-    run(test_runner,"expr parsing");
+    return run(test_runner,"expr parsing");
 }
diff --git a/benchmark/test_numeric_cast_vs_static_cast.cpp b/benchmark/test_numeric_cast_vs_static_cast.cpp
index 52865ac..8ea6e6b 100644
--- a/benchmark/test_numeric_cast_vs_static_cast.cpp
+++ b/benchmark/test_numeric_cast_vs_static_cast.cpp
@@ -75,13 +75,14 @@ int main(int argc, char** argv)
 {
     mapnik::parameters params;
     benchmark::handle_args(argc,argv,params);
+    int return_value = 0;
     {
         test_static test_runner(params);
-        run(test_runner,"static_cast");
+        return_value = return_value | run(test_runner,"static_cast");
     }
     {
         test_numeric test_runner(params);
-        run(test_runner,"numeric_cast");
+        return_value = return_value | run(test_runner,"numeric_cast");
     }
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_offset_converter.cpp b/benchmark/test_offset_converter.cpp
index 4bd3175..c0d25da 100644
--- a/benchmark/test_offset_converter.cpp
+++ b/benchmark/test_offset_converter.cpp
@@ -93,9 +93,10 @@ int main(int argc, char** argv)
 {
     mapnik::parameters params;
     benchmark::handle_args(argc,argv,params);
+    int return_value = 0;
     {
         test_offset test_runner(params);
-        run(test_runner,"offset_test");
+        return_value = run(test_runner,"offset_test");
     }
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_polygon_clipping.cpp b/benchmark/test_polygon_clipping.cpp
index 0005fc9..b189a04 100644
--- a/benchmark/test_polygon_clipping.cpp
+++ b/benchmark/test_polygon_clipping.cpp
@@ -528,19 +528,20 @@ int main(int argc, char** argv)
         throw std::runtime_error("could not open: '" + filename_ + "'");
     std::string wkt_in( (std::istreambuf_iterator<char>(in) ),
                (std::istreambuf_iterator<char>()) );
+    int return_value = 0;
     {
         test1 test_runner(params,wkt_in,clipping_box);
-        run(test_runner,"clipping polygon with agg");
+        return_value = return_value | run(test_runner,"clipping polygon with agg");
     }
     {
         test3 test_runner(params,wkt_in,clipping_box);
-        run(test_runner,"clipping polygon with boost");
+        return_value = return_value | run(test_runner,"clipping polygon with boost");
     }
     /*
     {
         test4 test_runner(params,wkt_in,clipping_box);
-        run(test_runner,"clipping polygon with clipper_tree");
+        return_value = return_value | run(test_runner,"clipping polygon with clipper_tree");
     }
     */
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_polygon_clipping_rendering.cpp b/benchmark/test_polygon_clipping_rendering.cpp
index 88f20d5..ab23459 100644
--- a/benchmark/test_polygon_clipping_rendering.cpp
+++ b/benchmark/test_polygon_clipping_rendering.cpp
@@ -51,29 +51,30 @@ int main(int argc, char** argv)
     mapnik::box2d<double> z1(-20037508.3428,-8317435.0606,20037508.3428,18399242.7298);
     // bbox for 16/10491/22911.png
     mapnik::box2d<double> z16(-13622912.929097254,6026906.8062295765,-13621689.93664469,6028129.79868214);
+    int return_value = 0;
     {
         test test_runner(params,
                           "benchmark/data/polygon_rendering_clip.xml",
                           z1);
-        run(test_runner,"polygon clip render z1");        
+        return_value = return_value | run(test_runner,"polygon clip render z1");
     }
     {
         test test_runner(params,
                           "benchmark/data/polygon_rendering_no_clip.xml",
                           z1);
-        run(test_runner,"polygon noclip render z1");        
+        return_value = return_value | run(test_runner,"polygon noclip render z1");
     }
     {
         test test_runner(params,
                           "benchmark/data/polygon_rendering_clip.xml",
                           z16);
-        run(test_runner,"polygon clip render z16");        
+        return_value = return_value | run(test_runner,"polygon clip render z16");
     }
     {
         test test_runner(params,
                           "benchmark/data/polygon_rendering_no_clip.xml",
                           z16);
-        run(test_runner,"polygon noclip render z16");        
+        return_value = return_value | run(test_runner,"polygon noclip render z16");
     }
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_proj_transform1.cpp b/benchmark/test_proj_transform1.cpp
index b98a497..451c51a 100644
--- a/benchmark/test_proj_transform1.cpp
+++ b/benchmark/test_proj_transform1.cpp
@@ -67,32 +67,34 @@ int main(int argc, char** argv)
     std::string to_str("+init=epsg:3857");
     std::string from_str2("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
     std::string to_str2("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over");
+    int return_value = 0;
     test test_runner(params,
                      from_str,
                      to_str,
                      from,
                      to,
                      true);
-    run(test_runner,"lonlat->merc epsg");
+    return_value = return_value | run(test_runner,"lonlat->merc epsg");
     test test_runner2(params,
                      from_str2,
                      to_str2,
                      from,
                      to,
                      true);
-    run(test_runner2,"lonlat->merc literal");
+    return_value = return_value | run(test_runner2,"lonlat->merc literal");
     test test_runner3(params,
                      to_str,
                      from_str,
                      to,
                      from,
                      true);
-    run(test_runner3,"merc->lonlat epsg");
+    return_value = return_value | run(test_runner3,"merc->lonlat epsg");
     test test_runner4(params,
                      to_str2,
                      from_str2,
                      to,
                      from,
                      true);
-    return run(test_runner4,"merc->lonlat literal");
+    return_value = return_value | run(test_runner4,"merc->lonlat literal");
+    return return_value;
 }
diff --git a/benchmark/test_rendering.cpp b/benchmark/test_rendering.cpp
index 30e80be..593307b 100644
--- a/benchmark/test_rendering.cpp
+++ b/benchmark/test_rendering.cpp
@@ -88,6 +88,7 @@ public:
 
 int main(int argc, char** argv)
 {
+    int return_value = 0;
     try
     {
         mapnik::parameters params;
@@ -102,7 +103,7 @@ int main(int argc, char** argv)
         mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
         {
             test test_runner(params);
-            run(test_runner,*name);        
+            return_value = run(test_runner,*name);
         }
     }
     catch (std::exception const& ex)
@@ -110,5 +111,5 @@ int main(int argc, char** argv)
         std::clog << ex.what() << "\n";
         return -1;
     }
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_rendering_shared_map.cpp b/benchmark/test_rendering_shared_map.cpp
index 0b57053..75631f7 100644
--- a/benchmark/test_rendering_shared_map.cpp
+++ b/benchmark/test_rendering_shared_map.cpp
@@ -145,6 +145,7 @@ public:
 
 int main(int argc, char** argv)
 {
+    int return_value = 0;
     try
     {
         mapnik::parameters params;
@@ -159,7 +160,7 @@ int main(int argc, char** argv)
         mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
         {
             test test_runner(params);
-            run(test_runner,*name);
+            return_value = run(test_runner,*name);
         }
     }
     catch (std::exception const& ex)
@@ -167,5 +168,5 @@ int main(int argc, char** argv)
         std::clog << ex.what() << "\n";
         return -1;
     }
-    return 0;
+    return return_value;
 }
diff --git a/benchmark/test_utf_encoding.cpp b/benchmark/test_utf_encoding.cpp
index 100cbd6..a4ba10a 100644
--- a/benchmark/test_utf_encoding.cpp
+++ b/benchmark/test_utf_encoding.cpp
@@ -97,14 +97,16 @@ int main(int argc, char** argv)
 {
     mapnik::parameters params;
     benchmark::handle_args(argc,argv,params);
+    int return_value = 0;
 #ifndef __linux__
     test test_runner(params);
-    run(test_runner,"utf encode std::codecvt");
+    return_value = return_value | run(test_runner,"utf encode std::codecvt");
 #else
     std::clog << "skipping 'utf encode std::codecvt' test since <codecvt> is not supported on __linux__\n";
 #endif
     test2 test_runner2(params);
-    run(test_runner2,"utf encode boost::locale");
+    return_value = return_value | run(test_runner2,"utf encode boost::locale");
     test3 test_runner3(params);
-    return run(test_runner3,"utf encode ICU");
+    return_value = return_value | run(test_runner3,"utf encode ICU");
+    return return_value;
 }
diff --git a/include/mapnik/csv/csv_grammar.hpp b/include/mapnik/csv/csv_grammar.hpp
index 195542b..2bd0f52 100644
--- a/include/mapnik/csv/csv_grammar.hpp
+++ b/include/mapnik/csv/csv_grammar.hpp
@@ -64,7 +64,7 @@ struct csv_line_grammar : qi::grammar<Iterator, csv_line(std::string const&), qi
 
         line = column(_r1)  % char_(_r1)
             ;
-        column = quoted | *(char_ - (lit(_r1) /*| eol*/))
+        column = -omit[char_("\n\r")] >> quoted | *(char_ - (lit(_r1) /*| eol*/))
             ;
         quoted = omit[char_("\"'")[_a = _1]] > text(_a) > -lit(_a)
             ;
diff --git a/include/mapnik/debug.hpp b/include/mapnik/debug.hpp
index aaccb4f..cf5e5b9 100644
--- a/include/mapnik/debug.hpp
+++ b/include/mapnik/debug.hpp
@@ -37,293 +37,294 @@
 #include <unordered_map>
 #ifdef MAPNIK_THREADSAFE
 #include <mutex>
+#include <atomic>
 #endif
 
 namespace mapnik {
 
-    /*
-        Global logger class that holds the configuration of severity, format
-        and file/console redirection.
-    */
-    class MAPNIK_DECL logger :
+
+// Global logger class that holds the configuration of severity, format
+// and file/console redirection.
+
+class MAPNIK_DECL logger :
         public singleton<logger,CreateStatic>,
         private util::noncopyable
+{
+public:
+    enum severity_type
     {
-    public:
-        enum severity_type
-        {
-            debug = 0,
-            warn = 1,
-            error = 2,
-            none = 3
-        };
+        debug = 0,
+        warn = 1,
+        error = 2,
+        none = 3
+    };
 
-        using severity_map = std::unordered_map<std::string, severity_type>;
+    using severity_map = std::unordered_map<std::string, severity_type>;
 
-        // global security level
-        static severity_type get_severity()
-        {
-            return severity_level_;
-        }
+    // global security level
+    static severity_type get_severity()
+    {
+        return severity_level_;
+    }
 
-        static void set_severity(severity_type const& severity_level)
+    static void set_severity(severity_type severity_level)
+    {
+//#ifdef MAPNIK_THREADSAFE
+//        std::lock_guard<std::mutex> lock(severity_mutex_);
+//#endif
+        severity_level_ = severity_level;
+    }
+
+    // per object security levels
+    static severity_type get_object_severity(std::string const& object_name)
+    {
+        severity_map::iterator it = object_severity_level_.find(object_name);
+        if (object_name.empty() || it == object_severity_level_.end())
         {
-#ifdef MAPNIK_THREADSAFE
-            std::lock_guard<std::mutex> lock(severity_mutex_);
-#endif
-
-            severity_level_ = severity_level;
+            return severity_level_;
         }
-
-        // per object security levels
-        static severity_type get_object_severity(std::string const& object_name)
+        else
         {
-            severity_map::iterator it = object_severity_level_.find(object_name);
-            if (object_name.empty() || it == object_severity_level_.end())
-            {
-                return severity_level_;
-            }
-            else
-            {
-                return it->second;
-            }
+            return it->second;
         }
+    }
 
-        static void set_object_severity(std::string const& object_name,
-                                        severity_type const& security_level)
+    static void set_object_severity(std::string const& object_name,
+                                    severity_type const& security_level)
+    {
+        if (!object_name.empty())
         {
 #ifdef MAPNIK_THREADSAFE
             std::lock_guard<std::mutex> lock(severity_mutex_);
 #endif
-            if (! object_name.empty())
-            {
-                object_severity_level_[object_name] = security_level;
-            }
+            object_severity_level_[object_name] = security_level;
         }
+    }
 
-        static void clear_object_severity()
-        {
+    static void clear_object_severity()
+    {
 #ifdef MAPNIK_THREADSAFE
-            std::lock_guard<std::mutex> lock(severity_mutex_);
+        std::lock_guard<std::mutex> lock(severity_mutex_);
 #endif
 
-            object_severity_level_.clear();
-        }
+        object_severity_level_.clear();
+    }
 
-        // format
-        static std::string get_format()
-        {
-            return format_;
-        }
+    // format
+    static std::string const& get_format()
+    {
+        return format_;
+    }
 
-        static void set_format(std::string const& format)
-        {
+    static void set_format(std::string const& format)
+    {
 #ifdef MAPNIK_THREADSAFE
-            std::lock_guard<std::mutex> lock(format_mutex_);
+        std::lock_guard<std::mutex> lock(format_mutex_);
 #endif
-            format_ = format;
-        }
+        format_ = format;
+    }
 
-        // interpolate the format string for output
-        static std::string str();
+    // interpolate the format string for output
+    static std::string str();
 
-        // output
-        static void use_file(std::string const& filepath);
-        static void use_console();
+    // output
+    static void use_file(std::string const& filepath);
+    static void use_console();
 
-    private:
-        static severity_type severity_level_;
-        static severity_map object_severity_level_;
-        static bool severity_env_check_;
-
-        static std::string format_;
-        static bool format_env_check_;
-
-        static std::ofstream file_output_;
-        static std::string file_name_;
-        static std::streambuf* saved_buf_;
+private:
+    static severity_map object_severity_level_;
+    static std::string format_;
+    static std::ofstream file_output_;
+    static std::string file_name_;
+    static std::streambuf* saved_buf_;
 
 #ifdef MAPNIK_THREADSAFE
-        static std::mutex severity_mutex_;
-        static std::mutex format_mutex_;
+    static std::atomic<severity_type> severity_level_;
+    static std::atomic<bool> severity_env_check_;
+    static std::atomic<bool> format_env_check_;
+    static std::mutex severity_mutex_;
+    static std::mutex format_mutex_;
+#else
+    static severity_type severity_level_;
+    static bool severity_env_check_;
+    static bool format_env_check_;
 #endif
-    };
+};
 
 
-    namespace detail {
+namespace detail {
 
-        /*
-          Default sink, it regulates access to clog
-        */
-        template<class Ch, class Tr, class A>
-        class clog_sink
-        {
-        public:
-            using stream_buffer = std::basic_ostringstream<Ch, Tr, A>;
+// Default sink, it regulates access to clog
 
-            void operator()(logger::severity_type const& /*severity*/, stream_buffer const& s)
-            {
+template<class Ch, class Tr, class A>
+class clog_sink
+{
+public:
+    using stream_buffer = std::basic_ostringstream<Ch, Tr, A>;
+
+    void operator()(logger::severity_type const& /*severity*/, stream_buffer const& s)
+    {
 #ifdef MAPNIK_THREADSAFE
-                static std::mutex mutex;
-                std::lock_guard<std::mutex> lock(mutex);
+        static std::mutex mutex;
+        std::lock_guard<std::mutex> lock(mutex);
 #endif
-                std::clog << logger::str() << " " << s.str() << std::endl;
-            }
-        };
-
-
-        /*
-          Base log class, should not log anything when no MAPNIK_LOG is defined
-
-          This is used for debug/warn reporting that should not output
-          anything when not compiling for speed.
-        */
-        template<template <class Ch, class Tr, class A> class OutputPolicy,
-                 logger::severity_type Severity,
-                 class Ch = char,
-                 class Tr = std::char_traits<Ch>,
-                 class A = std::allocator<Ch> >
-        class base_log : public util::noncopyable
-        {
-        public:
-            using output_policy = OutputPolicy<Ch, Tr, A>;
-
-            base_log() {}
+        std::clog << logger::str() << " " << s.str() << std::endl;
+    }
+};
+
+// Base log class, should not log anything when no MAPNIK_LOG is defined
+//
+// This is used for debug/warn reporting that should not output
+// anything when not compiling for speed.
+
+template<template <class Ch, class Tr, class A> class OutputPolicy,
+         logger::severity_type Severity,
+         class Ch = char,
+         class Tr = std::char_traits<Ch>,
+         class A = std::allocator<Ch> >
+class base_log : public util::noncopyable
+{
+public:
+    using output_policy = OutputPolicy<Ch, Tr, A>;
+
+    base_log() {}
 
 #ifdef MAPNIK_LOG
-            base_log(const char* object_name)
-            {
-                if (object_name != nullptr)
-                {
-                    object_name_ = object_name;
-                }
-            }
+    base_log(const char* object_name)
+    {
+        if (object_name != nullptr)
+        {
+            object_name_ = object_name;
+        }
+    }
 #else
-            base_log(const char* /*object_name*/)
-            {
-            }
+    base_log(const char* /*object_name*/)
+    {
+    }
 #endif
 
-            ~base_log()
-            {
+    ~base_log()
+    {
 #ifdef MAPNIK_LOG
-                if (check_severity())
-                {
-                    output_policy()(Severity, streambuf_);
-                }
+        if (check_severity())
+        {
+            output_policy()(Severity, streambuf_);
+        }
 #endif
-            }
+    }
 
-            template<class T>
+    template<class T>
 #ifdef MAPNIK_LOG
-            base_log &operator<<(T const& x)
-            {
+    base_log &operator<<(T const& x)
+    {
 
-                streambuf_ << x;
-                return *this;
-            }
+        streambuf_ << x;
+        return *this;
+    }
 #else
-            base_log &operator<<(T const& /*x*/)
-            {
+    base_log &operator<<(T const& /*x*/)
+    {
 
-                return *this;
-            }
+        return *this;
+    }
 #endif
 
-        private:
+private:
 #ifdef MAPNIK_LOG
-            inline bool check_severity()
-            {
-                return Severity >= logger::get_object_severity(object_name_);
-            }
+    inline bool check_severity()
+    {
+        return Severity >= logger::get_object_severity(object_name_);
+    }
 
-            typename output_policy::stream_buffer streambuf_;
-            std::string object_name_;
+    typename output_policy::stream_buffer streambuf_;
+    std::string object_name_;
 #endif
-        };
+};
+
+
+
+//Base log class that always log, regardless of MAPNIK_LOG.
+//This is used for error reporting that should always log something
 
+template<template <class Ch, class Tr, class A> class OutputPolicy,
+         logger::severity_type Severity,
+         class Ch = char,
+         class Tr = std::char_traits<Ch>,
+         class A = std::allocator<Ch> >
+class base_log_always : public util::noncopyable
+{
+public:
+    using output_policy = OutputPolicy<Ch, Tr, A>;
 
-        /*
-          Base log class that always log, regardless of MAPNIK_LOG.
+    base_log_always() {}
 
-          This is used for error reporting that should always log something
-        */
-        template<template <class Ch, class Tr, class A> class OutputPolicy,
-                 logger::severity_type Severity,
-                 class Ch = char,
-                 class Tr = std::char_traits<Ch>,
-                 class A = std::allocator<Ch> >
-        class base_log_always : public util::noncopyable
+    base_log_always(const char* object_name)
+    {
+        if (object_name != nullptr)
         {
-        public:
-            using output_policy = OutputPolicy<Ch, Tr, A>;
-
-            base_log_always() {}
-
-            base_log_always(const char* object_name)
-            {
-                if (object_name != nullptr)
-                {
-                    object_name_ = object_name;
-                }
-            }
-
-            ~base_log_always()
-            {
-                if (check_severity())
-                {
-                    output_policy()(Severity, streambuf_);
-                }
-            }
-
-            template<class T>
-            base_log_always &operator<<(T const& x)
-            {
-                streambuf_ << x;
-                return *this;
-            }
-
-        private:
-            inline bool check_severity()
-            {
-                return Severity >= logger::get_object_severity(object_name_);
-            }
-
-            typename output_policy::stream_buffer streambuf_;
-            std::string object_name_;
-        };
-
-
-        using base_log_debug = base_log<clog_sink, logger::debug>;
-        using base_log_warn = base_log<clog_sink, logger::warn>;
-        using base_log_error = base_log_always<clog_sink, logger::error>;
-
-    } // namespace detail
-
-
-    // real interfaces
-    class MAPNIK_DECL warn : public detail::base_log_warn {
-    public:
-        warn() : detail::base_log_warn() {}
-        warn(const char* object_name) : detail::base_log_warn(object_name) {}
-    };
+            object_name_ = object_name;
+        }
+    }
 
-    class MAPNIK_DECL debug : public detail::base_log_debug {
-    public:
-        debug() : detail::base_log_debug() {}
-        debug(const char* object_name) : detail::base_log_debug(object_name) {}
-    };
+    ~base_log_always()
+    {
+        if (check_severity())
+        {
+            output_policy()(Severity, streambuf_);
+        }
+    }
 
-    class MAPNIK_DECL error : public detail::base_log_error {
-    public:
-        error() : detail::base_log_error() {}
-        error(const char* object_name) : detail::base_log_error(object_name) {}
-    };
+    template<class T>
+    base_log_always &operator<<(T const& x)
+    {
+        streambuf_ << x;
+        return *this;
+    }
 
-    // logging helpers
-    #define MAPNIK_LOG_DEBUG(s) mapnik::debug(#s)
-    #define MAPNIK_LOG_WARN(s) mapnik::warn(#s)
-    #define MAPNIK_LOG_ERROR(s) mapnik::error(#s)
+private:
+    inline bool check_severity()
+    {
+        return Severity >= logger::get_object_severity(object_name_);
+    }
+
+    typename output_policy::stream_buffer streambuf_;
+    std::string object_name_;
+};
+
+
+using base_log_debug = base_log<clog_sink, logger::debug>;
+using base_log_warn = base_log<clog_sink, logger::warn>;
+using base_log_error = base_log_always<clog_sink, logger::error>;
+
+} // namespace detail
+
+
+// real interfaces
+class MAPNIK_DECL warn : public detail::base_log_warn
+{
+public:
+    warn() : detail::base_log_warn() {}
+    warn(const char* object_name) : detail::base_log_warn(object_name) {}
+};
+
+class MAPNIK_DECL debug : public detail::base_log_debug
+{
+public:
+    debug() : detail::base_log_debug() {}
+    debug(const char* object_name) : detail::base_log_debug(object_name) {}
+};
+
+class MAPNIK_DECL error : public detail::base_log_error
+{
+public:
+    error() : detail::base_log_error() {}
+    error(const char* object_name) : detail::base_log_error(object_name) {}
+};
+
+// logging helpers
+#define MAPNIK_LOG_DEBUG(s) mapnik::debug(#s)
+#define MAPNIK_LOG_WARN(s) mapnik::warn(#s)
+#define MAPNIK_LOG_ERROR(s) mapnik::error(#s)
 }
 
 #endif // MAPNIK_DEBUG_HPP
diff --git a/include/mapnik/image.hpp b/include/mapnik/image.hpp
index ec8b1f8..9ebdfc3 100644
--- a/include/mapnik/image.hpp
+++ b/include/mapnik/image.hpp
@@ -34,24 +34,20 @@ namespace detail {
 struct MAPNIK_DECL buffer
 {
     explicit buffer(std::size_t size);
+    explicit buffer(unsigned char* data, std::size_t size);
     buffer(buffer && rhs) noexcept;
     buffer(buffer const& rhs);
     ~buffer();
-
     buffer& operator=(buffer rhs);
-    inline bool operator!() const
-    {
-        return (data_ == nullptr)? true : false;
-    }
-
-    void swap(buffer & rhs);
-    unsigned char* data();
-    unsigned char const* data() const;
-    std::size_t size() const;
+    inline bool operator!() const {return (data_ == nullptr)? true : false;}
+    inline unsigned char* data() {return data_;}
+    inline unsigned char const* data() const {return data_;}
+    inline std::size_t size() const {return size_;}
 private:
+    void swap(buffer & rhs);
     std::size_t size_;
     unsigned char* data_;
-
+    bool owns_;
 };
 
 template <std::size_t max_size>
@@ -76,6 +72,8 @@ class image
 public:
     using pixel = T;
     using pixel_type = typename T::type;
+    using iterator = pixel_type*;
+    using const_iterator = pixel_type const*;
     static constexpr image_dtype dtype = T::id;
     static constexpr std::size_t pixel_size = sizeof(pixel_type);
 private:
@@ -93,6 +91,11 @@ public:
           bool initialize = true,
           bool premultiplied = false,
           bool painted = false);
+    image(int width,
+          int height,
+          unsigned char* data,
+          bool premultiplied = false,
+          bool painted = false);
     image(image<T> const& rhs);
     image(image<T> && rhs) noexcept;
     image<T>& operator=(image<T> rhs);
@@ -109,6 +112,12 @@ public:
     void set(pixel_type const& t);
     pixel_type const* data() const;
     pixel_type* data();
+    // simple iterator inteface
+    const_iterator begin() const;
+    const_iterator end() const;
+    iterator begin();
+    iterator end();
+    //
     unsigned char const* bytes() const;
     unsigned char* bytes();
     pixel_type const* get_row(std::size_t row) const;
diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp
index d6ed0cd..3b188a3 100644
--- a/include/mapnik/image_filter.hpp
+++ b/include/mapnik/image_filter.hpp
@@ -505,6 +505,7 @@ void apply_filter(Src & src, colorize_alpha const& op)
                 uint8_t & a = get_color(src_it[x], alpha_t());
                 if ( a > 0)
                 {
+                    a = (c.alpha() * a + 255) >> 8;
                     r = (c.red() * a + 255) >> 8;
                     g = (c.green() * a + 255) >> 8;
                     b = (c.blue() * a + 255) >> 8;
@@ -528,10 +529,10 @@ void apply_filter(Src & src, colorize_alpha const& op)
             {
                 stop_offset = offset;
             }
-            grad_lut.add_color(stop_offset, agg::rgba(c.red()/256.0,
-                                                      c.green()/256.0,
-                                                      c.blue()/256.0,
-                                                      c.alpha()/256.0));
+            grad_lut.add_color(stop_offset, agg::rgba(c.red()/255.0,
+                                                      c.green()/255.0,
+                                                      c.blue()/255.0,
+                                                      c.alpha()/255.0));
             offset += step;
         }
         if (grad_lut.build_lut())
@@ -549,12 +550,10 @@ void apply_filter(Src & src, colorize_alpha const& op)
                     if ( a > 0)
                     {
                         agg::rgba8 c = grad_lut[a];
+                        a = (c.a * a + 255) >> 8;
                         r = (c.r * a + 255) >> 8;
                         g = (c.g * a + 255) >> 8;
                         b = (c.b * a + 255) >> 8;
-                        if (r>a) r=a;
-                        if (g>a) g=a;
-                        if (b>a) b=a;
         #if 0
                         // rainbow
                         r = 0;
diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp
index 67e03da..7e04df8 100644
--- a/include/mapnik/image_filter_types.hpp
+++ b/include/mapnik/image_filter_types.hpp
@@ -116,19 +116,8 @@ struct scale_hsla : image_filter_base
       l0(_l0),
       l1(_l1),
       a0(_a0),
-      a1(_a1) {
-          if (h0 < 0 || h0 > 1 ||
-              h1 < 0 || h1 > 1 ||
-              s0 < 0 || s0 > 1 ||
-              s1 < 0 || s1 > 1 ||
-              l0 < 0 || l0 > 1 ||
-              l1 < 0 || l1 > 1 ||
-              a0 < 0 || a0 > 1 ||
-              a1 < 0 || a1 > 1)
-          {
-              throw std::runtime_error("scale-hsla values must be between 0 and 1");
-          }
-      }
+      a1(_a1) { }
+
     inline bool is_identity() const {
         return (h0 == 0 &&
                 h1 == 1 &&
diff --git a/include/mapnik/image_impl.hpp b/include/mapnik/image_impl.hpp
index 5a84f9e..732e7eb 100644
--- a/include/mapnik/image_impl.hpp
+++ b/include/mapnik/image_impl.hpp
@@ -78,6 +78,16 @@ image<T>::image()
 {}
 
 template <typename T>
+image<T>::image(int width, int height, unsigned char* data, bool premultiplied, bool painted)
+    : dimensions_(width, height),
+      buffer_(data, width * height * sizeof(pixel_size)),
+      pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
+      offset_(0.0),
+      scaling_(1.0),
+      premultiplied_alpha_(premultiplied),
+      painted_(painted) {}
+
+template <typename T>
 image<T>::image(int width, int height, bool initialize, bool premultiplied, bool painted)
     : dimensions_(width, height),
       buffer_(dimensions_.width() * dimensions_.height() * pixel_size),
@@ -101,18 +111,17 @@ image<T>::image(image<T> const& rhs)
       offset_(rhs.offset_),
       scaling_(rhs.scaling_),
       premultiplied_alpha_(rhs.premultiplied_alpha_),
-      painted_(rhs.painted_)
-{}
+      painted_(rhs.painted_) {}
 
 template <typename T>
 image<T>::image(image<T> && rhs) noexcept
     : dimensions_(std::move(rhs.dimensions_)),
-    buffer_(std::move(rhs.buffer_)),
-    pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
-    offset_(rhs.offset_),
-    scaling_(rhs.scaling_),
-    premultiplied_alpha_(rhs.premultiplied_alpha_),
-    painted_(rhs.painted_)
+      buffer_(std::move(rhs.buffer_)),
+      pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
+      offset_(rhs.offset_),
+      scaling_(rhs.scaling_),
+      premultiplied_alpha_(rhs.premultiplied_alpha_),
+      painted_(rhs.painted_)
 {
     rhs.dimensions_ = { 0, 0 };
     rhs.pData_ = nullptr;
@@ -216,6 +225,20 @@ inline unsigned char* image<T>::bytes()
     return buffer_.data();
 }
 
+// iterator interface
+template <typename T>
+inline typename image<T>::iterator image<T>::begin() { return pData_; }
+
+template <typename T>
+inline typename image<T>::iterator image<T>::end() { return pData_ + dimensions_.width() * dimensions_.height(); }
+
+template <typename T>
+inline typename image<T>::const_iterator image<T>::begin() const { return pData_; }
+
+template <typename T>
+inline typename image<T>::const_iterator image<T>::end() const{ return pData_ + dimensions_.width() * dimensions_.height(); }
+
+
 template <typename T>
 inline typename image<T>::pixel_type const* image<T>::get_row(std::size_t row) const
 {
diff --git a/include/mapnik/json/topojson_grammar_impl.hpp b/include/mapnik/json/topojson_grammar_impl.hpp
index f20fbf9..90e3f1a 100644
--- a/include/mapnik/json/topojson_grammar_impl.hpp
+++ b/include/mapnik/json/topojson_grammar_impl.hpp
@@ -73,7 +73,7 @@ topojson_grammar<Iterator, ErrorHandler>::topojson_grammar()
 
     // topo json
     topology = lit('{') >> lit("\"type\"") >> lit(':') >> lit("\"Topology\"")
-                        >> ( (lit(',') >> objects) ^ ( lit(',') >> arcs) ^ (lit(',') >> transform) ^ (lit(',') >> bbox))
+                        >> ( (lit(',') >> objects ) ^ ( lit(',') >> arcs) ^ (lit(',') >> transform) ^ (lit(',') >> bbox))
                         >> lit('}')
         ;
 
diff --git a/include/mapnik/json/topojson_utils.hpp b/include/mapnik/json/topojson_utils.hpp
index 5558bde..be6a83a 100644
--- a/include/mapnik/json/topojson_utils.hpp
+++ b/include/mapnik/json/topojson_utils.hpp
@@ -238,12 +238,6 @@ struct bounding_box_visitor
         }
         return bbox;
     }
-
-    box2d<double> operator() (mapnik::topojson::invalid const&) const
-    {
-        return box2d<double>();
-    }
-
 private:
     topology const& topo_;
     std::size_t num_arcs_;
diff --git a/include/mapnik/json/topology.hpp b/include/mapnik/json/topology.hpp
index 3cfc2d3..48453df 100644
--- a/include/mapnik/json/topology.hpp
+++ b/include/mapnik/json/topology.hpp
@@ -86,10 +86,7 @@ struct multi_polygon
     boost::optional<properties> props;
 };
 
-struct invalid {};
-
-using geometry =  util::variant<invalid,
-                                point,
+using geometry =  util::variant<point,
                                 linestring,
                                 polygon,
                                 multi_point,
diff --git a/include/mapnik/renderer_common/process_markers_symbolizer.hpp b/include/mapnik/renderer_common/process_markers_symbolizer.hpp
index 16e18ec..f67715b 100644
--- a/include/mapnik/renderer_common/process_markers_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_markers_symbolizer.hpp
@@ -115,7 +115,7 @@ struct render_marker_symbolizer_visitor
                                             feature_,
                                             common_.vars_,
                                             common_.scale_factor_);
-            if (clip) // optional clip (default: true)
+            if (clip)
             {
                 geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
                 if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
@@ -161,7 +161,7 @@ struct render_marker_symbolizer_visitor
                                             feature_,
                                             common_.vars_,
                                             common_.scale_factor_);
-            if (clip) // optional clip (default: true)
+            if (clip)
             {
                 geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
                 if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
@@ -220,7 +220,7 @@ struct render_marker_symbolizer_visitor
                                         common_.vars_,
                                         common_.scale_factor_);
 
-        if (clip) // optional clip (default: true)
+        if (clip)
         {
             geometry::geometry_types type = geometry::geometry_type(feature_.get_geometry());
             if (type == geometry::geometry_types::Polygon || type == geometry::geometry_types::MultiPolygon)
diff --git a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
index 99f1243..6fd2524 100644
--- a/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
+++ b/include/mapnik/renderer_common/process_polygon_symbolizer.hpp
@@ -54,7 +54,7 @@ void render_polygon_symbolizer(polygon_symbolizer const &sym,
     vertex_converter_type converter(clip_box, sym, common.t_, prj_trans, tr,
                                     feature,common.vars_,common.scale_factor_);
 
-    if (prj_trans.equal() && clip) converter.template set<clip_poly_tag>(); //optional clip (default: true)
+    if (prj_trans.equal() && clip) converter.template set<clip_poly_tag>();
     converter.template set<transform_tag>(); //always transform
     converter.template set<affine_transform_tag>();
     if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp
index 8bb63a7..f35a5d5 100644
--- a/include/mapnik/text/placement_finder.hpp
+++ b/include/mapnik/text/placement_finder.hpp
@@ -91,7 +91,7 @@ private:
     face_manager_freetype &font_manager_;
 
     placements_list placements_;
-
+    std::vector<text_layout_ptr> processed_layouts_;
     //ShieldSymbolizer
     bool has_marker_;
     marker_info_ptr marker_;
diff --git a/include/mapnik/util/singleton.hpp b/include/mapnik/util/singleton.hpp
index e77b25b..94f8bf1 100644
--- a/include/mapnik/util/singleton.hpp
+++ b/include/mapnik/util/singleton.hpp
@@ -80,7 +80,7 @@ template <typename T,
 #endif
         friend class CreatePolicy<T>;
         static std::atomic<T*> pInstance_;
-        static bool destroyed_;
+        static std::atomic<bool> destroyed_;
         singleton(const singleton &rhs);
         singleton& operator=(const singleton&);
 
@@ -135,7 +135,7 @@ template <typename T,
     template <typename T,
               template <typename U> class CreatePolicy> std::atomic<T*> singleton<T,CreatePolicy>::pInstance_;
     template <typename T,
-              template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_ = false;
+              template <typename U> class CreatePolicy> std::atomic<bool> singleton<T,CreatePolicy>::destroyed_(false);
 }
 
 #endif // MAPNIK_UTIL_SINGLETON_HPP
diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp
index 642932b..161b708 100644
--- a/include/mapnik/version.hpp
+++ b/include/mapnik/version.hpp
@@ -27,9 +27,8 @@
 
 #define MAPNIK_MAJOR_VERSION 3
 #define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 4
+#define MAPNIK_PATCH_VERSION 5
 
-// translates to 300003
 #define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
 
 #ifndef MAPNIK_STRINGIFY
diff --git a/plugins/input/csv/build.py b/plugins/input/csv/build.py
index c2beb24..2694109 100644
--- a/plugins/input/csv/build.py
+++ b/plugins/input/csv/build.py
@@ -21,48 +21,57 @@
 
 Import ('env')
 
-Import ('plugin_base')
+can_build = False
 
-PLUGIN_NAME = 'csv'
+if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
+    boost_version_from_header = int(env['BOOST_LIB_VERSION_FROM_HEADER'].split('_')[1])
+    if boost_version_from_header >= 56:
+        can_build = True
 
-plugin_env = plugin_base.Clone()
+if not can_build:
+    print 'WARNING: skipping building the optional topojson datasource plugin which requires boost >= 1.56'
+else:
+    Import ('plugin_base')
 
-plugin_sources = Split(
-  """
-  %(PLUGIN_NAME)s_datasource.cpp
-  %(PLUGIN_NAME)s_featureset.cpp
-  %(PLUGIN_NAME)s_inline_featureset.cpp
-  """ % locals()
-)
+    PLUGIN_NAME = 'csv'
 
-# Link Library to Dependencies
-libraries = []
-libraries.append('boost_system%s' % env['BOOST_APPEND'])
-libraries.append(env['ICU_LIB_NAME'])
-libraries.append('mapnik-json')
-libraries.append('mapnik-wkt')
+    plugin_env = plugin_base.Clone()
 
-if env['PLUGIN_LINKING'] == 'shared':
-    libraries.append(env['MAPNIK_NAME'])
+    plugin_sources = Split(
+        """
+        %(PLUGIN_NAME)s_datasource.cpp
+        %(PLUGIN_NAME)s_featureset.cpp
+        %(PLUGIN_NAME)s_inline_featureset.cpp
+        """ % locals()
+    )
 
-    TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
-                                      SHLIBPREFIX='',
-                                      SHLIBSUFFIX='.input',
-                                      source=plugin_sources,
-                                      LIBS=libraries)
+    # Link Library to Dependencies
+    libraries = []
+    libraries.append('boost_system%s' % env['BOOST_APPEND'])
+    libraries.append(env['ICU_LIB_NAME'])
+    libraries.append('mapnik-json')
+    libraries.append('mapnik-wkt')
 
-    # if the plugin links to libmapnik ensure it is built first
-    Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
-    Depends(TARGET, env.subst('../../../src/json/libmapnik-json${LIBSUFFIX}'))
-    Depends(TARGET, env.subst('../../../src/wkt/libmapnik-wkt${LIBSUFFIX}'))
+    if env['PLUGIN_LINKING'] == 'shared':
+        libraries.append(env['MAPNIK_NAME'])
 
-    if 'uninstall' not in COMMAND_LINE_TARGETS:
-        env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
-        env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
+        TARGET = plugin_env.SharedLibrary('../%s' % PLUGIN_NAME,
+                                          SHLIBPREFIX='',
+                                          SHLIBSUFFIX='.input',
+                                          source=plugin_sources,
+                                          LIBS=libraries)
 
-plugin_obj = {
-  'LIBS': libraries,
-  'SOURCES': plugin_sources,
-}
+        # if the plugin links to libmapnik ensure it is built first
+        Depends(TARGET, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME']))
+        Depends(TARGET, env.subst('../../../src/json/libmapnik-json${LIBSUFFIX}'))
+        Depends(TARGET, env.subst('../../../src/wkt/libmapnik-wkt${LIBSUFFIX}'))
 
-Return('plugin_obj')
+        if 'uninstall' not in COMMAND_LINE_TARGETS:
+            env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], TARGET)
+            env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST'])
+
+    plugin_obj = {
+        'LIBS': libraries,
+        'SOURCES': plugin_sources,
+    }
+    Return('plugin_obj')
diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp
index a727524..8b15fc9 100644
--- a/plugins/input/csv/csv_datasource.cpp
+++ b/plugins/input/csv/csv_datasource.cpp
@@ -37,6 +37,13 @@
 #include <mapnik/util/trim.hpp>
 #include <mapnik/util/geometry_to_ds_type.hpp>
 #include <mapnik/value_types.hpp>
+
+#ifdef CSV_MEMORY_MAPPED_FILE
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/streams/bufferstream.hpp>
+#include <mapnik/mapped_memory_cache.hpp>
+#endif
+
 // stl
 #include <sstream>
 #include <fstream>
@@ -102,17 +109,36 @@ csv_datasource::csv_datasource(parameters const& params)
     }
     else
     {
-#if defined (_WINDOWS)
+#if defined (CSV_MEMORY_MAPPED_FILE)
+        using file_source_type = boost::interprocess::ibufferstream;
+        file_source_type in;
+        mapnik::mapped_region_ptr mapped_region;
+        boost::optional<mapnik::mapped_region_ptr> memory =
+            mapnik::mapped_memory_cache::instance().find(filename_, true);
+        if (memory)
+        {
+            mapped_region = *memory;
+            in.buffer(static_cast<char*>(mapped_region->get_address()),mapped_region->get_size());
+        }
+        else
+        {
+            throw std::runtime_error("could not create file mapping for " + filename_);
+        }
+#elif defined (_WINDOWS)
         std::ifstream in(mapnik::utf8_to_utf16(filename_),std::ios_base::in | std::ios_base::binary);
+        if (!in.is_open())
+        {
+            throw mapnik::datasource_exception("CSV Plugin: could not open: '" + filename_ + "'");
+        }
 #else
         std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
-#endif
         if (!in.is_open())
         {
             throw mapnik::datasource_exception("CSV Plugin: could not open: '" + filename_ + "'");
         }
+#endif
         parse_csv(in, escape_, separator_, quote_);
-        in.close();
+        //in.close(); no need to call close, rely on dtor
     }
 }
 
@@ -135,7 +161,6 @@ void csv_datasource::parse_csv(T & stream,
     // get first line
     std::string csv_line;
     std::getline(stream,csv_line,stream.widen(newline));
-
     // if user has not passed a separator manually
     // then attempt to detect by reading first line
 
@@ -236,22 +261,22 @@ void csv_datasource::parse_csv(T & stream,
                   [ & ](std::string const& header){ ctx_->push(header); });
 
     mapnik::transcoder tr(desc_.get_encoding());
+    auto pos = stream.tellg();
 
     // handle rare case of a single line of data and user-provided headers
     // where a lack of a newline will mean that std::getline returns false
     bool is_first_row = false;
     if (!has_newline)
     {
-        stream >> csv_line;
+        stream.setstate(std::ios::failbit);
+        pos = 0;
         if (!csv_line.empty())
         {
             is_first_row = true;
         }
     }
-
     std::vector<item_type> boxes;
-    auto pos = stream.tellg();
-    while (std::getline(stream, csv_line, stream.widen(newline)) || is_first_row)
+    while (is_first_row || std::getline(stream, csv_line, stream.widen(newline)))
     {
         if ((row_limit_ > 0) && (line_number++ > row_limit_))
         {
@@ -463,42 +488,23 @@ mapnik::layer_descriptor csv_datasource::get_descriptor() const
     return desc_;
 }
 
-boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type() const
+template <typename T>
+boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type_impl(T & stream) const
 {
     boost::optional<mapnik::datasource_geometry_t> result;
     int multi_type = 0;
     auto itr = tree_->qbegin(boost::geometry::index::intersects(extent_));
     auto end = tree_->qend();
-    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
     for (std::size_t count = 0; itr !=end &&  count < 5; ++itr, ++count)
     {
         csv_datasource::item_type const& item = *itr;
         std::size_t file_offset = item.second.first;
         std::size_t size = item.second.second;
-
-        std::string str;
-        if (inline_string_.empty())
-        {
-#if defined (_WINDOWS)
-            std::ifstream in(mapnik::utf8_to_utf16(filename_),std::ios_base::in | std::ios_base::binary);
-#else
-            std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
-#endif
-            if (!in.is_open())
-            {
-                throw mapnik::datasource_exception("CSV Plugin: could not open: '" + filename_ + "'");
-            }
-            in.seekg(file_offset);
-            std::vector<char> record;
-            record.resize(size);
-            in.read(record.data(), size);
-            str = std::string(record.begin(), record.end());
-        }
-        else
-        {
-            str = inline_string_.substr(file_offset, size);
-        }
-
+        stream.seekg(file_offset);
+        std::vector<char> record;
+        record.resize(size);
+        stream.read(record.data(), size);
+        std::string str(record.begin(), record.end());
         try
         {
             auto values = csv_utils::parse_line(str, separator_);
@@ -524,6 +530,28 @@ boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type
     return result;
 }
 
+boost::optional<mapnik::datasource_geometry_t> csv_datasource::get_geometry_type() const
+{
+    if (inline_string_.empty())
+    {
+#if defined (_WINDOWS)
+        std::ifstream in(mapnik::utf8_to_utf16(filename_),std::ios_base::in | std::ios_base::binary);
+#else
+        std::ifstream in(filename_.c_str(),std::ios_base::in | std::ios_base::binary);
+#endif
+        if (!in.is_open())
+        {
+            throw mapnik::datasource_exception("CSV Plugin: could not open: '" + filename_ + "'");
+        }
+        return get_geometry_type_impl(in);
+    }
+    else
+    {
+        std::stringstream in(inline_string_);
+        return get_geometry_type_impl(in);
+    }
+}
+
 mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const
 {
 
@@ -550,9 +578,9 @@ mapnik::featureset_ptr csv_datasource::features(mapnik::query const& q) const
     mapnik::box2d<double> const& box = q.get_bbox();
     if (extent_.intersects(box))
     {
-        csv_featureset::array_type index_array;
         if (tree_)
         {
+            csv_featureset::array_type index_array;
             tree_->query(boost::geometry::index::intersects(box),std::back_inserter(index_array));
             std::sort(index_array.begin(),index_array.end(),
                       [] (item_type const& item0, item_type const& item1)
diff --git a/plugins/input/csv/csv_datasource.hpp b/plugins/input/csv/csv_datasource.hpp
index 0c8864b..06b5daf 100644
--- a/plugins/input/csv/csv_datasource.hpp
+++ b/plugins/input/csv/csv_datasource.hpp
@@ -45,7 +45,6 @@
 #include <boost/version.hpp>
 #include <boost/geometry/index/rtree.hpp>
 #pragma GCC diagnostic pop
-
 // stl
 #include <vector>
 #include <deque>
@@ -96,6 +95,9 @@ public:
                    std::string const& quote);
 
 private:
+    template <typename T>
+    boost::optional<mapnik::datasource_geometry_t> get_geometry_type_impl(T & stream) const;
+
     mapnik::layer_descriptor desc_;
     mapnik::box2d<double> extent_;
     std::string filename_;
diff --git a/plugins/input/csv/csv_featureset.cpp b/plugins/input/csv/csv_featureset.cpp
index 4a9e74a..acda58e 100644
--- a/plugins/input/csv/csv_featureset.cpp
+++ b/plugins/input/csv/csv_featureset.cpp
@@ -34,7 +34,9 @@
 csv_featureset::csv_featureset(std::string const& filename, detail::geometry_column_locator const& locator, std::string const& separator,
                                std::vector<std::string> const& headers, mapnik::context_ptr const& ctx, array_type && index_array)
     :
-#ifdef _WINDOWS
+#if defined(CSV_MEMORY_MAPPED_FILE)
+    //
+#elif defined( _WINDOWS)
     file_(_wfopen(mapnik::utf8_to_utf16(filename).c_str(), L"rb"), std::fclose),
 #else
     file_(std::fopen(filename.c_str(),"rb"), std::fclose),
@@ -48,7 +50,20 @@ csv_featureset::csv_featureset(std::string const& filename, detail::geometry_col
     locator_(locator),
     tr_("utf8")
 {
+#if defined (CSV_MEMORY_MAPPED_FILE)
+    boost::optional<mapnik::mapped_region_ptr> memory =
+            mapnik::mapped_memory_cache::instance().find(filename, true);
+    if (memory)
+    {
+        mapped_region_ = *memory;
+    }
+    else
+    {
+        throw std::runtime_error("could not create file mapping for " + filename);
+    }
+#else
     if (!file_) throw std::runtime_error("Can't open " + filename);
+#endif
 }
 
 csv_featureset::~csv_featureset() {}
@@ -74,12 +89,17 @@ mapnik::feature_ptr csv_featureset::next()
         csv_datasource::item_type const& item = *index_itr_++;
         std::size_t file_offset = item.second.first;
         std::size_t size = item.second.second;
+#if defined(CSV_MEMORY_MAPPED_FILE)
+        char const* start = (char const*)mapped_region_->get_address() + file_offset;
+        char const*  end = start + size;
+#else
         std::fseek(file_.get(), file_offset, SEEK_SET);
         std::vector<char> record;
         record.resize(size);
         std::fread(record.data(), size, 1, file_.get());
         auto const* start = record.data();
         auto const*  end = start + record.size();
+#endif
         return parse_feature(start, end);
     }
     return mapnik::feature_ptr();
diff --git a/plugins/input/csv/csv_featureset.hpp b/plugins/input/csv/csv_featureset.hpp
index 1fc2103..59afa1d 100644
--- a/plugins/input/csv/csv_featureset.hpp
+++ b/plugins/input/csv/csv_featureset.hpp
@@ -30,9 +30,15 @@
 #include <deque>
 #include <cstdio>
 
+#ifdef CSV_MEMORY_MAPPED_FILE
+#include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/streams/bufferstream.hpp>
+#include <mapnik/mapped_memory_cache.hpp>
+#endif
+
 class csv_featureset : public mapnik::Featureset
 {
-    using file_ptr = std::unique_ptr<std::FILE, int (*)(std::FILE *)>;
+
     using locator_type = detail::geometry_column_locator;
 public:
     using array_type = std::deque<csv_datasource::item_type>;
@@ -46,7 +52,13 @@ public:
     mapnik::feature_ptr next();
 private:
     mapnik::feature_ptr parse_feature(char const* beg, char const* end);
+#if defined (CSV_MEMORY_MAPPED_FILE)
+    using file_source_type = boost::interprocess::ibufferstream;
+    mapnik::mapped_region_ptr mapped_region_;
+#else
+    using file_ptr = std::unique_ptr<std::FILE, int (*)(std::FILE *)>;
     file_ptr file_;
+#endif
     std::string const& separator_;
     std::vector<std::string> const& headers_;
     const array_type index_array_;
diff --git a/plugins/input/csv/csv_utils.hpp b/plugins/input/csv/csv_utils.hpp
index b2981ce..b84e92d 100644
--- a/plugins/input/csv/csv_utils.hpp
+++ b/plugins/input/csv/csv_utils.hpp
@@ -44,6 +44,10 @@
 #include <cstdio>
 #include <algorithm>
 
+#ifndef _WINDOWS
+#define CSV_MEMORY_MAPPED_FILE
+#endif
+
 namespace csv_utils
 {
 
@@ -141,7 +145,9 @@ std::tuple<char,bool> autodect_newline(T & stream, std::size_t file_length)
     // autodetect newlines
     char newline = '\n';
     bool has_newline = false;
-    for (std::size_t lidx = 0; lidx < file_length && lidx < 4000; ++lidx)
+    static std::size_t const max_size = 4000;
+    std::size_t size = std::min(file_length, max_size);
+    for (std::size_t lidx = 0; lidx < size; ++lidx)
     {
         char c = static_cast<char>(stream.get());
         if (c == '\r')
diff --git a/plugins/input/topojson/topojson_datasource.cpp b/plugins/input/topojson/topojson_datasource.cpp
index 225a767..f9ba8ec 100644
--- a/plugins/input/topojson/topojson_datasource.cpp
+++ b/plugins/input/topojson/topojson_datasource.cpp
@@ -109,10 +109,6 @@ struct geometry_type_visitor
     {
         return static_cast<int>(mapnik::datasource_geometry_t::Polygon);
     }
-    int operator() (mapnik::topojson::invalid const&) const
-    {
-        return -1;
-    }
 };
 
 struct collect_attributes_visitor
@@ -121,8 +117,6 @@ struct collect_attributes_visitor
     collect_attributes_visitor(mapnik::layer_descriptor & desc):
       desc_(desc) {}
 
-    void operator() (mapnik::topojson::invalid const&) {}
-
     template <typename GeomType>
     void operator() (GeomType const& g)
     {
@@ -203,14 +197,15 @@ void topojson_datasource::parse_topojson(T const& buffer)
     values.reserve(topo_.geometries.size());
 
     std::size_t geometry_index = 0;
-
+    bool first = true;
     for (auto const& geom : topo_.geometries)
     {
         mapnik::box2d<double> box = mapnik::util::apply_visitor(mapnik::topojson::bounding_box_visitor(topo_), geom);
         if (box.valid())
         {
-            if (geometry_index == 0)
+            if (first)
             {
+                first = false;
                 extent_ = box;
                 collect_attributes_visitor assessor(desc_);
                 mapnik::util::apply_visitor( std::ref(assessor), geom);
@@ -220,8 +215,8 @@ void topojson_datasource::parse_topojson(T const& buffer)
                 extent_.expand_to_include(box);
             }
             values.emplace_back(box, geometry_index);
-            ++geometry_index;
         }
+        ++geometry_index;
     }
 
     // packing algorithm
diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp
index a6be6b1..17ec5bb 100644
--- a/src/agg/process_line_pattern_symbolizer.cpp
+++ b/src/agg/process_line_pattern_symbolizer.cpp
@@ -134,7 +134,7 @@ struct agg_renderer_process_visitor_l
 
         vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
 
-        if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
+        if (clip) converter.set<clip_line_tag>();
         converter.set<transform_tag>(); //always transform
         if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
         if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
@@ -204,7 +204,7 @@ struct agg_renderer_process_visitor_l
 
         vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
 
-        if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
+        if (clip) converter.set<clip_line_tag>();
         converter.set<transform_tag>(); //always transform
         if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
         if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp
index 386adee..fb00b2a 100644
--- a/src/agg/process_polygon_pattern_symbolizer.cpp
+++ b/src/agg/process_polygon_pattern_symbolizer.cpp
@@ -165,7 +165,7 @@ struct agg_renderer_process_visitor_p
         vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
 
 
-        if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
+        if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>();
         converter.set<transform_tag>(); //always transform
         converter.set<affine_transform_tag>(); // optional affine transform
         if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
@@ -264,7 +264,7 @@ struct agg_renderer_process_visitor_p
 
         vertex_converter_type converter(clip_box, sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
 
-        if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
+        if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>();
         converter.set<transform_tag>(); //always transform
         converter.set<affine_transform_tag>(); // optional affine transform
         if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
diff --git a/src/cairo/process_line_pattern_symbolizer.cpp b/src/cairo/process_line_pattern_symbolizer.cpp
index 4ec6357..7aa85ab 100644
--- a/src/cairo/process_line_pattern_symbolizer.cpp
+++ b/src/cairo/process_line_pattern_symbolizer.cpp
@@ -150,7 +150,7 @@ void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
 
     vertex_converter_type converter(clipping_extent,sym, common_.t_, prj_trans, tr, feature, common_.vars_, common_.scale_factor_);
 
-    if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
+    if (clip) converter.set<clip_line_tag>();
     converter.set<transform_tag>(); // always transform
     if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
     converter.set<affine_transform_tag>(); // optional affine transform
diff --git a/src/cairo/process_polygon_pattern_symbolizer.cpp b/src/cairo/process_polygon_pattern_symbolizer.cpp
index 760a425..aa7b0ca 100644
--- a/src/cairo/process_polygon_pattern_symbolizer.cpp
+++ b/src/cairo/process_polygon_pattern_symbolizer.cpp
@@ -132,7 +132,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
                                                    smooth_tag>;
 
     vertex_converter_type converter(clip_box,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
-    if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
+    if (prj_trans.equal() && clip) converter.set<clip_poly_tag>();
     converter.set<transform_tag>(); //always transform
     converter.set<affine_transform_tag>();
     if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
diff --git a/src/debug.cpp b/src/debug.cpp
index 1a90df5..f41f84c 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -27,17 +27,18 @@
 #include <ctime>
 #include <stdexcept>
 #include <fstream>
+#include <cstdlib>
 
 #ifndef MAPNIK_LOG_FORMAT
-  #define MAPNIK_LOG_FORMAT  Mapnik LOG> %Y-%m-%d %H:%M:%S:
+#define MAPNIK_LOG_FORMAT  Mapnik LOG> %Y-%m-%d %H:%M:%S:
 #endif
 
 #ifndef MAPNIK_DEFAULT_LOG_SEVERITY
-  #ifdef MAPNIK_DEBUG
-    #define MAPNIK_DEFAULT_LOG_SEVERITY 0
-  #else
-    #define MAPNIK_DEFAULT_LOG_SEVERITY 2
-  #endif
+#ifdef MAPNIK_DEBUG
+#define MAPNIK_DEFAULT_LOG_SEVERITY 0
+#else
+#define MAPNIK_DEFAULT_LOG_SEVERITY 2
+#endif
 #endif
 
 namespace mapnik {
@@ -52,25 +53,24 @@ std::mutex logger::format_mutex_;
 
 // first time checks
 
-bool logger::severity_env_check_ = true;
-bool logger::format_env_check_ = true;
-
+std::atomic<bool> logger::severity_env_check_ {true};
+std::atomic<bool> logger::format_env_check_ {true};
 
 // severity
 
-logger::severity_type logger::severity_level_ =
-    #if MAPNIK_DEFAULT_LOG_SEVERITY == 0
-        logger::debug
-    #elif MAPNIK_DEFAULT_LOG_SEVERITY == 1
-        logger::warn
-    #elif MAPNIK_DEFAULT_LOG_SEVERITY == 2
-        logger::error
-    #elif MAPNIK_DEFAULT_LOG_SEVERITY == 3
-        logger::none
-    #else
-        #error "Wrong default log severity level specified!"
-    #endif
-;
+std::atomic<logger::severity_type> logger::severity_level_ {
+#if MAPNIK_DEFAULT_LOG_SEVERITY == 0
+    logger::debug
+#elif MAPNIK_DEFAULT_LOG_SEVERITY == 1
+    logger::warn
+#elif MAPNIK_DEFAULT_LOG_SEVERITY == 2
+    logger::error
+#elif MAPNIK_DEFAULT_LOG_SEVERITY == 3
+    logger::none
+#else
+#error "Wrong default log severity level specified!"
+#endif
+};
 
 logger::severity_map logger::object_severity_level_ = logger::severity_map();
 
@@ -85,13 +85,13 @@ std::string logger::format_ = __xstr__(MAPNIK_LOG_FORMAT);
 
 std::string logger::str()
 {
-#if 0
+#ifdef MAPNIK_CHECK_ENV
     // update the format from getenv if this is the first time
     if (logger::format_env_check_)
     {
         logger::format_env_check_ = false;
 
-        const char* log_format = getenv("MAPNIK_LOG_FORMAT");
+        const char* log_format = std::getenv("MAPNIK_LOG_FORMAT");
         if (log_format != nullptr)
         {
             logger::format_ = log_format;
@@ -101,7 +101,7 @@ std::string logger::str()
 
     char buf[256];
     const time_t tm = time(0);
-    strftime(buf, sizeof(buf), logger::format_.c_str(), localtime(&tm));
+    std::strftime(buf, sizeof(buf), logger::format_.c_str(), localtime(&tm));
     return buf;
 }
 
diff --git a/src/grid/process_line_pattern_symbolizer.cpp b/src/grid/process_line_pattern_symbolizer.cpp
index d34f6e8..dc370f7 100644
--- a/src/grid/process_line_pattern_symbolizer.cpp
+++ b/src/grid/process_line_pattern_symbolizer.cpp
@@ -120,7 +120,7 @@ void grid_renderer<T>::process(line_pattern_symbolizer const& sym,
                                                    simplify_tag,smooth_tag,
                                                    offset_transform_tag,stroke_tag>;
     vertex_converter_type converter(clipping_extent,line,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
-    if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
+    if (clip) converter.set<clip_line_tag>();
     converter.set<transform_tag>(); // always transform
     if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
     converter.set<affine_transform_tag>(); // optional affine transform
diff --git a/src/grid/process_polygon_pattern_symbolizer.cpp b/src/grid/process_polygon_pattern_symbolizer.cpp
index 604c0c2..06408a8 100644
--- a/src/grid/process_polygon_pattern_symbolizer.cpp
+++ b/src/grid/process_polygon_pattern_symbolizer.cpp
@@ -79,7 +79,7 @@ void grid_renderer<T>::process(polygon_pattern_symbolizer const& sym,
     using vertex_converter_type = vertex_converter<clip_poly_tag,transform_tag,affine_transform_tag,smooth_tag>;
     vertex_converter_type converter(common_.query_extent_,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
 
-    if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
+    if (prj_trans.equal() && clip) converter.set<clip_poly_tag>();
     converter.set<transform_tag>(); //always transform
     converter.set<affine_transform_tag>();
     if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
diff --git a/src/image.cpp b/src/image.cpp
index caa0a8f..32c8433 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -36,27 +36,38 @@ namespace detail
 // BUFFER
 buffer::buffer(std::size_t size)
     : size_(size),
-      data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
+      data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr)),
+      owns_(true)
 {}
 
+buffer::buffer(unsigned char* data, std::size_t size)
+    : size_(size),
+      data_(data),
+      owns_(false)
+{}
+
+// move
 buffer::buffer(buffer && rhs) noexcept
-: size_(std::move(rhs.size_)),
-    data_(std::move(rhs.data_))
+: size_(rhs.size_),
+    data_(rhs.data_),
+    owns_(rhs.owns_)
 {
     rhs.size_ = 0;
     rhs.data_ = nullptr;
+    rhs.owns_ = false;
 }
-
+// copy
 buffer::buffer(buffer const& rhs)
     : size_(rhs.size_),
-      data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
+      data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr)),
+      owns_(true)
 {
     if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
 }
 
 buffer::~buffer()
 {
-    ::operator delete(data_);
+    if (owns_) ::operator delete(data_);
 }
 
 buffer& buffer::operator=(buffer rhs)
@@ -69,21 +80,7 @@ void buffer::swap(buffer & rhs)
 {
     std::swap(size_, rhs.size_);
     std::swap(data_, rhs.data_);
-}
-
-unsigned char* buffer::data()
-{
-    return data_;
-}
-
-unsigned char const* buffer::data() const
-{
-    return data_;
-}
-
-std::size_t buffer::size() const
-{
-    return size_;
+    std::swap(owns_, rhs.owns_);
 }
 
 template struct MAPNIK_DECL image_dimensions<65535>;
diff --git a/src/svg/svg_parser.cpp b/src/svg/svg_parser.cpp
index 06c7202..ec1f4d8 100644
--- a/src/svg/svg_parser.cpp
+++ b/src/svg/svg_parser.cpp
@@ -28,6 +28,7 @@
 #include <mapnik/safe_cast.hpp>
 #include <mapnik/svg/svg_parser_exception.hpp>
 #include <mapnik/util/file_io.hpp>
+#include <mapnik/util/utf_conv_win.hpp>
 #include "agg_ellipse.h"
 #include "agg_rounded_rect.h"
 #include "agg_span_gradient.h"
@@ -974,7 +975,11 @@ svg_parser::~svg_parser() {}
 
 bool svg_parser::parse(std::string const& filename)
 {
+#ifdef _WINDOWS
+    std::basic_ifstream<char> stream(mapnik::utf8_to_utf16(filename));
+#else
     std::basic_ifstream<char> stream(filename.c_str());
+#endif
     if (!stream)
     {
         std::stringstream ss;
diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp
index 086501e..04a2907 100644
--- a/src/text/placement_finder.cpp
+++ b/src/text/placement_finder.cpp
@@ -76,6 +76,8 @@ bool placement_finder::next_position()
                                                                info_.properties,
                                                                info_.properties.layout_defaults,
                                                                info_.properties.format_tree());
+        // ensure layouts stay in scope after layouts_.clear()
+        processed_layouts_.emplace_back(layout);
         // TODO: why is this call needed?
         // https://github.com/mapnik/mapnik/issues/2525
         text_props_ = evaluate_text_properties(info_.properties,feature_,attr_);
diff --git a/src/text/symbolizer_helpers.cpp b/src/text/symbolizer_helpers.cpp
index 860359a..1d0fe48 100644
--- a/src/text/symbolizer_helpers.cpp
+++ b/src/text/symbolizer_helpers.cpp
@@ -76,11 +76,8 @@ template <typename T>
 struct split_multi_geometries
 {
     using container_type = T;
-    split_multi_geometries(container_type & cont, view_transform const& t,
-                           proj_transform const& prj_trans)
-        : cont_(cont),
-          t_(t),
-          prj_trans_(prj_trans) { }
+    split_multi_geometries(container_type & cont)
+        : cont_(cont) { }
 
     void operator() (geometry::geometry_empty const&) const {}
     void operator() (geometry::multi_point<double> const& multi_pt) const
@@ -131,8 +128,6 @@ struct split_multi_geometries
     }
 
     container_type & cont_;
-    view_transform const& t_;
-    proj_transform const& prj_trans_;
 };
 
 } // ns detail
@@ -182,8 +177,7 @@ struct largest_bbox_first
 void base_symbolizer_helper::initialize_geometries() const
 {
     auto const& geom = feature_.get_geometry();
-    util::apply_visitor(detail::split_multi_geometries<geometry_container_type>
-                        (geometries_to_process_, t_, prj_trans_), geom);
+    util::apply_visitor(detail::split_multi_geometries<geometry_container_type>(geometries_to_process_), geom);
     if (!geometries_to_process_.empty())
     {
         auto type = geometry::geometry_type(geom);
@@ -294,7 +288,7 @@ text_symbolizer_helper::text_symbolizer_helper(
     value_double simplify_tolerance = mapnik::get<value_double, keys::simplify_tolerance>(sym_, feature_, vars_);
     value_double smooth = mapnik::get<value_double, keys::smooth>(sym_, feature_, vars_);
 
-    if (clip) converter_.template set<clip_line_tag>(); //optional clip (default: true)
+    if (clip) converter_.template set<clip_line_tag>();
     converter_.template set<transform_tag>(); //always transform
     converter_.template set<affine_transform_tag>();
     if (simplify_tolerance > 0.0) converter_.template set<simplify_tag>(); // optional simplify converter
@@ -419,7 +413,7 @@ text_symbolizer_helper::text_symbolizer_helper(
     value_double simplify_tolerance = mapnik::get<value_double, keys::simplify_tolerance>(sym_, feature_, vars_);
     value_double smooth = mapnik::get<value_double, keys::smooth>(sym_, feature_, vars_);
 
-    if (clip) converter_.template set<clip_line_tag>(); //optional clip (default: true)
+    if (clip) converter_.template set<clip_line_tag>();
     converter_.template set<transform_tag>(); //always transform
     converter_.template set<affine_transform_tag>();
     if (simplify_tolerance > 0.0) converter_.template set<simplify_tag>(); // optional simplify converter
diff --git a/src/unicode.cpp b/src/unicode.cpp
index cf36f55..dac9b29 100644
--- a/src/unicode.cpp
+++ b/src/unicode.cpp
@@ -39,7 +39,7 @@ transcoder::transcoder (std::string const& encoding)
     conv_ = ucnv_open(encoding.c_str(),&err);
     if (!U_SUCCESS(err))
     {
-        // NOT: conv_ should be null on error so no need to call ucnv_close
+        // NOTE: conv_ should be null on error so no need to call ucnv_close
         throw std::runtime_error(std::string("could not create converter for ") + encoding);
     }
 }
diff --git a/test/standalone/csv_test.cpp b/test/standalone/csv_test.cpp
index c156929..6535e82 100644
--- a/test/standalone/csv_test.cpp
+++ b/test/standalone/csv_test.cpp
@@ -612,6 +612,7 @@ TEST_CASE("csv") {
                 require_attributes(all_features(ds)->next(), {
                         attr{"x", 0}, attr{"y", 0}, attr{"name", ustring("data_name")} });
                 REQUIRE(count_features(all_features(ds)) == r.second);
+                CHECK(ds->get_geometry_type() == mapnik::datasource_geometry_t::Point);
             }
         } // END SECTION
 
diff --git a/test/unit/imaging/image.cpp b/test/unit/imaging/image.cpp
index ee70a67..23f02c2 100644
--- a/test/unit/imaging/image.cpp
+++ b/test/unit/imaging/image.cpp
@@ -10,7 +10,7 @@
 TEST_CASE("image class") {
 
 SECTION("test gray16") {
-    
+
     const mapnik::image_gray16 im(4,4);
     mapnik::image_gray16 im2(im);
     mapnik::image_gray16 im3(5,5);
@@ -20,11 +20,11 @@ SECTION("test gray16") {
     CHECK_FALSE(im2 == im3);
     CHECK(im < im3);
     CHECK_FALSE(im < im2);
-    
+
     // Check that width is correct
     CHECK(im.width() == 4);
     CHECK(im2.width() == 4);
-    
+
     // Check that height is correct
     CHECK(im.height() == 4);
     CHECK(im2.height() == 4);
@@ -40,11 +40,11 @@ SECTION("test gray16") {
     // Check that size is correct
     CHECK(im.size() == 32);
     CHECK(im2.size() == 32);
-    
+
     // Check that row_size is correct
     CHECK(im.row_size() == 8);
     CHECK(im2.row_size() == 8);
-    
+
     // Check that get_premultiplied is correct
     CHECK_FALSE(im.get_premultiplied());
     CHECK_FALSE(im2.get_premultiplied());
@@ -52,7 +52,7 @@ SECTION("test gray16") {
     // Check that set premultiplied works
     im2.set_premultiplied(true);
     CHECK(im2.get_premultiplied());
-    
+
     // Check that painted is correct
     CHECK_FALSE(im.painted());
     CHECK_FALSE(im2.painted());
@@ -64,15 +64,15 @@ SECTION("test gray16") {
     // Check that offset is correct
     CHECK(im.get_offset() == 0.0);
     CHECK(im2.get_offset() == 0.0);
-    
+
     // Check that set offset works
     im2.set_offset(2.3);
     CHECK(im2.get_offset() == 2.3);
-    
+
     // Check that scaling is correct
     CHECK(im.get_scaling() == 1.0);
     CHECK(im2.get_scaling() == 1.0);
-    
+
     // Check that set scaling works
     im2.set_scaling(1.1);
     CHECK(im2.get_scaling() == 1.1);
@@ -140,7 +140,7 @@ SECTION("test gray16") {
     CHECK(im2(0,0) == 30);
     CHECK(im2(0,1) == 514);
     CHECK(im2(1,1) == 50);
-    
+
 } // END SECTION
 
 SECTION("image_null")
@@ -149,11 +149,11 @@ SECTION("image_null")
     const mapnik::image_null im_null2(2,2); // Actually doesn't really set any size
     mapnik::image_null im_null3(im_null2);
     mapnik::image_null im_null4(std::move(im_null3));
-    
+
     // All nulls are equal
     CHECK(im_null == im_null4);
     CHECK(im_null == im_null2);
-    
+
     // No null is greater
     CHECK_FALSE(im_null < im_null4);
     CHECK_FALSE(im_null < im_null2);
@@ -289,5 +289,85 @@ SECTION("Image Buffer")
 
 } // END SECTION
 
-} // END TEST CASE
 
+SECTION("Image copy/move")
+{
+    mapnik::detail::buffer buf(16 * 16 * 4); // large enough to hold 16*16 RGBA image
+    CHECK(buf.size() == 16 * 16 * 4);
+    // fill buffer with 0xff
+    std::fill(buf.data(), buf.data() + buf.size(), 0xff);
+
+    // move buffer
+    mapnik::detail::buffer buf2(std::move(buf));
+    CHECK (buf.size() == 0);
+    CHECK (buf.data() == nullptr);
+
+    mapnik::image_rgba8 im(16, 16, buf2.data()); // shallow copy
+    std::size_t count = 0;
+    for (auto const& pixel : im)
+    {
+        // expect rgba(255,255,255,1.0)
+        CHECK( sizeof(pixel) == sizeof(mapnik::image_rgba8::pixel_type));
+        CHECK( pixel == 0xffffffff);
+        ++count;
+    }
+    CHECK( count == im.width() * im.height());
+    CHECK( buf2.size() == im.width() * im.height() * sizeof( mapnik::image_rgba8::pixel_type));
+
+    // mutate buffer
+    // fill buffer with 0x7f - semi-transparent grey
+    std::fill(buf2.data(), buf2.data() + buf2.size(), 0x7f);
+    for (auto const& pixel : im)
+    {
+        // expect rgba(127,127,127,0.5)
+        CHECK( pixel == 0x7f7f7f7f);
+    }
+
+    // mutate image directly (buf)
+    for (auto & pixel : im)
+    {
+        pixel = mapnik::color(0,255,0).rgba(); // green
+    }
+
+    // move
+    mapnik::image_rgba8 im2(std::move(im));
+    CHECK (im.data() == nullptr);
+    CHECK (im.bytes() == nullptr);
+    CHECK (im.width() == 0);
+    CHECK (im.height() == 0);
+    for (auto const& pixel : im2)
+    {
+        // expect `green`
+        CHECK( pixel == mapnik::color(0,255,0).rgba());
+    }
+
+    // deep copy
+    mapnik::image_rgba8 im3(im2); // allocates new internal buffer
+    for (auto & pixel : im3)
+    {
+        // expect `green`
+        CHECK( pixel == mapnik::color(0,255,0).rgba());
+        // mutate
+        pixel = mapnik::color(255,0,0).rgba(); //red
+    }
+
+    // im2 (green)
+    for (auto const& pixel : im2)
+    {
+        // expect `green`
+        CHECK( pixel == mapnik::color(0,255,0).rgba());
+    }
+
+    //buf2 still holds green pixels
+    CHECK(buf2.size() == 16 * 16 * 4);
+
+    unsigned char* itr = buf2.data();
+    unsigned char* end = itr + buf2.size();
+    count = 0;
+    for ( ;itr!= end; ++itr)
+    {
+        CHECK( *itr == ((count++ % 2 == 0) ? 0 : 0xff)); // green
+    }
+}
+
+} // END TEST CASE
diff --git a/test/unit/imaging/image_filter.cpp b/test/unit/imaging/image_filter.cpp
index f07836d..0386409 100644
--- a/test/unit/imaging/image_filter.cpp
+++ b/test/unit/imaging/image_filter.cpp
@@ -119,15 +119,12 @@ SECTION("test agg stack blur") {
 
 } // END SECTION
 
-SECTION("test scale-hsla") {
+SECTION("test scale-hsla 1") {
     
     mapnik::image_rgba8 im(3,3);
     mapnik::fill(im,mapnik::color("blue"));
     mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
 
-    // Should throw because a value is greater then 1.0
-    REQUIRE_THROWS(mapnik::filter::filter_image(im, "scale-hsla(0.0,1.5,0.0,1.0,0.0,0.5,0.0,0.5)"););
-
     mapnik::filter::filter_image(im, "scale-hsla(0.0,0.5,0.0,1.0,0.0,0.5,0.0,0.5)");
 
     CHECK(im(0,0) == 0x80004000);
@@ -142,6 +139,35 @@ SECTION("test scale-hsla") {
     
 } // END SECTION
 
+SECTION("test scale-hsla 2") {
+
+    mapnik::image_rgba8 im(3,3);
+    mapnik::set_pixel(im, 0, 0, mapnik::color(255, 0, 0));
+    mapnik::set_pixel(im, 0, 1, mapnik::color(147, 112, 219));
+    mapnik::set_pixel(im, 0, 2, mapnik::color(128, 128, 128));
+    mapnik::set_pixel(im, 1, 0, mapnik::color(72, 209, 204));
+    mapnik::set_pixel(im, 1, 1, mapnik::color(218, 112, 214));
+    mapnik::set_pixel(im, 1, 2, mapnik::color(30, 144, 255));
+    mapnik::set_pixel(im, 2, 0, mapnik::color(238, 130, 238));
+    mapnik::set_pixel(im, 2, 1, mapnik::color(154, 205, 50));
+    mapnik::set_pixel(im, 2, 2, mapnik::color(160, 82, 45));
+
+    // Should not throw on values out of [0, 1]
+    // https://github.com/mapnik/mapnik/issues/3052
+    REQUIRE_NOTHROW(mapnik::filter::filter_image(im, "scale-hsla(0.0,1.5,-1.0,1.0,-1.0,2.0,1.0,1.0)"););
+
+    CHECK(im(0,0) == 0xff0000ff);
+    CHECK(im(0,1) == 0xffefeff4);
+    CHECK(im(0,2) == 0xff818181);
+    CHECK(im(1,0) == 0xffb895a5);
+    CHECK(im(1,1) == 0xffededf3);
+    CHECK(im(1,2) == 0xffd75aff);
+    CHECK(im(2,0) == 0xffffffff);
+    CHECK(im(2,1) == 0xff649b64);
+    CHECK(im(2,2) == 0xff2e343b);
+
+} // END SECTION
+
 SECTION("test emboss") {
     
     mapnik::image_rgba8 im(3,3);
@@ -310,18 +336,58 @@ SECTION("test colorize-alpha - two color") {
 
     mapnik::filter::filter_image(im, "colorize-alpha(green,blue)");
 
-    CHECK(im(0,0) == 0xfffc0000);
-    CHECK(im(0,1) == 0xfffc0000);
-    CHECK(im(0,2) == 0xfffc0000);
-    CHECK(im(1,0) == 0xfffc0000);
-    CHECK(im(1,1) == 0xfffc0000);
-    CHECK(im(1,2) == 0xfffc0000);
-    CHECK(im(2,0) == 0xfffc0000);
-    CHECK(im(2,1) == 0xfffc0000);
-    CHECK(im(2,2) == 0xfffc0000);
+    CHECK(im(0,0) == 0xfffd0000);
+    CHECK(im(0,1) == 0xfffd0000);
+    CHECK(im(0,2) == 0xfffd0000);
+    CHECK(im(1,0) == 0xfffd0000);
+    CHECK(im(1,1) == 0xfffd0000);
+    CHECK(im(1,2) == 0xfffd0000);
+    CHECK(im(2,0) == 0xfffd0000);
+    CHECK(im(2,1) == 0xfffd0000);
+    CHECK(im(2,2) == 0xfffd0000);
     
 } // END SECTION
 
+SECTION("test colorize-alpha - one color with transparency") {
+
+    mapnik::image_rgba8 im(3,3);
+    mapnik::fill(im,mapnik::color("#0000ffaa"));
+    mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa"));
+
+    mapnik::filter::filter_image(im, "colorize-alpha(#0000ff99)");
+
+    CHECK(im(0,0) == 0x66660000);
+    CHECK(im(0,1) == 0x66660000);
+    CHECK(im(0,2) == 0x66660000);
+    CHECK(im(1,0) == 0x66660000);
+    CHECK(im(1,1) == 0x66660000);
+    CHECK(im(1,2) == 0x66660000);
+    CHECK(im(2,0) == 0x66660000);
+    CHECK(im(2,1) == 0x66660000);
+    CHECK(im(2,2) == 0x66660000);
+
+} // END SECTION
+
+SECTION("test colorize-alpha - two color with transparency") {
+
+    mapnik::image_rgba8 im(3,3);
+    mapnik::fill(im,mapnik::color("#0000ffaa"));
+    mapnik::set_pixel(im, 1, 1, mapnik::color("#aaaaaaaa"));
+
+    mapnik::filter::filter_image(im, "colorize-alpha(#0000ff00,#00ff00ff)");
+
+    CHECK(im(0,0) == 0x70264a00);
+    CHECK(im(0,1) == 0x70264a00);
+    CHECK(im(0,2) == 0x70264a00);
+    CHECK(im(1,0) == 0x70264a00);
+    CHECK(im(1,1) == 0x70264a00);
+    CHECK(im(1,2) == 0x70264a00);
+    CHECK(im(2,0) == 0x70264a00);
+    CHECK(im(2,1) == 0x70264a00);
+    CHECK(im(2,2) == 0x70264a00);
+
+} // END SECTION
+
 SECTION("test color-blind-protanope") {
     
     mapnik::image_rgba8 im(2,2);
diff --git a/test/unit/imaging/image_io_test.cpp b/test/unit/imaging/image_io_test.cpp
index 6daeca8..8a51502 100644
--- a/test/unit/imaging/image_io_test.cpp
+++ b/test/unit/imaging/image_io_test.cpp
@@ -21,6 +21,11 @@ SECTION("readers") {
     boost::optional<std::string> type;
     try
     {
+        mapnik::image_rgba8 im_og;
+        auto im_size = mapnik::image_rgba8::pixel_size * im_og.width() * im_og.height();
+        mapnik::detail::buffer buf(im_og.bytes(), im_size);
+        mapnik::image_rgba8 im2(im_og.width(), im_og.height(), buf.data());
+        CHECK( im2.bytes() == im_og.bytes() );
 #if defined(HAVE_JPEG)
         should_throw = "./test/data/images/blank.jpg";
         REQUIRE( mapnik::util::exists( should_throw ) );

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik.git



More information about the Pkg-grass-devel mailing list