From 4c38bf9b81054730fc030c7ee88f1b4695e72542 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 19 Apr 2013 14:09:25 -0700 Subject: [PATCH 1/3] remove geos plugin (moved to https://github.com/mapnik/non-core-plugins) - refs #1809 --- SConstruct | 13 +- plugins/input/geos/build.py | 52 ---- plugins/input/geos/geos_datasource.cpp | 317 ------------------------ plugins/input/geos/geos_datasource.hpp | 71 ------ plugins/input/geos/geos_feature_ptr.hpp | 108 -------- plugins/input/geos/geos_featureset.cpp | 129 ---------- plugins/input/geos/geos_featureset.hpp | 66 ----- 7 files changed, 2 insertions(+), 754 deletions(-) delete mode 100644 plugins/input/geos/build.py delete mode 100644 plugins/input/geos/geos_datasource.cpp delete mode 100644 plugins/input/geos/geos_datasource.hpp delete mode 100644 plugins/input/geos/geos_feature_ptr.hpp delete mode 100644 plugins/input/geos/geos_featureset.cpp delete mode 100644 plugins/input/geos/geos_featureset.hpp diff --git a/SConstruct b/SConstruct index 1f85a2847..abc2695d3 100644 --- a/SConstruct +++ b/SConstruct @@ -58,7 +58,6 @@ pretty_dep_names = { 'ociei':'Oracle database library | configure with OCCI_LIBS & OCCI_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki//OCCI', 'gdal':'GDAL C++ library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki/GDAL', 'ogr':'OGR-enabled GDAL C++ Library | configured using gdal-config program | try setting GDAL_CONFIG SCons option | more info: https://github.com/mapnik/mapnik/wiki//OGR', - 'geos_c':'GEOS Simple Geometry Specification C Library | configured with GEOS_LIB & GEOS_INCLUDE | more info: https://github.com/mapnik/mapnik/wiki//GEOS', 'cairo':'Cairo C library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', 'pycairo':'Python bindings to Cairo library | configured using pkg-config | try setting PKG_CONFIG_PATH SCons option', 'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/', @@ -74,7 +73,6 @@ pretty_dep_names = { 'pg_config':'pg_config program | try setting PG_CONFIG SCons option', 'xml2-config':'xml2-config program | try setting XML2_CONFIG SCons option', 'gdal-config':'gdal-config program | try setting GDAL_CONFIG SCons option', - 'geos-config':'geos-config program | try setting GEOS_CONFIG SCons option', 'freetype-config':'freetype-config program | try setting FREETYPE_CONFIG SCons option', 'osm':'more info: https://github.com/mapnik/mapnik/wiki//OsmPlugin', 'curl':'libcurl is required for the "osm" plugin - more info: https://github.com/mapnik/mapnik/wiki//OsmPlugin', @@ -90,7 +88,6 @@ PLUGINS = { # plugins with external dependencies 'postgis': {'default':True,'path':None,'inc':'libpq-fe.h','lib':'pq','lang':'C'}, 'gdal': {'default':True,'path':None,'inc':'gdal_priv.h','lib':'gdal','lang':'C++'}, 'ogr': {'default':True,'path':None,'inc':'ogrsf_frmts.h','lib':'gdal','lang':'C++'}, - 'geos': {'default':False,'path':None,'inc':'geos_c.h','lib':'geos_c','lang':'C'}, # configured with custom paths, hence 'path': PREFIX/INCLUDES/LIBS 'occi': {'default':False,'path':'OCCI','inc':'occi.h','lib':'ociei','lang':'C++'}, 'sqlite': {'default':True,'path':'SQLITE','inc':'sqlite3.h','lib':'sqlite3','lang':'C'}, @@ -330,7 +327,6 @@ PathVariable.PathAccept), BoolVariable('CPP_TESTS', 'Compile the C++ tests', 'True'), # Variables for optional dependencies - ('GEOS_CONFIG', 'The path to the geos-config executable.', 'geos-config'), # Note: cairo and and pycairo are optional but configured automatically through pkg-config # Therefore, we use a single boolean for whether to attempt to build cairo support. BoolVariable('CAIRO', 'Attempt to build with Cairo rendering support', 'True'), @@ -549,7 +545,7 @@ def parse_config(context, config, checks='--libs --cflags'): env = context.env tool = config.lower().replace('_','-') toolname = tool - if config in ('GDAL_CONFIG','GEOS_CONFIG'): + if config in ('GDAL_CONFIG'): toolname += ' %s' % checks context.Message( 'Checking for %s... ' % toolname) cmd = '%s %s' % (env[config],checks) @@ -578,7 +574,7 @@ def parse_config(context, config, checks='--libs --cflags'): ret = False print ' (xml2-config not found!)' if not parsed: - if config in ('GDAL_CONFIG','GEOS_CONFIG'): + if config in ('GDAL_CONFIG'): # optional deps... env['SKIPPED_DEPS'].append(tool) conf.rollback_option(config) @@ -1284,11 +1280,6 @@ if not preconfigured: libname = conf.get_pkg_lib('GDAL_CONFIG','ogr') if libname: details['lib'] = libname - elif plugin == 'geos': - if conf.parse_config('GEOS_CONFIG',checks='--ldflags --cflags'): - lgeos_c = env['PLUGINS']['geos']['lib'] - env.Append(LIBS = lgeos_c) - elif details['path'] and details['lib'] and details['inc']: backup = env.Clone().Dictionary() # Note, the 'delete_existing' keyword makes sure that these paths are prepended diff --git a/plugins/input/geos/build.py b/plugins/input/geos/build.py deleted file mode 100644 index e75c7822e..000000000 --- a/plugins/input/geos/build.py +++ /dev/null @@ -1,52 +0,0 @@ -# -# This file is part of Mapnik (c++ mapping toolkit) -# -# Copyright (C) 2007 Artem Pavlenko, Jean-Francois Doyon -# -# Mapnik is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -# -# - - -Import ('plugin_base') -Import ('env') - -prefix = env['PREFIX'] - -plugin_env = plugin_base.Clone() - -geos_src = Split( - """ - geos_datasource.cpp - geos_featureset.cpp - """ - ) - -libraries = [env['PLUGINS']['geos']['lib']] - -# Link Library to Dependencies -libraries.append('mapnik') -libraries.append(env['ICU_LIB_NAME']) -libraries.append('boost_system%s' % env['BOOST_APPEND']) -libraries.append('boost_filesystem%s' % env['BOOST_APPEND']) - -input_plugin = plugin_env.SharedLibrary('../geos', source=geos_src, SHLIBPREFIX='', SHLIBSUFFIX='.input', LIBS=libraries, LINKFLAGS=env['CUSTOM_LDFLAGS']) - -# if the plugin links to libmapnik ensure it is built first -Depends(input_plugin, env.subst('../../../src/%s' % env['MAPNIK_LIB_NAME'])) - -if 'uninstall' not in COMMAND_LINE_TARGETS: - env.Install(env['MAPNIK_INPUT_PLUGINS_DEST'], input_plugin) - env.Alias('install', env['MAPNIK_INPUT_PLUGINS_DEST']) diff --git a/plugins/input/geos/geos_datasource.cpp b/plugins/input/geos/geos_datasource.cpp deleted file mode 100644 index ef38c79cd..000000000 --- a/plugins/input/geos/geos_datasource.cpp +++ /dev/null @@ -1,317 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#include "geos_datasource.hpp" -#include "geos_featureset.hpp" - -// stl -#include -#include -#include -#include - -// mapnik -#include -#include -#include -#include -#include - -// boost -#include -#include -#include -#include -#include - -// geos -#include - -using mapnik::box2d; -using mapnik::coord2d; -using mapnik::query; -using mapnik::featureset_ptr; -using mapnik::layer_descriptor; -using mapnik::attribute_descriptor; -using mapnik::datasource_exception; -using mapnik::datasource; -using mapnik::parameters; -using mapnik::filter_in_box; - -DATASOURCE_PLUGIN(geos_datasource) - -void geos_notice(const char* format, ...) -{ -#ifdef MAPNIK_LOG - char buffer[512]; - va_list args; - va_start(args, format); - vsnprintf(buffer, 512, format, args); - va_end(args); - - MAPNIK_LOG_WARN(geos) << "geos_datasource: " << buffer; -#endif -} - -void geos_error(const char* format, ...) -{ -#ifdef MAPNIK_LOG - char buffer[512]; - va_list args; - va_start(args, format); - vsnprintf(buffer, 512, format, args); - va_end(args); - - MAPNIK_LOG_ERROR(geos) << "geos_datasource: " << buffer; -#endif -} - - -geos_datasource::geos_datasource(parameters const& params) - : datasource(params), - extent_(), - extent_initialized_(false), - type_(datasource::Vector), - desc_(*params.get("type"), *params.get("encoding", "utf-8")), - geometry_data_(""), - geometry_data_name_("name"), - geometry_id_(1) -{ - boost::optional geometry = params.get("wkt"); - if (! geometry) throw datasource_exception("missing parameter"); - geometry_string_ = *geometry; - - boost::optional ext = params.get("extent"); - if (ext) extent_initialized_ = extent_.from_string(*ext); - - boost::optional id = params.get("gid"); - if (id) geometry_id_ = *id; - - boost::optional gdata = params.get("field_data"); - if (gdata) geometry_data_ = *gdata; - - boost::optional gdata_name = params.get("field_name"); - if (gdata_name) geometry_data_name_ = *gdata_name; - - desc_.add_descriptor(attribute_descriptor(geometry_data_name_, mapnik::String)); - -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats__(std::clog, "geos_datasource::init"); -#endif - - // open geos driver - initGEOS(geos_notice, geos_error); - - // parse the string into geometry - geometry_.set_feature(GEOSGeomFromWKT(geometry_string_.c_str())); - if (*geometry_ == NULL || ! GEOSisValid(*geometry_)) - { - throw datasource_exception("GEOS Plugin: invalid geometry specified"); - } - - // try to obtain the extent from the geometry itself - if (! extent_initialized_) - { -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats2__(std::clog, "geos_datasource::init(initialize_extent)"); -#endif - - MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Initializing extent from geometry"; - - if (GEOSGeomTypeId(*geometry_) == GEOS_POINT) - { - double x, y; - unsigned int size; - - const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq(*geometry_); - - GEOSCoordSeq_getSize(cs, &size); - GEOSCoordSeq_getX(cs, 0, &x); - GEOSCoordSeq_getY(cs, 0, &y); - - extent_.init(x, y, x, y); - extent_initialized_ = true; - } - else - { - geos_feature_ptr envelope (GEOSEnvelope(*geometry_)); - if (*envelope != NULL && GEOSisValid(*envelope)) - { -#ifdef MAPNIK_LOG - char* wkt = GEOSGeomToWKT(*envelope); - MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Getting coord sequence from=" << wkt; - GEOSFree(wkt); -#endif - - const GEOSGeometry* exterior = GEOSGetExteriorRing(*envelope); - if (exterior != NULL && GEOSisValid(exterior)) - { - const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq(exterior); - if (cs != NULL) - { - MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Iterating boundary points"; - - double x, y; - double minx = std::numeric_limits::max(), - miny = std::numeric_limits::max(), - maxx = -std::numeric_limits::max(), - maxy = -std::numeric_limits::max(); - - unsigned int num_points; - GEOSCoordSeq_getSize(cs, &num_points); - - for (unsigned int i = 0; i < num_points; ++i) - { - GEOSCoordSeq_getX(cs, i, &x); - GEOSCoordSeq_getY(cs, i, &y); - - if (x < minx) minx = x; - if (x > maxx) maxx = x; - if (y < miny) miny = y; - if (y > maxy) maxy = y; - } - - extent_.init(minx, miny, maxx, maxy); - extent_initialized_ = true; - } - } - } - } - } - - if (! extent_initialized_) - { - throw datasource_exception("GEOS Plugin: cannot determine extent for geometry"); - } - -} - -geos_datasource::~geos_datasource() -{ - { - geometry_.set_feature(0); - - finishGEOS(); - } -} - - -const char * geos_datasource::name() -{ - return "geos"; -} - -mapnik::datasource::datasource_t geos_datasource::type() const -{ - return type_; -} - -box2d geos_datasource::envelope() const -{ - return extent_; -} - -boost::optional geos_datasource::get_geometry_type() const -{ - boost::optional result; - -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats__(std::clog, "geos_datasource::get_geometry_type"); -#endif - - // get geometry type - const int type = GEOSGeomTypeId(*geometry_); - switch (type) - { - case GEOS_POINT: - case GEOS_MULTIPOINT: - result.reset(mapnik::datasource::Point); - break; - case GEOS_LINESTRING: - case GEOS_LINEARRING: - case GEOS_MULTILINESTRING: - result.reset(mapnik::datasource::LineString); - break; - case GEOS_POLYGON: - case GEOS_MULTIPOLYGON: - result.reset(mapnik::datasource::Polygon); - break; - case GEOS_GEOMETRYCOLLECTION: - result.reset(mapnik::datasource::Collection); - break; - default: - break; - } - - return result; -} - -layer_descriptor geos_datasource::get_descriptor() const -{ - return desc_; -} - -featureset_ptr geos_datasource::features(query const& q) const -{ -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats__(std::clog, "geos_datasource::features"); -#endif - - const mapnik::box2d extent = q.get_bbox(); - - std::ostringstream s; - s << "POLYGON((" - << extent.minx() << " " << extent.miny() << "," - << extent.maxx() << " " << extent.miny() << "," - << extent.maxx() << " " << extent.maxy() << "," - << extent.minx() << " " << extent.maxy() << "," - << extent.minx() << " " << extent.miny() - << "))"; - - MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Using extent=" << s.str(); - - return boost::make_shared(*geometry_, - GEOSGeomFromWKT(s.str().c_str()), - geometry_id_, - geometry_data_, - geometry_data_name_, - desc_.get_encoding()); -} - -featureset_ptr geos_datasource::features_at_point(coord2d const& pt, double tol) const -{ -#ifdef MAPNIK_STATS - mapnik::progress_timer __stats__(std::clog, "geos_datasource::features_at_point"); -#endif - - std::ostringstream s; - s << "POINT(" << pt.x << " " << pt.y << ")"; - - MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Using point=" << s.str(); - - return boost::make_shared(*geometry_, - GEOSGeomFromWKT(s.str().c_str()), - geometry_id_, - geometry_data_, - geometry_data_name_, - desc_.get_encoding()); -} diff --git a/plugins/input/geos/geos_datasource.hpp b/plugins/input/geos/geos_datasource.hpp deleted file mode 100644 index 35bb813ec..000000000 --- a/plugins/input/geos/geos_datasource.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef GEOS_DATASOURCE_HPP -#define GEOS_DATASOURCE_HPP - -// mapnik -#include -#include -#include -#include -#include -#include -#include - -// boost -#include -#include - -// stl -#include -#include - -#include "geos_feature_ptr.hpp" - -class geos_datasource : public mapnik::datasource -{ -public: - geos_datasource(mapnik::parameters const& params); - virtual ~geos_datasource (); - mapnik::datasource::datasource_t type() const; - static const char * name(); - mapnik::featureset_ptr features(mapnik::query const& q) const; - mapnik::featureset_ptr features_at_point(mapnik::coord2d const& pt, double tol = 0) const; - mapnik::box2d envelope() const; - boost::optional get_geometry_type() const; - mapnik::layer_descriptor get_descriptor() const; - -private: - void init(mapnik::parameters const& params); - mapnik::box2d extent_; - bool extent_initialized_; - mapnik::datasource::datasource_t type_; - mapnik::layer_descriptor desc_; - mutable geos_feature_ptr geometry_; - std::string geometry_data_; - std::string geometry_data_name_; - int geometry_id_; - std::string geometry_string_; -}; - -#endif // GEOS_DATASOURCE_HPP diff --git a/plugins/input/geos/geos_feature_ptr.hpp b/plugins/input/geos/geos_feature_ptr.hpp deleted file mode 100644 index 069dc6124..000000000 --- a/plugins/input/geos/geos_feature_ptr.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef GEOS_FEATURE_PTR_HPP -#define GEOS_FEATURE_PTR_HPP - -// geos -#include -#include - -class geos_feature_ptr -{ -public: - geos_feature_ptr () - : feat_ (NULL) - { - } - - explicit geos_feature_ptr (GEOSGeometry* const feat) - : feat_ (feat) - { - } - - ~geos_feature_ptr () - { - if (feat_ != NULL) - GEOSGeom_destroy(feat_); - } - - void set_feature (GEOSGeometry* const feat) - { - if (feat_ != NULL) - GEOSGeom_destroy(feat_); - - feat_ = feat; - } - - GEOSGeometry* operator*() - { - return feat_; - } - -private: - GEOSGeometry* feat_; -}; - - -class geos_wkb_ptr -{ -public: - geos_wkb_ptr (GEOSGeometry* const geometry) - : data_ (NULL), - size_ (0) - { - data_ = GEOSGeomToWKB_buf(geometry, &size_); - } - - ~geos_wkb_ptr () - { - if (data_ != NULL) - { - // We use std::free here instead of GEOSFree(data_) to support geos 3.1.0 - std::free(data_); - } - } - - bool is_valid() const - { - return (data_ != NULL) && (size_ > 0); - } - - unsigned int size() const - { - return (unsigned int) size_; - } - - const char* data() - { - return reinterpret_cast(data_); - } - -private: - unsigned char* data_; - size_t size_; -}; - - -#endif // GEOS_FEATURE_PTR_HPP - diff --git a/plugins/input/geos/geos_featureset.cpp b/plugins/input/geos/geos_featureset.cpp deleted file mode 100644 index 339cb46a5..000000000 --- a/plugins/input/geos/geos_featureset.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -// mapnik -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "geos_featureset.hpp" - -// boost -#include - -using mapnik::query; -using mapnik::box2d; -using mapnik::feature_ptr; -using mapnik::geometry_utils; -using mapnik::transcoder; -using mapnik::feature_factory; - -geos_featureset::geos_featureset(GEOSGeometry* geometry, - GEOSGeometry* extent, - mapnik::value_integer feature_id, - std::string const& field, - std::string const& field_name, - std::string const& encoding) - : geometry_(geometry), - tr_(new transcoder(encoding)), - extent_(extent), - feature_id_(feature_id), - field_(field), - field_name_(field_name), - already_rendered_(false), - ctx_(boost::make_shared()) -{ - ctx_->push(field_name); -} - -geos_featureset::~geos_featureset() -{ -} - -feature_ptr geos_featureset::next() -{ - if (! already_rendered_) - { - already_rendered_ = true; - - if (GEOSisValid(geometry_) && ! GEOSisEmpty(geometry_)) - { - bool render_geometry = true; - - if (*extent_ != NULL && GEOSisValid(*extent_) && ! GEOSisEmpty(*extent_)) - { - const int type = GEOSGeomTypeId(*extent_); - render_geometry = false; - - switch (type) - { - case GEOS_POINT: - if (GEOSIntersects(*extent_, geometry_)) - { - render_geometry = true; - } - break; - - case GEOS_POLYGON: - if (GEOSContains(*extent_, geometry_) - || GEOSWithin(geometry_, *extent_) - || GEOSEquals(geometry_, *extent_)) - { - render_geometry = true; - } - break; - - default: - MAPNIK_LOG_DEBUG(geos) << "geos_featureset: Unknown extent geometry_type=" << type; - break; - } - } - - if (render_geometry) - { - geos_wkb_ptr wkb(geometry_); - if (wkb.is_valid()) - { - feature_ptr feature(feature_factory::create(ctx_,feature_id_)); - - if (geometry_utils::from_wkb(feature->paths(), - wkb.data(), - wkb.size()) - && field_ != "") - { - feature->put(field_name_, tr_->transcode(field_.c_str())); - } - - return feature; - } - } - } - } - - return feature_ptr(); -} diff --git a/plugins/input/geos/geos_featureset.hpp b/plugins/input/geos/geos_featureset.hpp deleted file mode 100644 index 3180449ed..000000000 --- a/plugins/input/geos/geos_featureset.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/***************************************************************************** - * - * This file is part of Mapnik (c++ mapping toolkit) - * - * Copyright (C) 2011 Artem Pavlenko - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - *****************************************************************************/ - -#ifndef GEOS_FEATURESET_HPP -#define GEOS_FEATURESET_HPP - -// mapnik -#include -#include -#include -#include - -// boost -#include - -// geos -#include - -#include "geos_feature_ptr.hpp" - -class geos_featureset : public mapnik::Featureset -{ -public: - geos_featureset(GEOSGeometry* geometry, - GEOSGeometry* extent, - mapnik::value_integer feature_id, - std::string const& field, - std::string const& field_name, - std::string const& encoding); - virtual ~geos_featureset(); - mapnik::feature_ptr next(); - -private: - GEOSGeometry* geometry_; - boost::scoped_ptr tr_; - geos_feature_ptr extent_; - mapnik::value_integer feature_id_; - std::string field_; - std::string field_name_; - bool already_rendered_; - mapnik::context_ptr ctx_; - - geos_featureset(const geos_featureset&); - const geos_featureset& operator=(const geos_featureset&); -}; - -#endif // GEOS_FEATURESET_HPP From 3f6abd3362b5870b09f30c68b3e1c22619c36719 Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 22 Apr 2013 11:35:09 +0100 Subject: [PATCH 2/3] + backport image_reader from buffer/string from image-readers-c++11 branch --- bindings/python/mapnik_image.cpp | 34 ++++++ include/mapnik/factory.hpp | 12 ++- include/mapnik/image_reader.hpp | 8 +- src/image_reader.cpp | 44 ++++++++ src/jpeg_reader.cpp | 179 ++++++++++++++++++++++++------- src/png_reader.cpp | 123 ++++++++++++--------- 6 files changed, 311 insertions(+), 89 deletions(-) diff --git a/bindings/python/mapnik_image.cpp b/bindings/python/mapnik_image.cpp index 32384a034..5dde3c86c 100644 --- a/bindings/python/mapnik_image.cpp +++ b/bindings/python/mapnik_image.cpp @@ -164,6 +164,36 @@ boost::shared_ptr open_from_file(std::string const& filename) throw mapnik::image_reader_exception("Unsupported image format:" + filename); } +boost::shared_ptr fromstring(std::string const& str) +{ + std::auto_ptr reader(get_image_reader(str.c_str(),str.size())); + if (reader.get()) + { + boost::shared_ptr image_ptr = boost::make_shared(reader->width(),reader->height()); + reader->read(0,0,image_ptr->data()); + return image_ptr; + } + throw mapnik::image_reader_exception("Failed to load image from buffer" ); +} + +boost::shared_ptr frombuffer(PyObject * obj) +{ + void const* buffer=0; + Py_ssize_t buffer_len; + if (PyObject_AsReadBuffer(obj, &buffer, &buffer_len) == 0) + { + std::auto_ptr reader(get_image_reader(reinterpret_cast(buffer),buffer_len)); + if (reader.get()) + { + boost::shared_ptr image_ptr = boost::make_shared(reader->width(),reader->height()); + reader->read(0,0,image_ptr->data()); + return image_ptr; + } + } + throw mapnik::image_reader_exception("Failed to load image from buffer" ); +} + + void blend (image_32 & im, unsigned x, unsigned y, image_32 const& im2, float opacity) { im.set_rectangle_alpha2(im2.data(),x,y,opacity); @@ -257,6 +287,10 @@ void export_image() .def("save", &save_to_file3) .def("open",open_from_file) .staticmethod("open") + .def("frombuffer",&frombuffer) + .staticmethod("frombuffer") + .def("fromstring",&fromstring) + .staticmethod("fromstring") #if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO) .def("from_cairo",&from_cairo) .staticmethod("from_cairo") diff --git a/include/mapnik/factory.hpp b/include/mapnik/factory.hpp index ac44ca3e7..775329c09 100644 --- a/include/mapnik/factory.hpp +++ b/include/mapnik/factory.hpp @@ -83,7 +83,17 @@ public: { return (pos->second)(file); } - return factory_error_policy::on_unknown_type(key); + return 0; + } + + product_type* create_object(const key_type& key, char const* data, std::size_t size) + { + typename product_map::const_iterator pos=map_.find(key); + if (pos!=map_.end()) + { + return (pos->second)(data, size); + } + return 0; } }; } diff --git a/include/mapnik/image_reader.hpp b/include/mapnik/image_reader.hpp index dff902653..c30d1da6f 100644 --- a/include/mapnik/image_reader.hpp +++ b/include/mapnik/image_reader.hpp @@ -27,13 +27,16 @@ #include #include #include - +#include +// boost +#include // stl #include #include namespace mapnik { + class image_reader_exception : public std::exception { private: @@ -60,8 +63,11 @@ struct MAPNIK_DECL image_reader : private mapnik::noncopyable }; bool register_image_reader(std::string const& type,image_reader* (*)(std::string const&)); +bool register_image_reader(std::string const& type,image_reader* (*)(char const*, std::size_t)); + MAPNIK_DECL image_reader* get_image_reader(std::string const& file,std::string const& type); MAPNIK_DECL image_reader* get_image_reader(std::string const& file); +MAPNIK_DECL image_reader* get_image_reader(char const* data, size_t size); } diff --git a/src/image_reader.cpp b/src/image_reader.cpp index 22e476e27..af98b6f0e 100644 --- a/src/image_reader.cpp +++ b/src/image_reader.cpp @@ -27,15 +27,59 @@ namespace mapnik { + typedef factory ImageReaderFactory; +typedef factory MemImageReaderFactory; + + +inline boost::optional type_from_bytes(char const* data, size_t size) +{ + typedef boost::optional result_type; + if (size >= 4) + { + unsigned int magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + if (magic == 0x89504E47U) + { + return result_type("png"); + } + else if (magic == 0x49492A00 || magic == 0x4D4D002A) + { + return result_type("tiff"); + } + } + if (size>=2) + { + unsigned int magic = ((data[0] << 8) | data[1]) & 0xffff; + if (magic == 0xffd8) + { + return result_type("jpeg"); + } + } + + return result_type(); +} bool register_image_reader(std::string const& type,image_reader* (* fun)(std::string const&)) { return ImageReaderFactory::instance().register_product(type,fun); } +bool register_image_reader(std::string const& type,image_reader* (* fun)(char const*, std::size_t)) +{ + return MemImageReaderFactory::instance().register_product(type,fun); +} + +image_reader* get_image_reader(char const* data, size_t size) +{ + boost::optional type = type_from_bytes(data,size); + if (type) + return MemImageReaderFactory::instance().create_object(*type, data,size); + return 0; +} + image_reader* get_image_reader(std::string const& filename,std::string const& type) { return ImageReaderFactory::instance().create_object(type,filename); diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp index 169db9a6b..f7a491307 100644 --- a/src/jpeg_reader.cpp +++ b/src/jpeg_reader.cpp @@ -23,7 +23,6 @@ // mapnik #include #include -#include // jpeg extern "C" @@ -34,24 +33,29 @@ extern "C" // boost #include #include +#include +#include +#include // std #include namespace mapnik { + +template class jpeg_reader : public image_reader { - struct jpeg_file_guard +public: + typedef T source_type; + typedef boost::iostreams::stream input_stream; + const static unsigned BUF_SIZE = 4096; +private: + struct jpeg_stream_wrapper { - jpeg_file_guard(FILE * fd) - : fd_(fd) {} - - ~jpeg_file_guard() - { - if (fd_) fclose(fd_); - } - FILE * fd_; + jpeg_source_mgr manager; + input_stream * stream; + JOCTET buffer[BUF_SIZE]; }; struct jpeg_info_guard @@ -67,11 +71,13 @@ class jpeg_reader : public image_reader }; private: - std::string file_name_; + source_type source_; + input_stream stream_; unsigned width_; unsigned height_; public: - explicit jpeg_reader(std::string const& fileName); + explicit jpeg_reader(std::string const& file_name); + explicit jpeg_reader(char const* data, size_t size); ~jpeg_reader(); unsigned width() const; unsigned height() const; @@ -81,44 +87,135 @@ private: void init(); static void on_error(j_common_ptr cinfo); static void on_error_message(j_common_ptr cinfo); + static void init_source(j_decompress_ptr cinfo); + static boolean fill_input_buffer(j_decompress_ptr cinfo); + static void skip(j_decompress_ptr cinfo, long count); + static void term(j_decompress_ptr cinfo); + static void attach_stream(j_decompress_ptr cinfo, input_stream* in); }; namespace { image_reader* create_jpeg_reader(std::string const& file) { - return new jpeg_reader(file); -} -const bool registered = register_image_reader("jpeg",create_jpeg_reader); + return new jpeg_reader(file); } -jpeg_reader::jpeg_reader(std::string const& fileName) - : file_name_(fileName), +image_reader* create_jpeg_reader2(char const* data, size_t size) +{ + return new jpeg_reader(data, size); +} + +const bool registered = register_image_reader("jpeg",create_jpeg_reader); +const bool registered2 = register_image_reader("jpeg",create_jpeg_reader2); +} + +// ctors +template +jpeg_reader::jpeg_reader(std::string const& file_name) + : source_(file_name,std::ios_base::in | std::ios_base::binary), + stream_(source_), width_(0), height_(0) { + if (!stream_) throw image_reader_exception("cannot open image file "+ file_name); init(); } -jpeg_reader::~jpeg_reader() {} - -void jpeg_reader::on_error(j_common_ptr cinfo) +template +jpeg_reader::jpeg_reader(char const* data, size_t size) + : source_(data, size), + stream_(source_), + width_(0), + height_(0) +{ + if (!stream_) throw image_reader_exception("cannot open image stream"); + init(); +} + +// dtor +template +jpeg_reader::~jpeg_reader() {} + +// jpeg stream wrapper +template +void jpeg_reader::init_source (j_decompress_ptr cinfo) +{ + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + wrap->stream->seekg(0,std::ios_base::beg); +} + +template +boolean jpeg_reader::fill_input_buffer (j_decompress_ptr cinfo) +{ + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + wrap->stream->read(reinterpret_cast(&wrap->buffer[0]),BUF_SIZE); + std::streamsize size = wrap->stream->gcount(); + wrap->manager.next_input_byte = wrap->buffer; + wrap->manager.bytes_in_buffer = BUF_SIZE; + return (size > 0) ? TRUE : FALSE; +} + +template +void jpeg_reader::skip(j_decompress_ptr cinfo, long count) +{ + if (count <= 0) return; //A zero or negative skip count should be treated as a no-op. + jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); + + if (wrap->manager.bytes_in_buffer > 0 && count < wrap->manager.bytes_in_buffer) + { + wrap->manager.bytes_in_buffer -= count; + wrap->manager.next_input_byte = &wrap->buffer[BUF_SIZE - wrap->manager.bytes_in_buffer]; + } + else + { + wrap->stream->seekg(count, std::ios_base::cur); + // trigger buffer fill + wrap->manager.next_input_byte = 0; + wrap->manager.bytes_in_buffer = 0; //bytes_in_buffer may be zero on return. + } +} + +template +void jpeg_reader::term (j_decompress_ptr cinfo) +{ +// no-op +} + +template +void jpeg_reader::attach_stream (j_decompress_ptr cinfo, input_stream* in) +{ + if (cinfo->src == 0) + { + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper)); + } + jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); + src->manager.init_source = init_source; + src->manager.fill_input_buffer = fill_input_buffer; + src->manager.skip_input_data = skip; + src->manager.resync_to_restart = jpeg_resync_to_restart; + src->manager.term_source = term; + src->manager.bytes_in_buffer = 0; + src->manager.next_input_byte = 0; + src->stream = in; +} + +template +void jpeg_reader::on_error(j_common_ptr cinfo) { - //(*cinfo->err->output_message)(cinfo); - //jpeg_destroy(cinfo); throw image_reader_exception("JPEG Reader: libjpeg could not read image"); } -void jpeg_reader::on_error_message(j_common_ptr cinfo) +template +void jpeg_reader::on_error_message(j_common_ptr cinfo) { // used to supress jpeg from printing to stderr } -void jpeg_reader::init() +template +void jpeg_reader::init() { - FILE * fp = fopen(file_name_.c_str(),"rb"); - if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + file_name_); - jpeg_file_guard guard(fp); jpeg_decompress_struct cinfo; jpeg_info_guard iguard(&cinfo); jpeg_error_mgr jerr; @@ -126,38 +223,42 @@ void jpeg_reader::init() jerr.error_exit = on_error; jerr.output_message = on_error_message; jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, fp); + attach_stream(&cinfo, &stream_); int ret = jpeg_read_header(&cinfo, TRUE); - if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader: failed to read header in " + file_name_); + if (ret != JPEG_HEADER_OK) + throw image_reader_exception("JPEG Reader: failed to read header"); jpeg_start_decompress(&cinfo); width_ = cinfo.output_width; height_ = cinfo.output_height; if (cinfo.out_color_space == JCS_UNKNOWN) { - throw image_reader_exception("JPEG Reader: failed to read unknown color space in " + file_name_); + throw image_reader_exception("JPEG Reader: failed to read unknown color space"); } if (cinfo.output_width == 0 || cinfo.output_height == 0) { - throw image_reader_exception("JPEG Reader: failed to read image size of " + file_name_); + throw image_reader_exception("JPEG Reader: failed to read image size of"); } } -unsigned jpeg_reader::width() const +template +unsigned jpeg_reader::width() const { return width_; } -unsigned jpeg_reader::height() const +template +unsigned jpeg_reader::height() const { return height_; } -void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image) +template +void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image) { - FILE * fp = fopen(file_name_.c_str(),"rb"); - if (!fp) throw image_reader_exception("JPEG Reader: cannot open image file " + file_name_); - jpeg_file_guard guard(fp); + stream_.clear(); + stream_.seekg(0, std::ios_base::beg); + jpeg_decompress_struct cinfo; jpeg_info_guard iguard(&cinfo); jpeg_error_mgr jerr; @@ -165,9 +266,9 @@ void jpeg_reader::read(unsigned x0, unsigned y0, image_data_32& image) jerr.error_exit = on_error; jerr.output_message = on_error_message; jpeg_create_decompress(&cinfo); - jpeg_stdio_src(&cinfo, fp); + attach_stream(&cinfo, &stream_); int ret = jpeg_read_header(&cinfo, TRUE); - if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader: failed to read header in " + file_name_); + if (ret != JPEG_HEADER_OK) throw image_reader_exception("JPEG Reader read(): failed to read header"); jpeg_start_decompress(&cinfo); JSAMPARRAY buffer; int row_stride; diff --git a/src/png_reader.cpp b/src/png_reader.cpp index 324c33e7d..fa0ec9821 100644 --- a/src/png_reader.cpp +++ b/src/png_reader.cpp @@ -20,32 +20,27 @@ * *****************************************************************************/ +// mapnik #include #include -#include extern "C" { #include } - +// boost #include +#include +#include namespace mapnik { + +template class png_reader : public image_reader { - struct png_file_guard - { - png_file_guard(FILE * fd) - : fd_(fd) {} - - ~png_file_guard() - { - if (fd_) fclose(fd_); - } - FILE * fd_; - }; + typedef T source_type; + typedef boost::iostreams::stream ifstream; struct png_struct_guard { @@ -62,13 +57,16 @@ class png_reader : public image_reader }; private: - std::string fileName_; + + source_type source_; + ifstream stream_; unsigned width_; unsigned height_; int bit_depth_; int color_type_; public: - explicit png_reader(std::string const& fileName); + explicit png_reader(std::string const& file_name); + explicit png_reader(char const* data, std::size_t size); ~png_reader(); unsigned width() const; unsigned height() const; @@ -76,28 +74,26 @@ public: void read(unsigned x,unsigned y,image_data_32& image); private: void init(); + static void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length); }; namespace { + image_reader* create_png_reader(std::string const& file) { - return new png_reader(file); -} -const bool registered = register_image_reader("png",create_png_reader); + return new png_reader(file); } -png_reader::png_reader(std::string const& fileName) - : fileName_(fileName), - width_(0), - height_(0), - bit_depth_(0), - color_type_(0) +image_reader* create_png_reader2(char const * data, std::size_t size) { - init(); + return new png_reader(data, size); +} + +const bool registered = register_image_reader("png",create_png_reader); +const bool registered2 = register_image_reader("png", create_png_reader2); } -png_reader::~png_reader() {} void user_error_fn(png_structp png_ptr, png_const_charp error_msg) { @@ -109,35 +105,64 @@ void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) MAPNIK_LOG_DEBUG(png_reader) << "libpng warning: '" << warning_msg << "'"; } -static void -png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +template +void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { - png_size_t check; - check = (png_size_t)fread(data, (png_size_t)1, length, - (FILE *)png_get_io_ptr(png_ptr)); - - if (check != length) + ifstream * fin = reinterpret_cast(png_get_io_ptr(png_ptr)); + fin->read(reinterpret_cast(data), length); + if (fin->gcount() != length) { png_error(png_ptr, "Read Error"); } } -void png_reader::init() +template +png_reader::png_reader(std::string const& file_name) + : source_(file_name,std::ios_base::in | std::ios_base::binary), + stream_(source_), + width_(0), + height_(0), + bit_depth_(0), + color_type_(0) { - FILE *fp=fopen(fileName_.c_str(),"rb"); - if (!fp) throw image_reader_exception("cannot open image file "+fileName_); - png_file_guard guard(fp); + if (!stream_) throw image_reader_exception("cannot open image file "+ file_name); + init(); +} + +template +png_reader::png_reader(char const* data, std::size_t size) + : source_(data,size), + stream_(source_), + width_(0), + height_(0), + bit_depth_(0), + color_type_(0) +{ + + if (!stream_) throw image_reader_exception("cannot open image stream"); + init(); +} + + +template +png_reader::~png_reader() {} + + +template +void png_reader::init() +{ png_byte header[8]; memset(header,0,8); - if ( fread(header,1,8,fp) != 8) + stream_.read(reinterpret_cast(header),8); + if ( stream_.gcount() != 8) { - throw image_reader_exception("Could not read " + fileName_); + throw image_reader_exception("Could not read image"); } int is_png=!png_sig_cmp(header,0,8); if (!is_png) { - throw image_reader_exception(fileName_ + " is not a png file"); + throw image_reader_exception(" File or steam is not a png"); } png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,0,0,0); @@ -155,7 +180,7 @@ void png_reader::init() info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); - png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data); + png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); png_set_sig_bytes(png_ptr,8); png_read_info(png_ptr, info_ptr); @@ -169,21 +194,23 @@ void png_reader::init() MAPNIK_LOG_DEBUG(png_reader) << "png_reader: bit_depth=" << bit_depth_ << ",color_type=" << color_type_; } -unsigned png_reader::width() const +template +unsigned png_reader::width() const { return width_; } -unsigned png_reader::height() const +template +unsigned png_reader::height() const { return height_; } -void png_reader::read(unsigned x0, unsigned y0,image_data_32& image) +template +void png_reader::read(unsigned x0, unsigned y0,image_data_32& image) { - FILE *fp=fopen(fileName_.c_str(),"rb"); - if (!fp) throw image_reader_exception("cannot open image file "+fileName_); - png_file_guard guard(fp); + stream_.clear(); + stream_.seekg(0, std::ios_base::beg); png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,0,0,0); @@ -201,7 +228,7 @@ void png_reader::read(unsigned x0, unsigned y0,image_data_32& image) info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) throw image_reader_exception("failed to create info_ptr"); - png_set_read_fn(png_ptr, (png_voidp)fp, png_read_data); + png_set_read_fn(png_ptr, (png_voidp)&stream_, png_read_data); png_read_info(png_ptr, info_ptr); if (color_type_ == PNG_COLOR_TYPE_PALETTE) From 4dd31056fc24f759ebc998ee6a15713fc8c7651d Mon Sep 17 00:00:00 2001 From: artemp Date: Mon, 22 Apr 2013 11:36:37 +0100 Subject: [PATCH 3/3] + fix warnings when compiling with g++ 4.2.1 on os x --- src/jpeg_reader.cpp | 5 +++-- src/png_reader.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/jpeg_reader.cpp b/src/jpeg_reader.cpp index f7a491307..5af08699e 100644 --- a/src/jpeg_reader.cpp +++ b/src/jpeg_reader.cpp @@ -162,7 +162,8 @@ void jpeg_reader::skip(j_decompress_ptr cinfo, long count) if (count <= 0) return; //A zero or negative skip count should be treated as a no-op. jpeg_stream_wrapper* wrap = reinterpret_cast(cinfo->src); - if (wrap->manager.bytes_in_buffer > 0 && count < wrap->manager.bytes_in_buffer) + if (wrap->manager.bytes_in_buffer > 0u + && static_cast(count) < wrap->manager.bytes_in_buffer) { wrap->manager.bytes_in_buffer -= count; wrap->manager.next_input_byte = &wrap->buffer[BUF_SIZE - wrap->manager.bytes_in_buffer]; @@ -190,7 +191,7 @@ void jpeg_reader::attach_stream (j_decompress_ptr cinfo, input_stream* in) cinfo->src = (struct jpeg_source_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(jpeg_stream_wrapper)); } - jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); + typename jpeg_reader::jpeg_stream_wrapper * src = reinterpret_cast (cinfo->src); src->manager.init_source = init_source; src->manager.fill_input_buffer = fill_input_buffer; src->manager.skip_input_data = skip; diff --git a/src/png_reader.cpp b/src/png_reader.cpp index fa0ec9821..91d0d4f46 100644 --- a/src/png_reader.cpp +++ b/src/png_reader.cpp @@ -110,7 +110,7 @@ void png_reader::png_read_data(png_structp png_ptr, png_bytep data, png_size_ { ifstream * fin = reinterpret_cast(png_get_io_ptr(png_ptr)); fin->read(reinterpret_cast(data), length); - if (fin->gcount() != length) + if (fin->gcount() != static_cast(length)) { png_error(png_ptr, "Read Error"); }