[gdal] 03/07: New upstream version 2.2.2~rc1+dfsg

Bas Couwenberg sebastic at debian.org
Sat Sep 16 01:51:23 UTC 2017


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

sebastic pushed a commit to branch experimental-2.2
in repository gdal.

commit d145cd72a458b2f625491bc3d0231b865469cedf
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Fri Sep 15 20:59:49 2017 +0200

    New upstream version 2.2.2~rc1+dfsg
---
 GDALmake.opt.in                                    |   3 +-
 MIGRATION_GUIDE.TXT                                |   6 +-
 NEWS                                               | 206 +++++++-
 VERSION                                            |   2 +-
 alg/gdal_alg.h                                     |   3 +-
 alg/gdaltransformer.cpp                            |  60 ++-
 alg/gdalwarper.cpp                                 |   5 +-
 alg/gdalwarpkernel.cpp                             |  17 +-
 alg/gdalwarpoperation.cpp                          |  29 +-
 apps/gdal_translate_lib.cpp                        |  14 +-
 apps/ogr2ogr_lib.cpp                               |  18 +-
 ci/travis/precise_32bit/before_install.sh          |   5 +-
 ci/travis/precise_32bit/install.sh                 |   3 +-
 ci/travis/trusty_clang/before_install.sh           |   5 +-
 ci/travis/trusty_clang/install.sh                  |   3 +-
 ci/travis/trusty_clang/script.sh                   |   3 +-
 configure                                          | 196 ++++++--
 configure.ac                                       | 125 +++--
 frmts/georaster/georaster_dataset.cpp              |  65 ++-
 frmts/georaster/georaster_priv.h                   |  27 +-
 frmts/georaster/georaster_wrapper.cpp              | 216 ++++++++-
 frmts/grib/degrib18/g2clib-1.0.4/dec_jpeg2000.cpp  |   5 +
 frmts/gsg/gsagdataset.cpp                          |   7 +-
 frmts/gtiff/geotiff.cpp                            | 144 +++++-
 frmts/gtiff/gt_wkt_srs.cpp                         |  20 +-
 frmts/hf2/hf2dataset.cpp                           |  11 +-
 frmts/idrisi/IdrisiDataset.cpp                     |   4 +-
 frmts/jpeg2000/jpeg2000_vsil_io.cpp                |   9 +-
 frmts/jpeg2000/jpeg2000dataset.cpp                 |   7 +-
 frmts/makefile.vc                                  |   2 -
 frmts/mbtiles/mbtilesdataset.cpp                   |  20 +-
 frmts/netcdf/netcdfdataset.cpp                     |  55 ++-
 frmts/netcdf/netcdflayer.cpp                       |  11 +-
 frmts/openjpeg/openjpegdataset.cpp                 |  75 ++-
 .../pcidsk/sdk/channel/cbandinterleavedchannel.cpp |   2 +-
 frmts/pcidsk/sdk/core/pcidsk_utils.cpp             |   6 +
 frmts/pcidsk/sdk/core/pcidskexception.cpp          |   5 +
 frmts/pdf/GNUmakefile                              |   4 +
 frmts/pdf/makefile.vc                              |   6 +-
 frmts/pdf/pdfdataset.cpp                           |  26 +-
 frmts/pdf/pdfio.cpp                                |  34 +-
 frmts/pdf/pdfio.h                                  |  16 +-
 frmts/pdf/pdfobject.cpp                            |  64 ++-
 frmts/pds/isis3dataset.cpp                         |  58 ++-
 frmts/pds/nasakeywordhandler.cpp                   |  99 ++--
 frmts/pds/nasakeywordhandler.h                     |   4 +-
 frmts/raw/cpgdataset.cpp                           |   4 +-
 frmts/raw/fastdataset.cpp                          |  18 +-
 frmts/raw/gtxdataset.cpp                           |  67 ++-
 frmts/raw/rawdataset.cpp                           |   7 +-
 frmts/srtmhgt/srtmhgtdataset.cpp                   |   5 +-
 frmts/vrt/vrtsourcedrasterband.cpp                 |  10 +-
 frmts/vrt/vrtsources.cpp                           |  16 +-
 frmts/vrt/vrtwarped.cpp                            | 106 +++-
 frmts/xyz/xyzdataset.cpp                           |  56 ++-
 gcore/gdal.h                                       |   3 +-
 gcore/gdal_misc.cpp                                |  27 +-
 gcore/gdal_priv.h                                  |   5 +-
 gcore/gdal_version.h                               |   8 +-
 gcore/gdaldriver.cpp                               |  23 +-
 gcore/gdalproxydataset.cpp                         |  25 +-
 gcore/gdalrasterblock.cpp                          |  58 ++-
 man/man1/gdal-config.1                             |   2 +-
 man/man1/gdal2tiles.1                              |   2 +-
 man/man1/gdal_calc.1                               |   2 +-
 man/man1/gdal_contour.1                            |   2 +-
 man/man1/gdal_edit.1                               |   2 +-
 man/man1/gdal_fillnodata.1                         |   2 +-
 man/man1/gdal_grid.1                               |   2 +-
 man/man1/gdal_merge.1                              |   2 +-
 man/man1/gdal_pansharpen.1                         |   2 +-
 man/man1/gdal_polygonize.1                         |   2 +-
 man/man1/gdal_proximity.1                          |   2 +-
 man/man1/gdal_rasterize.1                          |   2 +-
 man/man1/gdal_retile.1                             |   2 +-
 man/man1/gdal_sieve.1                              |   2 +-
 man/man1/gdal_translate.1                          |   2 +-
 man/man1/gdal_utilities.1                          |   2 +-
 man/man1/gdaladdo.1                                |   2 +-
 man/man1/gdalbuildvrt.1                            |   2 +-
 man/man1/gdalcompare.1                             |   2 +-
 man/man1/gdaldem.1                                 |   2 +-
 man/man1/gdalinfo.1                                |   2 +-
 man/man1/gdallocationinfo.1                        |   2 +-
 man/man1/gdalmanage.1                              |   2 +-
 man/man1/gdalmove.1                                |   2 +-
 man/man1/gdalsrsinfo.1                             |   2 +-
 man/man1/gdaltindex.1                              |   2 +-
 man/man1/gdaltransform.1                           |   2 +-
 man/man1/gdalwarp.1                                |   2 +-
 man/man1/gnm_utilities.1                           |   2 +-
 man/man1/gnmanalyse.1                              |   2 +-
 man/man1/gnmmanage.1                               |   2 +-
 man/man1/nearblack.1                               |   2 +-
 man/man1/ogr2ogr.1                                 |   2 +-
 man/man1/ogr_utilities.1                           |   2 +-
 man/man1/ogrinfo.1                                 |   2 +-
 man/man1/ogrlineref.1                              |   2 +-
 man/man1/ogrmerge.1                                |   2 +-
 man/man1/ogrtindex.1                               |   2 +-
 man/man1/pct2rgb.1                                 |   2 +-
 man/man1/rgb2pct.1                                 |   2 +-
 nmake.opt                                          |   8 +-
 ogr/ogr_srs_esri.cpp                               |  11 +-
 ogr/ogr_srs_proj4.cpp                              |  16 +-
 ogr/ogr_srs_validate.cpp                           |   4 +-
 ogr/ograpispy.cpp                                  |   9 +-
 ogr/ogrcompoundcurve.cpp                           |  15 +-
 ogr/ogrcurve.cpp                                   |  39 +-
 ogr/ogrlinestring.cpp                              |  18 +-
 ogr/ogrsf_frmts/avc/avc_rawbin.c                   |   4 +-
 ogr/ogrsf_frmts/dxf/ogrdxf_dimension.cpp           |  15 +-
 ogr/ogrsf_frmts/dxf/ogrdxflayer.cpp                |  21 +-
 ogr/ogrsf_frmts/dxf/ogrdxfwriterds.cpp             |   4 +-
 ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp       |  31 +-
 ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h         |   4 +-
 ogr/ogrsf_frmts/gml/gmlreader.cpp                  |   4 +-
 ogr/ogrsf_frmts/gml/gmlutils.cpp                   |  14 +-
 ogr/ogrsf_frmts/gmlas/ogr_gmlas.h                  |   8 +
 ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h           |   1 +
 ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp       |  16 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlasfeatureclass.cpp     |   4 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp            |   8 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp           |  53 +-
 ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp   |  37 +-
 ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp  |  13 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp   |  38 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagelayer.cpp        |  29 +-
 ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp   |  31 +-
 ogr/ogrsf_frmts/kml/kml.cpp                        |  14 +-
 ogr/ogrsf_frmts/kml/ogrkmldriver.cpp               |   9 +-
 ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp     |  28 +-
 ogr/ogrsf_frmts/mitab/mitab_feature_mif.cpp        |   5 +-
 ogr/ogrsf_frmts/mssqlspatial/ogr_mssqlspatial.h    |   6 +-
 .../mssqlspatial/ogrmssqlspatialtablelayer.cpp     |  32 +-
 ogr/ogrsf_frmts/nas/nashandler.cpp                 |  40 +-
 ogr/ogrsf_frmts/nas/nasreaderp.h                   |   5 +-
 ogr/ogrsf_frmts/ntf/ntfrecord.cpp                  |   5 +-
 ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp           |   6 +-
 ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp       |  50 +-
 ogr/ogrsf_frmts/osm/osm_parser.cpp                 |  12 +-
 ogr/ogrsf_frmts/shape/ogrshapedriver.cpp           |   6 +-
 ogr/ogrsf_frmts/shape/ogrshapelayer.cpp            |  17 +-
 ogr/ogrsf_frmts/shape/shpopen.c                    |  16 +-
 ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp     |   6 +-
 ogr/ogrsf_frmts/vrt/ogrvrtdatasource.cpp           |   4 +-
 ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp                |   6 +-
 ogr/ogrspatialreference.cpp                        |  16 +-
 ogr/ogrutils.cpp                                   |   8 +-
 port/cpl_error.cpp                                 |   6 +-
 port/cpl_string.cpp                                |   6 +-
 port/cpl_strtod.cpp                                |   8 +-
 port/cpl_vsi_error.cpp                             |   6 +-
 port/cpl_vsi_mem.cpp                               |  13 +-
 port/cpl_vsil_crypt.cpp                            |  49 +-
 port/cpl_vsil_curl.cpp                             |   3 +-
 port/cpl_vsil_gzip.cpp                             |  12 +-
 port/cplkeywordparser.cpp                          |   6 +-
 port/cplstring.cpp                                 |   6 +-
 swig/csharp/apps/GDALDatasetRasterIOEx.cs          | 329 +++++++++++++
 swig/csharp/gdal/Band.cs                           | 136 +++++-
 swig/csharp/gdal/Dataset.cs                        | 156 +++++-
 swig/csharp/gdal/GdalPINVOKE.cs                    |  88 +++-
 swig/csharp/gdal/RasterIOExtraArg.cs               | 185 +++++++
 swig/csharp/gdal/SWIGTYPE_p_GDALProgressFunc.cs    |  30 ++
 swig/csharp/gdal/gdal_wrap.cpp                     | 538 ++++++++++++++++++++-
 swig/csharp/makefile.vc                            |   3 +-
 swig/include/csharp/gdal_csharp.i                  |  82 +++-
 swig/include/csharp/gdal_csharp_extend.i           |  30 +-
 swig/include/csharp/typemaps_csharp.i              |  12 +-
 swig/include/gdal_array.i                          |   4 +-
 swig/include/perl/gdal_perl.i                      |   4 +-
 swig/include/perl/ogr_perl.i                       |   2 +-
 swig/include/python/typemaps_python.i              |   5 +-
 swig/perl/lib/Geo/GDAL.pm                          |   4 +-
 swig/perl/lib/Geo/OGR.pm                           |   2 +-
 swig/python/README.txt                             |   2 +-
 swig/python/extensions/gdal_array_wrap.cpp         |   2 +-
 swig/python/extensions/gdal_wrap.cpp               |   5 +-
 swig/python/scripts/gdal2tiles.py                  |   5 +-
 swig/python/setup.py                               |   2 +-
 181 files changed, 3984 insertions(+), 726 deletions(-)

diff --git a/GDALmake.opt.in b/GDALmake.opt.in
index 4af4653..17efccf 100644
--- a/GDALmake.opt.in
+++ b/GDALmake.opt.in
@@ -120,7 +120,7 @@ GDAL_INCLUDE	=	-I$(GDAL_ROOT)/port -I$(GDAL_ROOT)/gcore \
 # libtool targets and help variables
 LIBGDAL	:=		libgdal.la
 LIBGDAL_CURRENT	:=	23
-LIBGDAL_REVISION	:=	0
+LIBGDAL_REVISION	:=	1
 LIBGDAL_AGE	:=	3
 
 # native build targets and variables
@@ -472,6 +472,7 @@ POPPLER_HAS_OPTCONTENT = @POPPLER_HAS_OPTCONTENT@
 POPPLER_BASE_STREAM_HAS_TWO_ARGS = @POPPLER_BASE_STREAM_HAS_TWO_ARGS@
 POPPLER_0_20_OR_LATER = @POPPLER_0_20_OR_LATER@
 POPPLER_0_23_OR_LATER = @POPPLER_0_23_OR_LATER@
+POPPLER_0_58_OR_LATER = @POPPLER_0_58_OR_LATER@
 POPPLER_INC = @POPPLER_INC@
 POPPLER_PLUGIN_LIB = @POPPLER_PLUGIN_LIB@
 
diff --git a/MIGRATION_GUIDE.TXT b/MIGRATION_GUIDE.TXT
index 562f969..167155f 100644
--- a/MIGRATION_GUIDE.TXT
+++ b/MIGRATION_GUIDE.TXT
@@ -26,7 +26,11 @@ OGRFeature::IsFieldSetAndNotNull() if there is no need to distinguish both
 states.
 On the writing side, a few drivers will now distinguish between the unset
 and null state, namely GeoJSON, CouchDB, Cloudant, MongoDB, ElasticSearch and
-GML.
+GML. For example, for the GeoJSON driver, in GDAL 2.1 or before, a unset field
+was written as field_name: null. Starting with GDAL 2.2, only fields explicitly
+set as null with OGR_F_SetFieldNull() will be written with a null value.
+Unset fields of a feature will not be present in the corresponding JSon feature
+element. 
 
 MIGRATION GUIDE FROM GDAL 2.0 to GDAL 2.1
 ------------------------------------------
diff --git a/NEWS b/NEWS
index dcae136..8e8ab49 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,203 @@
+= GDAL/OGR 2.2.2 Release Notes = 
+
+The 2.2.2 release is a bug fix release.
+
+== Build ==
+
+ * Windows build: always build the PDF driver, even when none of poppler/podofo/pdfium are available, in which case it is write-only (#6938)
+ * Compilation fixes on Ubuntu 16.04 with explicit --std=c++03 (#6952)
+
+== Port ==
+
+ * /vsigzip/: make Eof() detect end of stream when receive a Z_BUF_ERROR error. Fixes #6944.
+ * Fix memleak in VSIGSFSHandler::GetFileList()
+ * /vsigzip/: avoid trying to write a .gz.properties file on a /vsicurl/ file (#7016)
+ * Fix registration of /vsicrypt/ file system handler when compiled as a plugin (#7030)
+ * CPLStrtod(): parse string like '-1.#IND0000000' as NaN instead of -1 (#7031)
+
+== Algorithms ==
+ 
+  * Warper: when operating on single-band, skip target pixels whose source center pixel is nodata (2.2 regression, #7001)
+  * Warper: avoid blocking when number of rows is 1 and NUM_THREADS > 1 (#7041). Also limit the number of threads so that each one processes at least 65536 pixels
+
+== GDAL core ==
+
+ * GDALGCPsToGeoTransform(): add GDAL_GCPS_TO_GEOTRANSFORM_APPROX_OK=YES and GDAL_GCPS_TO_GEOTRANSFORM_APPROX_THRESHOLD=threshold_in_pixel configuration option (#6995)
+ * Fix issue with GDALProxyRasterBand::FlushCache() not flushing everything required (#7040)
+ * RawDataset::IRasterIO(): don't assume all bands are RawRasterBand
+
+== GDAL utilities ==
+
+ * gdal2tiles.py: fix GDAL 2.2 regression where tilemapresource.xml was no longer generated (#6966)
+ * gdal_translate/DefaultCreateCopy(): do not destroy target file in case of failed copy wen using -co APPEND_SUBDATASET=YES (#7019)
+ * gdal_translate: make -b mask[,xx] use the appropriate band data type (#7028)
+
+== GDAL drivers ==
+
+GeoRaster driver:
+ * add support for GCP (#6973)
+
+GPKG driver:
+ * do not error out if extent in gpkg_contents is present but invalid (#6976)
+ * fix opening subdatasets with absolute filenames on Windows (https://issues.qgis.org/issues/16997)
+ * fix possible assertion / corruption when creating a raster GeoPackage (#7022)
+
+GSAG driver:
+ * fix reading issue that could cause a spurious 0 value to be read and shift all following values (#6992)
+
+GTiff driver:
+ * fix reading subsampled JPEG-in-TIFF when block height = 8 (#6988)
+ * when reading a COMPD_CS (and GTIFF_REPORT_COMPD_CS=YES), set the name from the GTCitationGeoKey (#7011)
+
+GTX driver:
+ * do not emit error when opening with GDAL_PAM_ENABLED=NO (#6996)
+
+HF2 driver:
+ * fix reading tiles that are 1-pixel wide (2.1 regression, #6949)
+
+IDRISI driver:
+ * Fix memleak in IDRISI Open()
+
+ISIS3 driver:
+ * make sure that -co USE_SRC_HISTORY=NO -co ADD_GDAL_HISTORY=NO results in remove of History section (#6968)
+ * fix logic to initialize underlying GeoTIFF file in IWriteBlock(), and implement Fill() (#7040)
+
+JPEG2000 driver:
+ * Fix build failure in C++03 mode on Jasper inclusion in RHEL 6 (#6951)
+ * Fix build failure with recent Jasper that no longer define uchar
+
+JP2OpenJPEG driver:
+ * Add support for building against OpenJPEG 2.2 (#7002)
+ * fix performance issues with small images with very small tile size, such as some Sentinel2 quicklooks (#7012)
+ * properly use the opj_set_decode_area() API (#7018)
+ 
+netCDF driver:
+ * avoid vector vs raster variable confusion that prevents reading Sentinel3 datasets, and avoid invalid geolocation array to be reported (#6974)
+
+PDF driver:
+ * add support for Poppler 0.58 (#7033)
+
+PDS driver:
+ * fix parsing of labels with nested list constructs (2.2 regression, #6970)
+
+SRTMHGT driver:
+ * recognizes the .hgt.gz extension (#7016)
+
+VRT driver:
+ * avoid stack buffer read overflow with complex data type and scale = 0. (oss-fuzz#2468)
+ * fix uninitialized buffer in areas without sources when using non pixel packed spacing (#6965)
+ * Warped VRT: correctly take into account cutline for implicit overviews; also avoid serializing a duplicate CUTLINE warping options in warped .vrt (#6954)
+ * Warped VRT: fix implicit overview when output geotransform is not the same as the transformer dst geotransform (#6972)
+ * fix IGetDataCoverageStatus() in the case of non-simple sources, which unbreaks gdalenhance -equalize (#6987)
+
+== OGR core ==
+
+ * OGRCompondCurve::addCurveDirectly(): try reversing non contiguous curves (for GML/NAS)
+ * OGR API SPY: fix the way we map dataset handles to variable name, to avoid invalid reuses of variable still active
+ * OGRParseDate(): avoid false-positive time detection, in particular for GeoJSON (#7014)
+ * OGRCurve::get_isClosed(): do not take into account M component (#7017)
+ * OGRLineString::setPoint() and addPoint() with a OGRPoint* argument. properly takes into account ZM, Z and M dimensions (#7017)
+ 
+== OGRSpatialReference ==
+
+ * Fix OGRSpatialReference::IsSame() to return FALSE when comparing EPSG:3857 (web_mercator) and EPSG:3395 (WGS84 Mercator) (#7029)
+ * importFromProj4(): implement import of Hotine Oblique Mercator Two Points Natural Origin, and fix OGRSpatialReference::Validate() for that formulation (#7042)
+ 
+== OGR utilities ==
+
+ * ogr2ogr: fix small memory leak when using -limit switch
+ * ogr2ogr: make -f GMT work again (#6993)
+
+== OGR drivers ==
+
+AVCBin driver:
+ * fix 2.1 regression regarding attributes fetching (#6950)
+
+DXF driver:
+ * fix reading files where INSERT is the last entity and DXF_MERGE_BLOCK_GEOMETRIES is false (#7006)
+ * avoid segfault when creating a DXF file with only the 'blocks' layer (#6998)
+ * fix potential null pointer dereference in PrepareLineStyle (#7038)
+
+GeoJSON driver:
+ * fix 2.2 regression regarding lack of setting the FeatureCollection CRS on feature geometries (fixes https://github.com/r-spatial/sf/issues/449#issuecomment-319369945)
+ * prevent infinite recursion when reading geocouch spatiallist with properties.properties.properties (#7036)
+
+GML driver:
+ * fix field type detection logic to avoid a field with xsi:nil=true to be identified as a string (#7027)
+ * JPGIS FGD v4: fix logic so that coordinate order reported is lon/lat (https://github.com/OSGeo/gdal/pull/241)
+ 
+GMLAS driver:
+ * fix memleak in swe:DataRecord handling
+ * avoid false-positive warning about attribute found in document but ignored according to configuration, when the attribute is actually not present in the document but has a default value (#6956)
+ * (quick-and-not-prefect) fix to avoid a <xs:any> to prevent all other fields from being set (#6957)
+ * get the srsName when set on the srsName of the gml:pos of a gml:Point (#6962)
+ * CityGML related fixes: better take into account .xsd whose namespace prefix is not in the document, fix discovery of substitution elements, handle gYear data type (#6975)
+
+GPKG driver:
+ * fix feature count after SetFeature() with sqlite < 3.7.8 (#6953)
+ * do not take into account gpkg_contents for the extent of vector layers when it is present but invalid (#6976)
+ * fix logic to detect FID on SQL result layer when several FID fields are selected (#7026)
+
+KML / LIBKML drivers:
+ * read documents with an explicit kml prefix (#6981)
+
+MSSQLSpatial driver:
+ * fix issues on x64 (#6930)
+ * properly format DELETE statement with schema (#7039)
+
+OCI driver:
+ * check view with unquoted table name (#5552)
+
+OpenFileGDB driver:
+ * properly read GeneralPolygon with M component whose all values are set to NaN (#7017)
+
+OSM driver:
+ * increase string buffer for osm XML files (#6964)
+
+Shapefile driver:
+ * use VSIStatL() in Create() to properly work with /vsimem/ directories (#6991)
+ * fix regression affecting GDAL 2.1.3 or later, 2.2.0 or later, when editing the last shape of a file and growing it, and then appending a new shape, which resulted in corruption of both shapes (#7031)
+
+SQLite/Spatialite driver:
+ * escape integer primary key column name on table creation (#7007)
+
+== C# bindings ==
+
+ * Implement RasterIO extensions (#6915)
+
+== Python bindings ==
+
+ * fix reference count issue on gdal.VSIStatL() when it returns None, that can cause Python crashes if None refcount drops to zero
+ * add C-API to create driver instances for use in SWIG (https://trac.osgeo.org/osgeo4w/ticket/466)
+ 
+== Security oriented fixes ==
+
+Note: this is only a very partial backport of more extensive fixes done in GDAL trunk. Credit to OSS-Fuzz for all of them. (oss-fuzz#XXXX is a shortcut to
+https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=XXXX)
+
+* NAS: avoid assertion / null ptr deref and possibly other failures on corrupted files. (oss-fuzz#2366, oss-fuzz#2580)
+* NTF: avoid null ptr deref. Related to https://oss-fuzz.com/v2/testcase-detail/6527758899347456
+* VSIMemHandle::Read(): avoid unwanted unsigned int overflow that cause a later heap buffer overflow. Fixes https://oss-fuzz.com/v2/testcase-detail/5227283000328192.
+* MBTiles: fix use after free. (oss-fuzz#2388)
+* netCDF: fix stack buffer overflow when building vector layers from netCDF variables if they don't have the expected number of dimensions. (oss-fuzz#2400)
+* DXF: prevent infinite loop / excessive memory allocation on truncated file. (#oss-fuzz#2403)
+* DXF: avoid excessive memory allocation. (oss-fuzz#2444)
+* XYZ: fix write heap-buffer-overflow (oss-fuzz#2426)
+* GTiff: make IGetDataCoverageStatus() properly set the current TIFF directory, and only implement it for 'normal' bands. To avoid heap buffer overflows. (oss-fuzz#2438)
+* GTiff: avoid null pointer derefrence when requested implicit overviews on corrupted JPEG-compressed file. (oss-fuzz#2441)
+* GTiff: avoid potential issue on corrupted files (oss-fuzz#2481)
+* GTiff: don't override member nBlocksPerRow member of GTiffJPEGOverviewBand with unrelated value, in case of single-strip case. (oss-fuzz#3020)
+* PCIDSK: for band interleave channel, correctly use pixel_offset in case it is different from pixel_size. (oss-fuzz#2440)
+* MITAB: fix skipping of blank lines when reading MIF geometries, and avoid potential very loop loop. Fixes https://oss-fuzz.com/v2/testcase-detail/4516730841858048
+* CPLKeywordParser: avoid potential heap buffer overflow read. (oss-fuzz#2706)
+* CPLKeywordParser: avoid potential infinite loop. Fixes https://oss-fuzz.com/v2/testcase-detail/5733173726019584
+* morphFromESRI(): fixes heap-after-free uses. (oss-fuzz#2864)
+* OGR_VRT: fix null pointer dereference on GetExtent() on an invalid layer. (oss-fuzz#3017)
+* OGR_VRT: avoid crash on cyclic VRT. (oss-fuzz#3123)
+* OSM: avoid potential write heap buffer overflow on corrupted PBF files. (oss-fuzz#3022)
+* FAST: fix potential read heap buffer overflow. (oss-fuzz#3025)
+* CPG: avoid null pointer dereference on failed open. (oss-fuzz#3136)
+
 = GDAL/OGR 2.2.1 Release Notes = 
 
 The 2.2.1 release is a bug fix release.
@@ -76,7 +276,7 @@ MySQL driver:
  * fix compilation issue with Arch Linux and mariadb 10.1.23 (fixes #6899)
 
 PG driver:
- * do not be confused by a 'geometry' table in a non-PostGIS enabled detabase (#6896)
+ * do not be confused by a 'geometry' table in a non-PostGIS enabled database (#6896)
 
 PLScenes:
  * remove support for V0. Deprecate V1 API. Only Data V1 is supported ( #6933)
@@ -150,7 +350,7 @@ Note: this is only a very partial backport of more extensive fixes done in GDAL
 * GXF: fix int overflow and avoid excessive memory allocation. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2207
 * DGN: prevent heap-buffer-overflow read. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1988
 * COSAR: fix leak of file descriptor. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2019
-* ISO8211: prevent stack buffer oveflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2022
+* ISO8211: prevent stack buffer overflow. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2022
 * WEBP: prevent int32 overflow and too large memory allocation. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2059
 * IRIS: fix heap-buffer-overflow in some cases of nDataTypeCode. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2069
 * E00GRID: avoid heap and stack buffer overflows. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=2090 , 2182, 2237, 2327
@@ -7115,7 +7315,7 @@ GTiff driver:
  * ensure zip/jpeg quality is preserved in crystalize. (#2642)
  * support handling nodata via pam/aux mechanisms (#2505)
  * ensure TIFFFlush() is called in FlushCache() (#2512)
- * Replace Crystalize() by SetDirectory() in GTiffDataset::IBuildOverviews() so that 2 consecutive ds.BuilOverviews() calls work without needing to close and reopen the dataset in between
+ * Replace Crystalize() by SetDirectory() in GTiffDataset::IBuildOverviews() so that 2 consecutive ds.BuildOverviews() calls work without needing to close and reopen the dataset in between
  * Prevent crash when disk is full
  * Add detection of big-endian bigtiffs when BIGTIFF_SUPPORT is *NOT* defined
  * Add missing ScaleAtCenter parameter for Hotine Oblique Mercator when writing the geotiff keys
diff --git a/VERSION b/VERSION
index c043eea..b1b25a5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.1
+2.2.2
diff --git a/alg/gdal_alg.h b/alg/gdal_alg.h
index 65b1e5c..c4d34cc 100644
--- a/alg/gdal_alg.h
+++ b/alg/gdal_alg.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal_alg.h 37723 2017-03-16 17:07:53Z rouault $
+ * $Id: gdal_alg.h 39654 2017-07-24 19:24:32Z rouault $
  *
  * Project:  GDAL Image Processing Algorithms
  * Purpose:  Prototypes, and definitions for various GDAL based algorithms.
@@ -162,6 +162,7 @@ int CPL_DLL GDALGenImgProjTransform(
     double *x, double *y, double *z, int *panSuccess );
 
 void GDALSetTransformerDstGeoTransform( void *, const double * );
+void GDALGetTransformerDstGeoTransform( void*, double* );
 
 /* Geo to geo reprojection transformer. */
 void CPL_DLL *
diff --git a/alg/gdaltransformer.cpp b/alg/gdaltransformer.cpp
index cca2f1d..4aa584a 100644
--- a/alg/gdaltransformer.cpp
+++ b/alg/gdaltransformer.cpp
@@ -57,7 +57,7 @@
 #include "ogr_srs_api.h"
 
 
-CPL_CVSID("$Id: gdaltransformer.cpp 37723 2017-03-16 17:07:53Z rouault $");
+CPL_CVSID("$Id: gdaltransformer.cpp 39654 2017-07-24 19:24:32Z rouault $");
 
 CPL_C_START
 void *GDALDeserializeGCPTransformer( CPLXMLNode *psTree );
@@ -3658,3 +3658,61 @@ void GDALSetTransformerDstGeoTransform( void *pTransformArg,
         GDALSetGenImgProjTransformerDstGeoTransform(psInfo, padfGeoTransform);
     }
 }
+
+/************************************************************************/
+/*                 GDALGetTransformerDstGeoTransform()                  */
+/************************************************************************/
+
+/**
+ * Get ApproxTransformer or GenImgProj output geotransform.
+ *
+ * @param pTransformArg transformer handle.
+ * @param padfGeoTransform (output) the destination geotransform to return (six doubles).
+ */
+
+void GDALGetTransformerDstGeoTransform( void *pTransformArg,
+                                        double *padfGeoTransform )
+{
+    VALIDATE_POINTER0( pTransformArg, "GDALSetTransformerDstGeoTransform" );
+
+    GDALTransformerInfo *psInfo =
+        static_cast<GDALTransformerInfo *>(pTransformArg);
+
+    if( psInfo == NULL ||
+        memcmp(psInfo->abySignature,
+               GDAL_GTI2_SIGNATURE,
+               strlen(GDAL_GTI2_SIGNATURE)) != 0 )
+    {
+        CPLError(CE_Failure, CPLE_AppDefined,
+                 "Attempt to call GDALGetTransformerDstGeoTransform on "
+                 "a non-GTI2 transformer.");
+        return;
+    }
+
+    if( EQUAL(psInfo->pszClassName, "GDALApproxTransformer") )
+    {
+        ApproxTransformInfo *psATInfo =
+            static_cast<ApproxTransformInfo *>(pTransformArg);
+        psInfo = static_cast<GDALTransformerInfo *>(psATInfo->pBaseCBData);
+
+        if( psInfo == NULL ||
+            memcmp(psInfo->abySignature,
+                   GDAL_GTI2_SIGNATURE,
+                   strlen(GDAL_GTI2_SIGNATURE)) != 0 )
+        {
+            CPLError(CE_Failure, CPLE_AppDefined,
+                     "Attempt to call GDALGetTransformerDstGeoTransform on "
+                     "a non-GTI2 transformer.");
+            return;
+        }
+    }
+
+    if( EQUAL(psInfo->pszClassName, "GDALGenImgProjTransformer") )
+    {
+        GDALGenImgProjTransformInfo *psGenImgProjInfo =
+            reinterpret_cast<GDALGenImgProjTransformInfo *>( psInfo );
+
+        memcpy( padfGeoTransform, psGenImgProjInfo->adfDstGeoTransform,
+                sizeof(double) * 6 );
+    }
+}
diff --git a/alg/gdalwarper.cpp b/alg/gdalwarper.cpp
index 46ce3d8..2772dc4 100644
--- a/alg/gdalwarper.cpp
+++ b/alg/gdalwarper.cpp
@@ -51,7 +51,7 @@
 #include <emmintrin.h>
 #endif
 
-CPL_CVSID("$Id: gdalwarper.cpp 36857 2016-12-14 20:14:32Z goatbar $");
+CPL_CVSID("$Id: gdalwarper.cpp 39481 2017-07-05 08:26:30Z rouault $");
 
 /************************************************************************/
 /*                         GDALReprojectImage()                         */
@@ -1416,7 +1416,8 @@ GDALSerializeWarpOptions( const GDALWarpOptions *psWO )
 
         // EXTRA_ELTS is an internal detail that we will recover
         // no need to serialize it.
-        if( !EQUAL(pszName, "EXTRA_ELTS") )
+        // And CUTLINE is also serialized in a special way
+        if( !EQUAL(pszName, "EXTRA_ELTS") && !EQUAL(pszName, "CUTLINE") )
         {
             CPLXMLNode *psOption =
                 CPLCreateXMLElementAndValue(
diff --git a/alg/gdalwarpkernel.cpp b/alg/gdalwarpkernel.cpp
index e1ad0a5..93bf025 100644
--- a/alg/gdalwarpkernel.cpp
+++ b/alg/gdalwarpkernel.cpp
@@ -71,7 +71,7 @@
 
 #endif
 
-CPL_CVSID("$Id: gdalwarpkernel.cpp 38093 2017-04-21 21:02:44Z rouault $");
+CPL_CVSID("$Id: gdalwarpkernel.cpp 40076 2017-09-12 10:45:20Z rouault $");
 
 static const double BAND_DENSITY_THRESHOLD = 0.0000000001;
 static const float SRC_DENSITY_THRESHOLD =  0.000000001f;
@@ -476,8 +476,21 @@ static CPLErr GWKRun( GDALWarpKernel *poWK,
         return GWKGenericMonoThread(poWK, pfnFunc);
     }
 
-    const int nThreads =
+    int nThreads =
         std::min(psThreadData->poThreadPool->GetThreadCount(), nDstYSize / 2);
+    // Config option mostly useful for tests to be able to test multithreading
+    // with small rasters
+    const int nWarpChunkSize = atoi(
+        CPLGetConfigOption("WARP_THREAD_CHUNK_SIZE", "65536"));
+    if( nWarpChunkSize > 0 )
+    {
+        GIntBig nChunks =
+            static_cast<GIntBig>(nDstYSize) * poWK->nDstXSize / nWarpChunkSize;
+        if( nThreads > nChunks )
+            nThreads = static_cast<int>(nChunks);
+    }
+    if( nThreads <= 0 )
+        nThreads = 1;
 
     CPLDebug("WARP", "Using %d threads", nThreads);
 
diff --git a/alg/gdalwarpoperation.cpp b/alg/gdalwarpoperation.cpp
index 44584fa..703fc7a 100644
--- a/alg/gdalwarpoperation.cpp
+++ b/alg/gdalwarpoperation.cpp
@@ -49,7 +49,7 @@
 #include "ogr_api.h"
 #include "ogr_core.h"
 
-CPL_CVSID("$Id: gdalwarpoperation.cpp 38093 2017-04-21 21:02:44Z rouault $");
+CPL_CVSID("$Id: gdalwarpoperation.cpp 39828 2017-08-16 08:07:41Z rouault $");
 
 struct _GDALWarpChunk {
     int dx, dy, dsx, dsy;
@@ -589,7 +589,7 @@ CPLErr GDALWarpOperation::Initialize( const GDALWarpOptions *psNewOptions )
         CSLFetchNameValue( psOptions->papszWarpOptions, "CUTLINE" );
 
     CPLErr eErr = CE_None;
-    if( pszCutlineWKT )
+    if( pszCutlineWKT && psOptions->hCutline == NULL )
     {
         if( OGR_G_CreateFromWkt( (char **) &pszCutlineWKT, NULL,
                                  (OGRGeometryH *) &(psOptions->hCutline) )
@@ -599,14 +599,11 @@ CPLErr GDALWarpOperation::Initialize( const GDALWarpOptions *psNewOptions )
             CPLError( CE_Failure, CPLE_AppDefined,
                       "Failed to parse CUTLINE geometry wkt." );
         }
-        else
-        {
-            const char *pszBD = CSLFetchNameValue( psOptions->papszWarpOptions,
-                                                   "CUTLINE_BLEND_DIST" );
-            if( pszBD )
-                psOptions->dfCutlineBlendDist = CPLAtof(pszBD);
-        }
     }
+    const char *pszBD = CSLFetchNameValue( psOptions->papszWarpOptions,
+                                            "CUTLINE_BLEND_DIST" );
+    if( pszBD )
+        psOptions->dfCutlineBlendDist = CPLAtof(pszBD);
 
 /* -------------------------------------------------------------------- */
 /*      Set SRC_ALPHA_MAX if not provided.                              */
@@ -1959,13 +1956,25 @@ CPLErr GDALWarpOperation::WarpRegionToBuffer(
             oWK.papanBandSrcValid = NULL;
         }
 
+
+/* -------------------------------------------------------------------- */
+/*      If there's just a single band, then transfer                    */
+/*      papanBandSrcValid[0] as panUnifiedSrcValid.                     */
+/* -------------------------------------------------------------------- */
+        if( oWK.papanBandSrcValid != NULL && psOptions->nBandCount == 1 )
+        {
+            oWK.panUnifiedSrcValid = oWK.papanBandSrcValid[0];
+            CPLFree( oWK.papanBandSrcValid );
+            oWK.papanBandSrcValid = NULL;
+        }
+
 /* -------------------------------------------------------------------- */
 /*      If UNIFIED_SRC_NODATA is set, then compute a unified input      */
 /*      pixel mask if and only if all bands nodata is true.  That       */
 /*      is, we only treat a pixel as nodata if all bands match their    */
 /*      respective nodata values.                                       */
 /* -------------------------------------------------------------------- */
-        if( oWK.papanBandSrcValid != NULL &&
+        else if( oWK.papanBandSrcValid != NULL &&
             CPLFetchBool( psOptions->papszWarpOptions, "UNIFIED_SRC_NODATA",
                           false )
             && eErr == CE_None )
diff --git a/apps/gdal_translate_lib.cpp b/apps/gdal_translate_lib.cpp
index 5108a70..e13f3f6 100644
--- a/apps/gdal_translate_lib.cpp
+++ b/apps/gdal_translate_lib.cpp
@@ -52,7 +52,7 @@
 #include "ogr_spatialref.h"
 #include "vrtdataset.h"
 
-CPL_CVSID("$Id: gdal_translate_lib.cpp 37719 2017-03-16 14:51:42Z rouault $");
+CPL_CVSID("$Id: gdal_translate_lib.cpp 39998 2017-09-04 13:20:51Z rouault $");
 
 static int ArgIsNumeric( const char * );
 static void AttachMetadata( GDALDatasetH, char ** );
@@ -1221,16 +1221,20 @@ GDALDatasetH GDALTranslate( const char *pszDest, GDALDatasetH hSrcDataset,
 /* -------------------------------------------------------------------- */
 /*      Select output data type to match source.                        */
 /* -------------------------------------------------------------------- */
+        GDALRasterBand* poRealSrcBand =
+                (nSrcBand < 0) ? poSrcBand->GetMaskBand(): poSrcBand;
         if( psOptions->eOutputType == GDT_Unknown )
-            eBandType = poSrcBand->GetRasterDataType();
+        {
+            eBandType = poRealSrcBand->GetRasterDataType();
+        }
         else
         {
             eBandType = psOptions->eOutputType;
 
             // Check that we can copy existing statistics
-            GDALDataType eSrcBandType = poSrcBand->GetRasterDataType();
-            const char* pszMin = poSrcBand->GetMetadataItem("STATISTICS_MINIMUM");
-            const char* pszMax = poSrcBand->GetMetadataItem("STATISTICS_MAXIMUM");
+            GDALDataType eSrcBandType = poRealSrcBand->GetRasterDataType();
+            const char* pszMin = poRealSrcBand->GetMetadataItem("STATISTICS_MINIMUM");
+            const char* pszMax = poRealSrcBand->GetMetadataItem("STATISTICS_MAXIMUM");
             if( !bFilterOutStatsMetadata && eBandType != eSrcBandType &&
                 pszMin != NULL && pszMax != NULL )
             {
diff --git a/apps/ogr2ogr_lib.cpp b/apps/ogr2ogr_lib.cpp
index b361106..aea8a88 100644
--- a/apps/ogr2ogr_lib.cpp
+++ b/apps/ogr2ogr_lib.cpp
@@ -61,7 +61,7 @@
 #include "ogrlayerdecorator.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ogr2ogr_lib.cpp 39040 2017-06-09 21:43:58Z rouault $");
+CPL_CVSID("$Id: ogr2ogr_lib.cpp 39771 2017-08-07 19:33:50Z rouault $");
 
 typedef enum
 {
@@ -2142,7 +2142,14 @@ GDALDatasetH GDALVectorTranslate( const char *pszDest, GDALDatasetH hDstDS, int
     {
         GDALDriverManager *poDM = GetGDALDriverManager();
 
-        poDriver = poDM->GetDriverByName(psOptions->pszFormat);
+        const char* pszOGRCompatFormat = psOptions->pszFormat;
+        // Special processing for non-unified drivers that have the same name
+        // as GDAL and OGR drivers
+        // Other candidates could be VRT, SDTS, OGDI and PDS, but they don't
+        // have write capabilities.
+        if( EQUAL(pszOGRCompatFormat, "GMT") )
+            pszOGRCompatFormat = "OGR_GMT";
+        poDriver = poDM->GetDriverByName(pszOGRCompatFormat);
         if( poDriver == NULL )
         {
             CPLError( CE_Failure, CPLE_AppDefined,
@@ -4254,6 +4261,11 @@ int LayerTranslator::Translate( OGRFeature* poFeatureIn,
     bool bRet = true;
     while( true )
     {
+        if( m_nLimit >= 0 && psInfo->nFeaturesRead >= m_nLimit )
+        {
+            break;
+        }
+
         OGRFeature      *poDstFeature = NULL;
 
         if( poFeatureIn != NULL )
@@ -4262,8 +4274,6 @@ int LayerTranslator::Translate( OGRFeature* poFeatureIn,
             poFeature = poSrcLayer->GetFeature(psOptions->nFIDToFetch);
         else
             poFeature = poSrcLayer->GetNextFeature();
-        if( m_nLimit >= 0 && psInfo->nFeaturesRead >= m_nLimit )
-            break;
 
         if( poFeature == NULL )
             break;
diff --git a/ci/travis/precise_32bit/before_install.sh b/ci/travis/precise_32bit/before_install.sh
index 9c2c41f..f836b11 100755
--- a/ci/travis/precise_32bit/before_install.sh
+++ b/ci/travis/precise_32bit/before_install.sh
@@ -16,11 +16,12 @@ sudo i386 chroot "$chroot" apt-get update
 sudo i386 chroot "$chroot" apt-get install -y clang
 sudo i386 chroot "$chroot" apt-get install -y python-software-properties
 sudo i386 chroot "$chroot" add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
-sudo i386 chroot "$chroot" add-apt-repository -y ppa:marlam/gta
+#sudo i386 chroot "$chroot" add-apt-repository -y ppa:marlam/gta
 sudo i386 chroot "$chroot" apt-get update
 # Disable postgresql since it draws ssl-cert that doesn't install cleanly
 # postgis postgresql-9.1 postgresql-client-9.1 postgresql-9.1-postgis-2.1 postgresql-9.1-postgis-2.1-scripts libpq-dev
-sudo i386 chroot "$chroot" apt-get install -y python-numpy libpng12-dev libjpeg-dev libgif-dev liblzma-dev libgeos-dev libcurl4-gnutls-dev libproj-dev libxml2-dev libexpat-dev libxerces-c-dev libnetcdf-dev netcdf-bin libpoppler-dev libspatialite-dev gpsbabel swig libhdf4-alt-dev libhdf5-serial-dev libpodofo-dev poppler-utils libfreexl-dev unixodbc-dev libwebp-dev libepsilon-dev libgta-dev liblcms2-2 libpcre3-dev libcrypto++-dev
+sudo i386 chroot "$chroot" apt-get install -y python-numpy libpng12-dev libjpeg-dev libgif-dev liblzma-dev libgeos-dev libcurl4-gnutls-dev libproj-dev libxml2-dev libexpat-dev libxerces-c-dev libnetcdf-dev netcdf-bin libpoppler-dev libspatialite-dev gpsbabel swig libhdf4-alt-dev libhdf5-serial-dev libpodofo-dev poppler-utils libfreexl-dev unixodbc-dev libwebp-dev libepsilon-dev  liblcms2-2 libpcre3-dev libcrypto++-dev
+# libgta-dev
 sudo i386 chroot "$chroot" apt-get install -y make
 sudo i386 chroot "$chroot" apt-get install -y python-dev
 sudo i386 chroot "$chroot" apt-get install -y g++
diff --git a/ci/travis/precise_32bit/install.sh b/ci/travis/precise_32bit/install.sh
index 8277507..2767a5a 100755
--- a/ci/travis/precise_32bit/install.sh
+++ b/ci/travis/precise_32bit/install.sh
@@ -5,7 +5,8 @@ set -e
 export chroot="$PWD"/buildroot.i386
 export LC_ALL=en_US
 
-sudo i386 chroot "$chroot" sh -c "cd $PWD/gdal && CC=clang CXX=clang ./configure --prefix=/usr --without-libtool --enable-debug --with-jpeg12 --with-python --with-poppler --with-podofo --with-spatialite --with-mysql --with-liblzma --with-webp --with-epsilon --with-gta"
+sudo i386 chroot "$chroot" sh -c "cd $PWD/gdal && CC=clang CXX=clang ./configure --prefix=/usr --without-libtool --enable-debug --with-jpeg12 --with-python --with-poppler --with-podofo --with-spatialite --with-mysql --with-liblzma --with-webp --with-epsilon"
+# --with-gta
 sudo i386 chroot "$chroot" sh -c "cd $PWD/gdal && make USER_DEFS=-Werror -j3"
 sudo i386 chroot "$chroot" sh -c "cd $PWD/gdal/apps && make USER_DEFS=-Werror -j3 test_ogrsf"
 sudo i386 chroot "$chroot" sh -c "rm -f /usr/lib/libgdal.so*"
diff --git a/ci/travis/trusty_clang/before_install.sh b/ci/travis/trusty_clang/before_install.sh
index a2327ce..43182e4 100755
--- a/ci/travis/trusty_clang/before_install.sh
+++ b/ci/travis/trusty_clang/before_install.sh
@@ -9,10 +9,11 @@ sudo mv /etc/apt/sources.list.d/pgdg* /tmp
 #sudo apt-get remove postgis libpq5 libpq-dev postgresql-9.1-postgis postgresql-9.2-postgis postgresql-9.3-postgis postgresql-9.1 postgresql-9.2 postgresql-9.3 libgdal1
 #sudo apt-get remove -y postgresql-9.1
 sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
-sudo add-apt-repository -y ppa:marlam/gta
+#sudo add-apt-repository -y ppa:marlam/gta
 sudo apt-get update
 # postgis postgresql-9.5 postgresql-client-9.5 postgresql-9.5-postgis-2.2 libpq-dev
-sudo apt-get install -y ccache python-numpy libpng12-dev libjpeg-dev libgif-dev liblzma-dev libgeos-dev libcurl4-gnutls-dev libproj-dev libxml2-dev libexpat-dev libxerces-c-dev libnetcdf-dev netcdf-bin libpoppler-dev libspatialite-dev gpsbabel swig libhdf4-alt-dev libhdf5-serial-dev libpodofo-dev poppler-utils libfreexl-dev unixodbc-dev libwebp-dev  libepsilon-dev libgta-dev liblcms2-2 libpcre3-dev mercurial cmake libcrypto++-dev
+sudo apt-get install -y ccache python-numpy libpng12-dev libjpeg-dev libgif-dev liblzma-dev libgeos-dev libcurl4-gnutls-dev libproj-dev libxml2-dev libexpat-dev libxerces-c-dev libnetcdf-dev netcdf-bin libpoppler-dev libspatialite-dev gpsbabel swig libhdf4-alt-dev libhdf5-serial-dev libpodofo-dev poppler-utils libfreexl-dev unixodbc-dev libwebp-dev  libepsilon-dev  liblcms2-2 libpcre3-dev mercurial cmake libcrypto++-dev
+# libgta-dev
 sudo apt-get install -y python-lxml
 sudo apt-get install -y python-pip
 sudo apt-get install -y libqhull-dev
diff --git a/ci/travis/trusty_clang/install.sh b/ci/travis/trusty_clang/install.sh
index cc81e7f..0cc9ebf 100755
--- a/ci/travis/trusty_clang/install.sh
+++ b/ci/travis/trusty_clang/install.sh
@@ -5,7 +5,8 @@ set -e
 cd gdal
 # --with-mongocxx=/usr/local
 export CCACHE_CPP2=yes
-CC="ccache clang" CXX="ccache clang" LDFLAGS="-lstdc++" ./configure --prefix=/usr --without-libtool --with-jpeg12 --with-python --with-poppler --with-podofo --with-spatialite --with-mysql --with-liblzma --with-webp --with-java --with-mdb --with-jvm-lib-add-rpath --with-epsilon --with-gta --with-ecw=/usr/local --with-mrsid=/usr/local --with-mrsid-lidar=/usr/local --with-fgdb=/usr/local --with-libkml --with-openjpeg=/usr/local
+CC="ccache clang" CXX="ccache clang" LDFLAGS="-lstdc++" ./configure --prefix=/usr --without-libtool --with-jpeg12 --with-python --with-poppler --with-podofo --with-spatialite --with-mysql --with-liblzma --with-webp --with-java --with-mdb --with-jvm-lib-add-rpath --with-epsilon --with-ecw=/usr/local --with-mrsid=/usr/local --with-mrsid-lidar=/usr/local --with-fgdb=/usr/local --with-libkml --with-openjpeg=/usr/local
+# --with-gta
 # Those ln -s are weird but otherwise Python bindings build fail with clang not being found
 sudo ln -s /usr/local/clang-3.5.0/bin/clang /usr/bin/clang
 sudo ln -s /usr/local/clang-3.5.0/bin/clang++ /usr/bin/clang++
diff --git a/ci/travis/trusty_clang/script.sh b/ci/travis/trusty_clang/script.sh
index 8d40517..00be957 100755
--- a/ci/travis/trusty_clang/script.sh
+++ b/ci/travis/trusty_clang/script.sh
@@ -40,7 +40,8 @@ mv ogr_fgdb.* disabled
 cd ..
 # Run ogr_pgeo.py in isolation from the rest
 cd ogr
-python ogr_pgeo.py
+# This crashes on Trusty since travis-ci upgraded their Trusty workers
+#python ogr_pgeo.py
 mv ogr_pgeo.* disabled
 cd ..
 # Run all the Python autotests
diff --git a/configure b/configure
index b3f2236..fb621be 100755
--- a/configure
+++ b/configure
@@ -662,6 +662,7 @@ PODOFO_INC
 HAVE_PODOFO
 POPPLER_PLUGIN_LIB
 POPPLER_INC
+POPPLER_0_58_OR_LATER
 POPPLER_0_23_OR_LATER
 POPPLER_0_20_OR_LATER
 POPPLER_BASE_STREAM_HAS_TWO_ARGS
@@ -25115,19 +25116,19 @@ $as_echo "$as_me: OpenJPEG (JPEG2000) support disabled." >&6;}
 
 elif test "$with_openjpeg" = "yes" -o "$with_openjpeg" = "" ; then
 
-  for ac_header in openjpeg-2.0/openjpeg.h
+  for ac_header in openjpeg-2.2/openjpeg.h
 do :
-  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
-if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.2/openjpeg.h" "ac_cv_header_openjpeg_2_2_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_2_openjpeg_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
+#define HAVE_OPENJPEG_2_2_OPENJPEG_H 1
 _ACEOF
 
 fi
 
 done
 
-  if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
+  if test "$ac_cv_header_openjpeg_2_2_openjpeg_h" = "yes"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data_length in -lopenjp2" >&5
 $as_echo_n "checking for opj_stream_set_user_data_length in -lopenjp2... " >&6; }
 if ${ac_cv_lib_openjp2_opj_stream_set_user_data_length+:} false; then :
@@ -25171,6 +25172,7 @@ else
 fi
 
     if test "$HAVE_OPENJPEG" = "yes"; then
+        OPENJPEG_VERSION=20200
         LIBS="-lopenjp2 $LIBS"
     fi
   else
@@ -25233,6 +25235,66 @@ fi
             OPENJPEG_VERSION=20100
             LIBS="-lopenjp2 $LIBS"
         fi
+    else
+        for ac_header in openjpeg-2.0/openjpeg.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "openjpeg-2.0/openjpeg.h" "ac_cv_header_openjpeg_2_0_openjpeg_h" "$ac_includes_default"
+if test "x$ac_cv_header_openjpeg_2_0_openjpeg_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_OPENJPEG_2_0_OPENJPEG_H 1
+_ACEOF
+
+fi
+
+done
+
+        if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data_length in -lopenjp2" >&5
+$as_echo_n "checking for opj_stream_set_user_data_length in -lopenjp2... " >&6; }
+if ${ac_cv_lib_openjp2_opj_stream_set_user_data_length+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopenjp2  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opj_stream_set_user_data_length ();
+int
+main ()
+{
+return opj_stream_set_user_data_length ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_openjp2_opj_stream_set_user_data_length=yes
+else
+  ac_cv_lib_openjp2_opj_stream_set_user_data_length=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_openjp2_opj_stream_set_user_data_length" >&5
+$as_echo "$ac_cv_lib_openjp2_opj_stream_set_user_data_length" >&6; }
+if test "x$ac_cv_lib_openjp2_opj_stream_set_user_data_length" = xyes; then :
+  HAVE_OPENJPEG=yes
+else
+  HAVE_OPENJPEG=no
+fi
+
+            if test "$HAVE_OPENJPEG" = "yes"; then
+                LIBS="-lopenjp2 $LIBS"
+            fi
+        fi
     fi
   fi
 else
@@ -25243,8 +25305,11 @@ else
   elif test -r $with_openjpeg/include/openjpeg-2.1/openjpeg.h ; then
     OPENJPEG_VERSION=20100
     EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
+  elif test -r $with_openjpeg/include/openjpeg-2.2/openjpeg.h ; then
+    OPENJPEG_VERSION=20200
+    EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
   else
-    as_fn_error $? "openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1" "$LINENO" 5
+    as_fn_error $? "openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1 or $with_openjpeg/include/openjpeg-2.2" "$LINENO" 5
   fi
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for opj_stream_set_user_data_length in -lopenjp2" >&5
@@ -32207,6 +32272,8 @@ HAVE_POPPLER=no
 POPPLER_HAS_OPTCONTENT=no
 POPPLER_BASE_STREAM_HAS_TWO_ARGS=no
 POPPLER_0_20_OR_LATER=no
+POPPLER_0_23_OR_LATER=no
+POPPLER_0_58_OR_LATER=no
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for poppler" >&5
 $as_echo_n "checking for poppler... " >&6; }
@@ -32247,17 +32314,21 @@ $as_echo "yes" >&6; }
         POPPLER_INC=$TEST_POPPLER_INC
         POPPLER_PLUGIN_LIB="${TEST_POPPLER_LIB}"
 
-        # And now try another dirty thing, but this one is
-        # optional.
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Catalog::optContent exists" >&5
-$as_echo_n "checking if Catalog::optContent exists... " >&6; }
+        CHECK_OTHER_POPPLER_VERSION=yes
+
+        # And now we check if we have Poppler >= 0.58.0
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Object does have new API (>= 0.58.0)" >&5
+$as_echo_n "checking if Object does have new API (>= 0.58.0)... " >&6; }
         rm -f testpoppler.*
-        echo '#define private public' > testpoppler.cpp
-        echo '#include <poppler/Object.h>' >> testpoppler.cpp
-        echo '#include <poppler/Catalog.h>' >> testpoppler.cpp
-        echo 'int main(int argc, char** argv) { return &(((Catalog*)0x8000)->optContent) == 0; }' >> testpoppler.cpp
+        echo '#include <poppler/Object.h>' > testpoppler.cpp
+        echo 'int main(int argc, char** argv) { Object o(objNull); return 0; }' >> testpoppler.cpp
         if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+            POPPLER_0_58_OR_LATER=yes
+            POPPLER_0_23_OR_LATER=yes
+            POPPLER_0_20_OR_LATER=yes
+            POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
             POPPLER_HAS_OPTCONTENT=yes
+            CHECK_OTHER_POPPLER_VERSION=no
             { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
         else
@@ -32265,50 +32336,75 @@ $as_echo "yes" >&6; }
 $as_echo "no" >&6; }
         fi
 
-        # And now we check if we have Poppler >= 0.16.0
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking if BaseStream constructor needs 2 arguments" >&5
-$as_echo_n "checking if BaseStream constructor needs 2 arguments... " >&6; }
-        rm -f testpoppler.*
-        echo '#include <poppler/Object.h>' > testpoppler.cpp
-        echo '#include <poppler/Stream.h>' >> testpoppler.cpp
-        echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
-        echo 'public:' >> testpoppler.cpp
-        echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
-        echo '};' >> testpoppler.cpp
-        echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
-        if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-            POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
-            { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+        if test "$CHECK_OTHER_POPPLER_VERSION" = "yes"; then
+
+            # And now try another dirty thing, but this one is
+            # optional.
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Catalog::optContent exists" >&5
+$as_echo_n "checking if Catalog::optContent exists... " >&6; }
+            rm -f testpoppler.*
+            echo '#define private public' > testpoppler.cpp
+            echo '#include <poppler/Object.h>' >> testpoppler.cpp
+            echo '#include <poppler/Catalog.h>' >> testpoppler.cpp
+            echo 'int main(int argc, char** argv) { return &(((Catalog*)0x8000)->optContent) == 0; }' >> testpoppler.cpp
+            if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+                POPPLER_HAS_OPTCONTENT=yes
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+            else
+                { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+            fi
 
-            # And now we check if we have Poppler >= 0.20.0
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have Poppler >= 0.20.0" >&5
-$as_echo_n "checking if we have Poppler >= 0.20.0... " >&6; }
+            # And now we check if we have Poppler >= 0.16.0
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking if BaseStream constructor needs 2 arguments" >&5
+$as_echo_n "checking if BaseStream constructor needs 2 arguments... " >&6; }
             rm -f testpoppler.*
-            echo '#include <poppler/Error.h>' > testpoppler.cpp
-            echo 'int main(int argc, char** argv) { setErrorCallback(0,0); return 0; }' >> testpoppler.cpp
+            echo '#include <poppler/Object.h>' > testpoppler.cpp
+            echo '#include <poppler/Stream.h>' >> testpoppler.cpp
+            echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
+            echo 'public:' >> testpoppler.cpp
+            echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
+            echo '};' >> testpoppler.cpp
+            echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
             if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-                POPPLER_0_20_OR_LATER=yes
+                POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
                 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
 
-                # And now we check if we have Poppler >= 0.23.0
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have Poppler >= 0.23.0" >&5
-$as_echo_n "checking if we have Poppler >= 0.23.0... " >&6; }
+                # And now we check if we have Poppler >= 0.20.0
+                { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have Poppler >= 0.20.0" >&5
+$as_echo_n "checking if we have Poppler >= 0.20.0... " >&6; }
                 rm -f testpoppler.*
-                echo '#include <poppler/Object.h>' > testpoppler.cpp
-                echo '#include <poppler/Stream.h>' >> testpoppler.cpp
-                echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
-                echo 'public:' >> testpoppler.cpp
-                echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
-                echo '  ~TestStream() {}' >> testpoppler.cpp
-                echo '  virtual BaseStream *copy() { return BaseStream::copy(); }' >> testpoppler.cpp
-                echo '};' >> testpoppler.cpp
-                echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
+                echo '#include <poppler/Error.h>' > testpoppler.cpp
+                echo 'int main(int argc, char** argv) { setErrorCallback(0,0); return 0; }' >> testpoppler.cpp
                 if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-                    POPPLER_0_23_OR_LATER=yes
+                    POPPLER_0_20_OR_LATER=yes
                     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 $as_echo "yes" >&6; }
+
+                    # And now we check if we have Poppler >= 0.23.0
+                    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have Poppler >= 0.23.0" >&5
+$as_echo_n "checking if we have Poppler >= 0.23.0... " >&6; }
+                    rm -f testpoppler.*
+                    echo '#include <poppler/Object.h>' > testpoppler.cpp
+                    echo '#include <poppler/Stream.h>' >> testpoppler.cpp
+                    echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
+                    echo 'public:' >> testpoppler.cpp
+                    echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
+                    echo '  ~TestStream() {}' >> testpoppler.cpp
+                    echo '  virtual BaseStream *copy() { return BaseStream::copy(); }' >> testpoppler.cpp
+                    echo '};' >> testpoppler.cpp
+                    echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
+                    if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+                        POPPLER_0_23_OR_LATER=yes
+                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+                    else
+                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                    fi
+
                 else
                     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
@@ -32318,10 +32414,6 @@ $as_echo "no" >&6; }
                 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
             fi
-
-        else
-            { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
         fi
     else
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -32344,6 +32436,8 @@ POPPLER_0_20_OR_LATER=$POPPLER_0_20_OR_LATER
 
 POPPLER_0_23_OR_LATER=$POPPLER_0_23_OR_LATER
 
+POPPLER_0_58_OR_LATER=$POPPLER_0_58_OR_LATER
+
 POPPLER_INC=$POPPLER_INC
 
 POPPLER_PLUGIN_LIB=$POPPLER_PLUGIN_LIB
diff --git a/configure.ac b/configure.ac
index 0a53d88..38adcf4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 dnl ***************************************************************************
-dnl $Id: configure.ac 39012 2017-06-09 10:08:43Z rouault $
+dnl $Id: configure.ac 40036 2017-09-08 11:23:21Z rouault $
 dnl
 dnl Project:  GDAL
 dnl Purpose:  Configure source file.
@@ -2539,10 +2539,11 @@ if test "$with_openjpeg" = "no" ; then
 
 elif test "$with_openjpeg" = "yes" -o "$with_openjpeg" = "" ; then
 
-  AC_CHECK_HEADERS([openjpeg-2.0/openjpeg.h])
-  if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
+  AC_CHECK_HEADERS([openjpeg-2.2/openjpeg.h])
+  if test "$ac_cv_header_openjpeg_2_2_openjpeg_h" = "yes"; then
     AC_CHECK_LIB(openjp2,opj_stream_set_user_data_length,HAVE_OPENJPEG=yes,HAVE_OPENJPEG=no,)
     if test "$HAVE_OPENJPEG" = "yes"; then
+        OPENJPEG_VERSION=20200
         LIBS="-lopenjp2 $LIBS"
     fi
   else
@@ -2553,6 +2554,14 @@ elif test "$with_openjpeg" = "yes" -o "$with_openjpeg" = "" ; then
             OPENJPEG_VERSION=20100
             LIBS="-lopenjp2 $LIBS"
         fi
+    else
+        AC_CHECK_HEADERS([openjpeg-2.0/openjpeg.h])
+        if test "$ac_cv_header_openjpeg_2_0_openjpeg_h" = "yes"; then
+            AC_CHECK_LIB(openjp2,opj_stream_set_user_data_length,HAVE_OPENJPEG=yes,HAVE_OPENJPEG=no,)
+            if test "$HAVE_OPENJPEG" = "yes"; then
+                LIBS="-lopenjp2 $LIBS"
+            fi
+        fi
     fi
   fi
 else
@@ -2563,8 +2572,11 @@ else
   elif test -r $with_openjpeg/include/openjpeg-2.1/openjpeg.h ; then
     OPENJPEG_VERSION=20100
     EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
+  elif test -r $with_openjpeg/include/openjpeg-2.2/openjpeg.h ; then
+    OPENJPEG_VERSION=20200
+    EXTRA_INCLUDES="-I$with_openjpeg/include $EXTRA_INCLUDES"
   else
-    AC_MSG_ERROR([openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1])
+    AC_MSG_ERROR([openjpeg.h not found in $with_openjpeg/include/openjpeg-2.0 or $with_openjpeg/include/openjpeg-2.1 or $with_openjpeg/include/openjpeg-2.2])
   fi
 
   AC_CHECK_LIB(openjp2,opj_stream_set_user_data_length,HAVE_OPENJPEG=yes,HAVE_OPENJPEG=no,-L$with_openjpeg/lib)
@@ -4271,6 +4283,8 @@ HAVE_POPPLER=no
 POPPLER_HAS_OPTCONTENT=no
 POPPLER_BASE_STREAM_HAS_TWO_ARGS=no
 POPPLER_0_20_OR_LATER=no
+POPPLER_0_23_OR_LATER=no
+POPPLER_0_58_OR_LATER=no
 
 AC_MSG_CHECKING([for poppler])
 
@@ -4309,59 +4323,84 @@ if test "$with_poppler" != "no" -a "$with_poppler" != ""; then
         POPPLER_INC=$TEST_POPPLER_INC
         POPPLER_PLUGIN_LIB="${TEST_POPPLER_LIB}"
 
-        # And now try another dirty thing, but this one is
-        # optional.
-        AC_MSG_CHECKING([if Catalog::optContent exists])
+        CHECK_OTHER_POPPLER_VERSION=yes
+
+        # And now we check if we have Poppler >= 0.58.0
+        AC_MSG_CHECKING([if Object does have new API (>= 0.58.0)])
         rm -f testpoppler.*
-        echo '#define private public' > testpoppler.cpp
-        echo '#include <poppler/Object.h>' >> testpoppler.cpp
-        echo '#include <poppler/Catalog.h>' >> testpoppler.cpp
-        echo 'int main(int argc, char** argv) { return &(((Catalog*)0x8000)->optContent) == 0; }' >> testpoppler.cpp
+        echo '#include <poppler/Object.h>' > testpoppler.cpp
+        echo 'int main(int argc, char** argv) { Object o(objNull); return 0; }' >> testpoppler.cpp
         if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+            POPPLER_0_58_OR_LATER=yes
+            POPPLER_0_23_OR_LATER=yes
+            POPPLER_0_20_OR_LATER=yes
+            POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
             POPPLER_HAS_OPTCONTENT=yes
+            CHECK_OTHER_POPPLER_VERSION=no
             AC_MSG_RESULT([yes])
         else
             AC_MSG_RESULT([no])
         fi
 
-        # And now we check if we have Poppler >= 0.16.0
-        AC_MSG_CHECKING([if BaseStream constructor needs 2 arguments])
-        rm -f testpoppler.*
-        echo '#include <poppler/Object.h>' > testpoppler.cpp
-        echo '#include <poppler/Stream.h>' >> testpoppler.cpp
-        echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
-        echo 'public:' >> testpoppler.cpp
-        echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
-        echo '};' >> testpoppler.cpp
-        echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
-        if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-            POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
-            AC_MSG_RESULT([yes])
+        if test "$CHECK_OTHER_POPPLER_VERSION" = "yes"; then
 
-            # And now we check if we have Poppler >= 0.20.0
-            AC_MSG_CHECKING([if we have Poppler >= 0.20.0])
+            # And now try another dirty thing, but this one is
+            # optional.
+            AC_MSG_CHECKING([if Catalog::optContent exists])
             rm -f testpoppler.*
-            echo '#include <poppler/Error.h>' > testpoppler.cpp
-            echo 'int main(int argc, char** argv) { setErrorCallback(0,0); return 0; }' >> testpoppler.cpp
+            echo '#define private public' > testpoppler.cpp
+            echo '#include <poppler/Object.h>' >> testpoppler.cpp
+            echo '#include <poppler/Catalog.h>' >> testpoppler.cpp
+            echo 'int main(int argc, char** argv) { return &(((Catalog*)0x8000)->optContent) == 0; }' >> testpoppler.cpp
             if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-                POPPLER_0_20_OR_LATER=yes
+                POPPLER_HAS_OPTCONTENT=yes
+                AC_MSG_RESULT([yes])
+            else
+                AC_MSG_RESULT([no])
+            fi
+
+            # And now we check if we have Poppler >= 0.16.0
+            AC_MSG_CHECKING([if BaseStream constructor needs 2 arguments])
+            rm -f testpoppler.*
+            echo '#include <poppler/Object.h>' > testpoppler.cpp
+            echo '#include <poppler/Stream.h>' >> testpoppler.cpp
+            echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
+            echo 'public:' >> testpoppler.cpp
+            echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
+            echo '};' >> testpoppler.cpp
+            echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
+            if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+                POPPLER_BASE_STREAM_HAS_TWO_ARGS=yes
                 AC_MSG_RESULT([yes])
 
-                # And now we check if we have Poppler >= 0.23.0
-                AC_MSG_CHECKING([if we have Poppler >= 0.23.0])
+                # And now we check if we have Poppler >= 0.20.0
+                AC_MSG_CHECKING([if we have Poppler >= 0.20.0])
                 rm -f testpoppler.*
-                echo '#include <poppler/Object.h>' > testpoppler.cpp
-                echo '#include <poppler/Stream.h>' >> testpoppler.cpp
-                echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
-                echo 'public:' >> testpoppler.cpp
-                echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
-                echo '  ~TestStream() {}' >> testpoppler.cpp
-                echo '  virtual BaseStream *copy() { return BaseStream::copy(); }' >> testpoppler.cpp
-                echo '};' >> testpoppler.cpp
-                echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
+                echo '#include <poppler/Error.h>' > testpoppler.cpp
+                echo 'int main(int argc, char** argv) { setErrorCallback(0,0); return 0; }' >> testpoppler.cpp
                 if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
-                    POPPLER_0_23_OR_LATER=yes
+                    POPPLER_0_20_OR_LATER=yes
                     AC_MSG_RESULT([yes])
+
+                    # And now we check if we have Poppler >= 0.23.0
+                    AC_MSG_CHECKING([if we have Poppler >= 0.23.0])
+                    rm -f testpoppler.*
+                    echo '#include <poppler/Object.h>' > testpoppler.cpp
+                    echo '#include <poppler/Stream.h>' >> testpoppler.cpp
+                    echo 'class TestStream: public BaseStream {' >> testpoppler.cpp
+                    echo 'public:' >> testpoppler.cpp
+                    echo '  TestStream() : BaseStream(0,0) {}' >> testpoppler.cpp
+                    echo '  ~TestStream() {}' >> testpoppler.cpp
+                    echo '  virtual BaseStream *copy() { return BaseStream::copy(); }' >> testpoppler.cpp
+                    echo '};' >> testpoppler.cpp
+                    echo 'int main(int argc, char** argv) { return 0; }' >> testpoppler.cpp
+                    if test -z "`${CXX} testpoppler.cpp -c ${POPPLER_INC} 2>&1`" ; then
+                        POPPLER_0_23_OR_LATER=yes
+                        AC_MSG_RESULT([yes])
+                    else
+                        AC_MSG_RESULT([no])
+                    fi
+
                 else
                     AC_MSG_RESULT([no])
                 fi
@@ -4369,9 +4408,6 @@ if test "$with_poppler" != "no" -a "$with_poppler" != ""; then
             else
                 AC_MSG_RESULT([no])
             fi
-
-        else
-            AC_MSG_RESULT([no])
         fi
     else
         AC_MSG_RESULT([no])
@@ -4387,6 +4423,7 @@ AC_SUBST(POPPLER_HAS_OPTCONTENT, $POPPLER_HAS_OPTCONTENT)
 AC_SUBST(POPPLER_BASE_STREAM_HAS_TWO_ARGS, $POPPLER_BASE_STREAM_HAS_TWO_ARGS)
 AC_SUBST(POPPLER_0_20_OR_LATER, $POPPLER_0_20_OR_LATER)
 AC_SUBST(POPPLER_0_23_OR_LATER, $POPPLER_0_23_OR_LATER)
+AC_SUBST(POPPLER_0_58_OR_LATER, $POPPLER_0_58_OR_LATER)
 AC_SUBST(POPPLER_INC, $POPPLER_INC)
 AC_SUBST(POPPLER_PLUGIN_LIB, $POPPLER_PLUGIN_LIB)
 
diff --git a/frmts/georaster/georaster_dataset.cpp b/frmts/georaster/georaster_dataset.cpp
index dd978fe..c4aee69 100644
--- a/frmts/georaster/georaster_dataset.cpp
+++ b/frmts/georaster/georaster_dataset.cpp
@@ -40,7 +40,7 @@
 
 #include "georaster_priv.h"
 
-CPL_CVSID("$Id: georaster_dataset.cpp 38222 2017-05-11 20:37:34Z rouault $");
+CPL_CVSID("$Id: georaster_dataset.cpp 39643 2017-07-24 15:25:46Z ilucena $")
 
 //  ---------------------------------------------------------------------------
 //                                                           GeoRasterDataset()
@@ -59,8 +59,6 @@ GeoRasterDataset::GeoRasterDataset()
     adfGeoTransform[4]  = 0.0;
     adfGeoTransform[5]  = 1.0;
     pszProjection       = NULL;
-    nGCPCount           = 0;
-    pasGCPList          = NULL;
     poMaskBand          = NULL;
     bApplyNoDataArray   = false;
     poJP2Dataset        = NULL;
@@ -74,11 +72,7 @@ GeoRasterDataset::~GeoRasterDataset()
 {
     FlushCache();
 
-    if( nGCPCount > 0 )
-    {
-        GDALDeinitGCPs( nGCPCount, pasGCPList );
-        CPLFree( pasGCPList );
-    }
+    poGeoRaster->FlushMetadata();
 
     delete poGeoRaster;
 
@@ -630,8 +624,7 @@ boolean GeoRasterDataset::JP2_CopyDirect( const char* pszJP2Filename,
                           "amount read differs from JP2 Box data length" );
             }
 
-            nLBox = (int) nDataLength + 8;
-            nLBox = CPL_MSBWORD32( nLBox );
+            nLBox = CPL_MSBWORD32( (int) nDataLength + 8 );
 
             memcpy( &nTBox, oBox.GetType(), 4 );
 
@@ -646,8 +639,7 @@ boolean GeoRasterDataset::JP2_CopyDirect( const char* pszJP2Filename,
             size_t nSize = 0;
             size_t nDataLength = oBox.GetDataLength();
  
-            nLBox = (int) nDataLength + 8;
-            nLBox = CPL_MSBWORD32( nLBox );
+            nLBox = CPL_MSBWORD32( (int) nDataLength + 8 );
 
             memcpy( &nTBox, oBox.GetType(), 4 );
 
@@ -1353,6 +1345,17 @@ GDALDataset *GeoRasterDataset::CreateCopy( const char* pszFilename,
     }
 
     // --------------------------------------------------------------------
+    //      Copy GCPs
+    // --------------------------------------------------------------------
+
+    if( poSrcDS->GetGCPCount() > 0 )
+    {
+        poDstDS->SetGCPs( poSrcDS->GetGCPCount(), 
+                          poSrcDS->GetGCPs(), 
+                          poSrcDS->GetGCPProjection() );
+    }
+
+    // --------------------------------------------------------------------
     //      Copy RPC
     // --------------------------------------------------------------------
 
@@ -2605,23 +2608,55 @@ void GeoRasterDataset::SetSubdatasets( GeoRasterWrapper* poGRW )
     }
 }
 
+int GeoRasterDataset::GetGCPCount()
+{
+    if ( poGeoRaster )
+    {
+        return poGeoRaster->nGCPCount;
+    }
+
+    return 0;
+}
+
 //  ---------------------------------------------------------------------------
 //                                                                    SetGCPs()
 //  ---------------------------------------------------------------------------
 
-CPLErr GeoRasterDataset::SetGCPs( int, const GDAL_GCP *, const char * )
+CPLErr GeoRasterDataset::SetGCPs( int nGCPCountIn, const GDAL_GCP *pasGCPListIn,
+                                  const char *pszGCPProjection )
 {
+    if( GetAccess() == GA_Update )
+    {
+        poGeoRaster->SetGCP( nGCPCountIn, pasGCPListIn );
+        SetProjection( pszGCPProjection ); 
+    }
+    else
+    {
+        CPLError(CE_Failure, CPLE_NotSupported,
+                 "SetGCPs() is only supported on GeoRaster insert or update.");
+        return CE_Failure;
+    }
+
     return CE_None;
 }
 
+const GDAL_GCP* GeoRasterDataset::GetGCPs()
+{
+    if( poGeoRaster->nGCPCount > 0 && poGeoRaster->pasGCPList )
+    {
+        return poGeoRaster->pasGCPList;
+    }
+
+    return NULL;
+}
+
 //  ---------------------------------------------------------------------------
 //                                                           GetGCPProjection()
 //  ---------------------------------------------------------------------------
 
 const char* GeoRasterDataset::GetGCPProjection()
-
 {
-    if( nGCPCount > 0 )
+    if( poGeoRaster && poGeoRaster->nGCPCount > 0 )
         return pszProjection;
     else
         return "";
diff --git a/frmts/georaster/georaster_priv.h b/frmts/georaster/georaster_priv.h
index 20192f1..865f810 100644
--- a/frmts/georaster/georaster_priv.h
+++ b/frmts/georaster/georaster_priv.h
@@ -56,7 +56,7 @@ void jpeg_vsiio_src (j_decompress_ptr cinfo, VSILFILE * infile);
 void jpeg_vsiio_dest (j_compress_ptr cinfo, VSILFILE * outfile);
 
 //  ---------------------------------------------------------------------------
-//  JPEG2000 support - Install the Vitual File System handler to OCI LOB
+//  JPEG2000 support - Install the Virtual File System handler to OCI LOB
 //  ---------------------------------------------------------------------------
 
 CPL_C_START
@@ -152,8 +152,6 @@ private:
     char*               pszProjection;
     char**              papszSubdatasets;
     double              adfGeoTransform[6];
-    int                 nGCPCount;
-    GDAL_GCP*           pasGCPList;
     GeoRasterRasterBand*
                         poMaskBand;
     bool                bApplyNoDataArray;
@@ -207,10 +205,10 @@ public:
                             GSpacing nPixelSpace, GSpacing nLineSpace,
                             GSpacing nBandSpace,
                             GDALRasterIOExtraArg* psExtraArg ) override;
-    virtual int         GetGCPCount() override { return nGCPCount; }
+    virtual int         GetGCPCount() override;
     virtual const char* GetGCPProjection() override;
     virtual const GDAL_GCP*
-                        GetGCPs() override { return pasGCPList; }
+                        GetGCPs() override;
     virtual CPLErr      SetGCPs(
                             int nGCPCount,
                             const GDAL_GCP *pasGCPList,
@@ -224,9 +222,9 @@ public:
                             GDALProgressFunc pfnProgress,
                             void* pProgresoversData ) override;
     virtual CPLErr      CreateMaskBand( int nFlags ) override;
-    virtual OGRErr      StartTransaction(int /* bForce */ =FALSE) override {return CE_None;};
-    virtual OGRErr      CommitTransaction() override {return CE_None;};
-    virtual OGRErr      RollbackTransaction() override {return CE_None;};
+    virtual OGRErr      StartTransaction(int /* bForce */ =FALSE) override {return CE_None;}
+    virtual OGRErr      CommitTransaction() override {return CE_None;}
+    virtual OGRErr      RollbackTransaction() override {return CE_None;}
     
     virtual char**      GetFileList() override;
 
@@ -347,7 +345,6 @@ private:
     void                InitializeLayersNode();
     bool                InitializeIO();
     void                InitializeLevel( int nLevel );
-    bool                FlushMetadata();
 
     void                LoadNoDataValues();
 
@@ -366,6 +363,12 @@ private:
 
 public:
 
+    int                 nGCPCount;
+    GDAL_GCP*           pasGCPList;
+    bool                bFlushGCP;
+    void                FlushGCP();
+
+    bool                FlushMetadata();
     static char**       ParseIdentificator( const char* pszStringID );
     static GeoRasterWrapper*
                         Open(
@@ -421,7 +424,7 @@ public:
     bool                FlushBlock( long nCacheBlock );
     bool                GetNoData( int nLayer, double* pdfNoDataValue );
     bool                SetNoData( int nLayer, const char* pszValue );
-    CPLXMLNode*         GetMetadata() { return phMetadata; };
+    CPLXMLNode*         GetMetadata() { return phMetadata; }
     bool                SetVAT( int nBand, const char* pszName );
     char*               GetVAT( int nBand );
     bool                GeneratePyramid(
@@ -436,10 +439,12 @@ public:
                                                 int nColumnBlocks,
                                                 int nRowBlocks,
                                                 int nBandBlocks );
-    void                SetWriteOnly( bool value ) { bWriteOnly = value; };
+    void                SetWriteOnly( bool value ) { bWriteOnly = value; }
     void                SetRPC();
     void                SetMaxLevel( int nMaxLevel );
     void                GetRPC();
+    void                GetGCP();
+    void                SetGCP( int nGCPCountIn, const GDAL_GCP *pasGCPListIn );
 
 public:
 
diff --git a/frmts/georaster/georaster_wrapper.cpp b/frmts/georaster/georaster_wrapper.cpp
index cc72cc5..117935a 100644
--- a/frmts/georaster/georaster_wrapper.cpp
+++ b/frmts/georaster/georaster_wrapper.cpp
@@ -34,7 +34,7 @@
 #include "cpl_string.h"
 #include "cpl_minixml.h"
 
-CPL_CVSID("$Id: georaster_wrapper.cpp 38500 2017-05-19 19:21:32Z ilucena $");
+CPL_CVSID("$Id: georaster_wrapper.cpp 39643 2017-07-24 15:25:46Z ilucena $")
 
 //  ---------------------------------------------------------------------------
 //                                                           GeoRasterWrapper()
@@ -106,6 +106,9 @@ GeoRasterWrapper::GeoRasterWrapper() :
     anULTCoordinate[0]  = 0;
     anULTCoordinate[1]  = 0;
     anULTCoordinate[2]  = 0;
+    pasGCPList          = NULL;
+    nGCPCount           = 0;
+    bFlushGCP           = false;
 }
 
 //  ---------------------------------------------------------------------------
@@ -126,6 +129,15 @@ GeoRasterWrapper::~GeoRasterWrapper()
     CPLFree( pabyCompressBuf );
     CPLFree( pahLevels );
 
+    if( bFlushGCP )
+    {
+        FlushGCP();
+        GDALDeinitGCPs( nGCPCount, pasGCPList );
+        CPLFree( pasGCPList );
+        pasGCPList = NULL;
+        nGCPCount = 0;
+    }
+
     if( CPLListCount( psNoDataList ) )
     {
         CPLList* psList = NULL;
@@ -244,7 +256,7 @@ GeoRasterWrapper* GeoRasterWrapper::Open( const char* pszStringId, bool bUpdate
         strlen( papszParam[1] ) == 0 &&
         strlen( papszParam[2] ) == 0 )
     {
-        /* In an external procedure environment, before openning any
+        /* In an external procedure environment, before opening any
          * dataset, the caller must pass the with_context as an
          * string metadata item OCI_CONTEXT_PTR to the driver. */ 
 
@@ -1346,12 +1358,22 @@ void GeoRasterWrapper::GetRasterInfo( void )
     //  Check for RPCs
     //  -------------------------------------------------------------------
 
-    const char* pszModelType = CPLGetXMLValue( phMetadata,
-                               "spatialReferenceInfo.modelType", "None" );
+    CPLXMLNode* phModelType = CPLGetXMLNode( phMetadata,
+        "spatialReferenceInfo.modelType");
 
-    if( EQUAL( pszModelType, "FunctionalFitting" ) )
+    for( int n = 1 ; phModelType ; phModelType = phModelType->psNext, n++ )
     {
-        GetRPC();
+        const char* pszModelType = CPLGetXMLValue( phModelType, ".", "None" );
+
+        if( EQUAL( pszModelType, "StoredFunction" ) )
+        {
+            GetGCP();
+        }
+
+        if( EQUAL( pszModelType, "FunctionalFitting" ) )
+        {
+            GetRPC();
+        }
     }
 
     //  -------------------------------------------------------------------
@@ -2407,6 +2429,180 @@ void GeoRasterWrapper::GetSpatialReference()
 }
 
 //  ---------------------------------------------------------------------------
+//                                                                     GetGCP()
+//  ---------------------------------------------------------------------------
+
+void GeoRasterWrapper::GetGCP()
+{
+    CPLXMLNode* psGCP = CPLGetXMLNode( phMetadata, 
+                "spatialReferenceInfo.gcpGeoreferenceModel.gcp" );
+
+    CPLXMLNode* psFirst = psGCP;
+
+    if( nGCPCount > 0 && pasGCPList )
+    {
+        GDALDeinitGCPs( nGCPCount, pasGCPList );
+        CPLFree( pasGCPList );
+    }
+
+    pasGCPList = NULL;
+    nGCPCount = 0;
+
+    for( int i = 1 ; psGCP ; psGCP = psGCP->psNext, i++ )
+    {
+        if( ! EQUAL( CPLGetXMLValue( psGCP, "type",  "" ), "ControlPoint" ) )
+        {
+            continue;
+        }
+        nGCPCount++;
+    }
+
+    pasGCPList = static_cast<GDAL_GCP *>(
+            CPLCalloc(sizeof(GDAL_GCP), nGCPCount) );
+
+    psGCP = psFirst;
+
+    for( int i = 0 ; psGCP ; psGCP = psGCP->psNext, i++ )
+    {
+        if( ! EQUAL( CPLGetXMLValue( psGCP, "type",  "" ), "ControlPoint" ) )
+        {
+            continue;
+        }
+        pasGCPList[i].pszId    = CPLStrdup( CPLGetXMLValue( psGCP, "ID", "" ) );
+        pasGCPList[i].pszInfo  = CPLStrdup( "" );
+        pasGCPList[i].dfGCPLine  = CPLAtof( CPLGetXMLValue( psGCP, "row", "0.0" ) );
+        pasGCPList[i].dfGCPPixel = CPLAtof( CPLGetXMLValue( psGCP, "column", "0.0" ) );
+        pasGCPList[i].dfGCPX     = CPLAtof( CPLGetXMLValue( psGCP, "X", "0.0" ) );
+        pasGCPList[i].dfGCPY     = CPLAtof( CPLGetXMLValue( psGCP, "Y", "0.0" ) );
+        pasGCPList[i].dfGCPZ     = CPLAtof( CPLGetXMLValue( psGCP, "Z", "0.0" ));
+    }
+}
+
+//  ---------------------------------------------------------------------------
+//                                                                     SetGCP()
+//  ---------------------------------------------------------------------------
+
+void GeoRasterWrapper::SetGCP( int nGCPCountIn, const GDAL_GCP *pasGCPListIn)
+{
+    if( nGCPCount > 0 )
+    {
+        GDALDeinitGCPs( nGCPCount, pasGCPList );
+        CPLFree( pasGCPList );
+    }
+
+    nGCPCount  = nGCPCountIn;
+    pasGCPList = GDALDuplicateGCPs(nGCPCount, pasGCPListIn);
+    bFlushGCP  = true;
+}
+
+void GeoRasterWrapper::FlushGCP()
+{
+    const char* pszStatement = CPLSPrintf(
+        "DECLARE\n"
+        "  gr   sdo_georaster;\n"
+        "BEGIN\n"
+        "  SELECT %s INTO gr FROM %s%s t WHERE %s FOR UPDATE;\n",
+            sColumn.c_str(),
+            sSchema.c_str(),
+            sTable.c_str(),
+            sWhere.c_str());
+
+    int nDimns = 2;
+
+    for( int iGCP = 0; iGCP < nGCPCount; ++iGCP )
+    {
+        if( pasGCPList[iGCP].dfGCPZ != 0.0 )
+        {
+            nDimns = 3;
+            break;
+        }
+    }
+
+    if ( nDimns == 3 )
+    {
+        pszStatement = CPLSPrintf(
+            "%s"
+            "  sdo_geor.setControlPoint(gr,\n"
+            "    SDO_GEOR_GCP(TO_CHAR(:1), '', 1,\n"
+            "      2, sdo_number_array(:2, :3),\n"
+            "      3, sdo_number_array(:4, :5, :6),\n"
+            "      NULL, NULL));\n",
+            pszStatement);
+    }
+    else
+    {
+        pszStatement = CPLSPrintf(
+            "%s"
+            "  sdo_geor.setControlPoint(gr,\n"
+            "    SDO_GEOR_GCP(TO_CHAR(:1), '', 1,\n"
+            "      2, sdo_number_array(:2, :3),\n"
+            "      2, sdo_number_array(:4, :5),\n"
+            "      NULL, NULL));\n",
+            pszStatement);
+    }
+
+    pszStatement = CPLSPrintf(
+            "%s"
+            "  UPDATE %s%s t SET %s = gr WHERE %s;\n"
+            "END;\n",
+            pszStatement,
+            sSchema.c_str(),
+            sTable.c_str(),
+            sColumn.c_str(),
+            sWhere.c_str());
+
+    OWStatement* poStmt = poConnection->CreateStatement( pszStatement );
+
+    long   lBindN = 0L;
+    double dBindL = 0.0;
+    double dBindP = 0.0;
+    double dBindX = 0.0;
+    double dBindY = 0.0;
+    double dBindZ = 0.0;
+
+    poStmt->Bind( &lBindN );
+    poStmt->Bind( &dBindL );
+    poStmt->Bind( &dBindP );
+    poStmt->Bind( &dBindX );
+    poStmt->Bind( &dBindY );
+
+    if ( nDimns == 3 )
+    {
+        poStmt->Bind( &dBindZ );
+    }
+
+    for( int iGCP = 0; iGCP < nGCPCount; ++iGCP )
+    {
+
+        // Assign bound variables
+
+        lBindN = iGCP + 1;
+        dBindL = pasGCPList[iGCP].dfGCPLine;
+        dBindP = pasGCPList[iGCP].dfGCPPixel;
+        dBindX = pasGCPList[iGCP].dfGCPX;
+        dBindY = pasGCPList[iGCP].dfGCPY;
+        dBindZ = nDimns == 3 ? pasGCPList[iGCP].dfGCPZ : 0.0;
+
+        // To avoid cppcheck false positive complaints about unreadVariable
+        CPL_IGNORE_RET_VAL(lBindN);
+        CPL_IGNORE_RET_VAL(dBindL);
+        CPL_IGNORE_RET_VAL(dBindP);
+        CPL_IGNORE_RET_VAL(dBindX);
+        CPL_IGNORE_RET_VAL(dBindY);
+        CPL_IGNORE_RET_VAL(dBindZ);
+
+        // Consume bound values
+
+        if( ! poStmt->Execute() )
+        {
+            CPLError( CE_Failure, CPLE_AppDefined, "Error loading GCP.");
+        }
+    }
+
+    delete poStmt;
+}
+
+//  ---------------------------------------------------------------------------
 //                                                                     GetRPC()
 //  ---------------------------------------------------------------------------
 
@@ -2428,14 +2624,6 @@ void GeoRasterWrapper::GetRPC()
         return;
     }
 
-    const char* pszModelType = CPLGetXMLValue( phMetadata,
-                               "spatialReferenceInfo.modelType", "None" );
-
-    if( EQUAL( pszModelType, "FunctionalFitting" ) == false )
-    {
-        return;
-    }
-
     CPLXMLNode* phPolyModel = CPLGetXMLNode( phSRSInfo, "polynomialModel" );
 
     if ( phPolyModel == NULL )
diff --git a/frmts/grib/degrib18/g2clib-1.0.4/dec_jpeg2000.cpp b/frmts/grib/degrib18/g2clib-1.0.4/dec_jpeg2000.cpp
index 3dfca90..66646ee 100644
--- a/frmts/grib/degrib18/g2clib-1.0.4/dec_jpeg2000.cpp
+++ b/frmts/grib/degrib18/g2clib-1.0.4/dec_jpeg2000.cpp
@@ -1,3 +1,8 @@
+#ifndef __STDC_LIMIT_MACROS
+// Needed on RHEL 6 for SIZE_MAX availability, needed by Jasper
+#define __STDC_LIMIT_MACROS 1
+#endif
+
 #include <cpl_port.h>
 
 #include <stdio.h>
diff --git a/frmts/gsg/gsagdataset.cpp b/frmts/gsg/gsagdataset.cpp
index a38fcaa..9e419cc 100644
--- a/frmts/gsg/gsagdataset.cpp
+++ b/frmts/gsg/gsagdataset.cpp
@@ -38,7 +38,7 @@
 #include "gdal_frmts.h"
 #include "gdal_pam.h"
 
-CPL_CVSID("$Id: gsagdataset.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: gsagdataset.cpp 39765 2017-08-07 11:11:09Z rouault $");
 
 #ifndef DBL_MAX
 # ifdef __DBL_MAX__
@@ -355,6 +355,9 @@ CPLErr GSAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     char *szEnd = szStart;
     for( int iCell=0; iCell<nBlockXSize; szStart = szEnd )
     {
+        while( isspace( (unsigned char)*szStart ) )
+            szStart++;
+
         double dfValue = CPLStrtod( szStart, &szEnd );
         if( szStart == szEnd )
         {
@@ -369,8 +372,6 @@ CPLErr GSAGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
             }
 
             /* Check if this was an expected failure */
-            while( isspace( (unsigned char)*szStart ) )
-                szStart++;
 
             /* Found sign at end of input, seek back to re-read it */
             bool bOnlySign = false;
diff --git a/frmts/gtiff/geotiff.cpp b/frmts/gtiff/geotiff.cpp
index 59e0756..d7d717c 100644
--- a/frmts/gtiff/geotiff.cpp
+++ b/frmts/gtiff/geotiff.cpp
@@ -106,7 +106,7 @@
 #include "xtiffio.h"
 
 
-CPL_CVSID("$Id: geotiff.cpp 39129 2017-06-15 10:32:38Z rouault $");
+CPL_CVSID("$Id: geotiff.cpp 39804 2017-08-13 13:15:08Z rouault $");
 
 #if SIZEOF_VOIDP == 4
 static bool bGlobalStripIntegerOverflow = false;
@@ -778,11 +778,16 @@ CPLErr GTiffJPEGOverviewBand::IReadBlock( int nBlockXOff, int nBlockYOff,
 
     // Compute the source block ID.
     int nBlockId = 0;
-    if( nBlockYSize != 1 )
-    {
-        nBlocksPerRow = DIV_ROUND_UP(poGDS->poParentDS->nRasterXSize,
+    int nParentBlockXSize, nParentBlockYSize;
+    poGDS->poParentDS->GetRasterBand(1)->
+        GetBlockSize(&nParentBlockXSize, &nParentBlockYSize);
+    const bool bIsSingleStripAsSplit = (nParentBlockYSize == 1 &&
+                           poGDS->poParentDS->nBlockYSize != nParentBlockYSize);
+    if( !bIsSingleStripAsSplit )
+    {
+        int l_nBlocksPerRow = DIV_ROUND_UP(poGDS->poParentDS->nRasterXSize,
                                                poGDS->poParentDS->nBlockXSize);
-        nBlockId = nBlockYOff * nBlocksPerRow + nBlockXOff;
+        nBlockId = nBlockYOff * l_nBlocksPerRow + nBlockXOff;
     }
     if( poGDS->poParentDS->nPlanarConfig == PLANARCONFIG_SEPARATE )
     {
@@ -813,7 +818,7 @@ CPLErr GTiffJPEGOverviewBand::IReadBlock( int nBlockXOff, int nBlockYOff,
         // Special case for last strip that might be smaller than other strips
         // In which case we must invalidate the dataset.
         TIFF* hTIFF = poGDS->poParentDS->hTIFF;
-        if( !TIFFIsTiled( hTIFF ) && poGDS->poParentDS->nBlockYSize > 1 &&
+        if( !TIFFIsTiled( hTIFF ) && !bIsSingleStripAsSplit &&
             (nBlockYOff + 1 ==
                  DIV_ROUND_UP( poGDS->poParentDS->nRasterYSize,
                                poGDS->poParentDS->nBlockYSize ) ||
@@ -972,7 +977,7 @@ CPLErr GTiffJPEGOverviewBand::IReadBlock( int nBlockXOff, int nBlockYOff,
         int nReqYOff = 0;
         int nReqXSize = 0;
         int nReqYSize = 0;
-        if( nBlockYSize == 1 )
+        if( bIsSingleStripAsSplit )
         {
             nReqYOff = nBlockYOff * nScaleFactor;
             nReqXSize = l_poDS->GetRasterXSize();
@@ -980,22 +985,48 @@ CPLErr GTiffJPEGOverviewBand::IReadBlock( int nBlockXOff, int nBlockYOff,
         }
         else
         {
-            nReqXSize = nBlockXSize * nScaleFactor;
+            if( nBlockXSize == poGDS->GetRasterXSize() )
+            {
+                nReqXSize = l_poDS->GetRasterXSize();
+            }
+            else
+            {
+                nReqXSize = nBlockXSize * nScaleFactor;
+            }
             nReqYSize = nBlockYSize * nScaleFactor;
         }
         int nBufXSize = nBlockXSize;
         int nBufYSize = nBlockYSize;
+        if( nBlockXOff == DIV_ROUND_UP(poGDS->poParentDS->nRasterXSize,
+                                       poGDS->poParentDS->nBlockXSize) - 1 )
+        {
+            nReqXSize = poGDS->poParentDS->nRasterXSize -
+                                nBlockXOff * poGDS->poParentDS->nBlockXSize;
+        }
         if( nReqXOff + nReqXSize > l_poDS->GetRasterXSize() )
         {
             nReqXSize = l_poDS->GetRasterXSize() - nReqXOff;
-            nBufXSize = nReqXSize / nScaleFactor;
-            if( nBufXSize == 0 ) nBufXSize = 1;
+        }
+        if( !bIsSingleStripAsSplit &&
+            nBlockYOff == DIV_ROUND_UP(poGDS->poParentDS->nRasterYSize,
+                                       poGDS->poParentDS->nBlockYSize) - 1 )
+        {
+            nReqYSize = poGDS->poParentDS->nRasterYSize -
+                                nBlockYOff * poGDS->poParentDS->nBlockYSize;
         }
         if( nReqYOff + nReqYSize > l_poDS->GetRasterYSize() )
         {
             nReqYSize = l_poDS->GetRasterYSize() - nReqYOff;
-            nBufYSize = nReqYSize / nScaleFactor;
-            if( nBufYSize == 0 ) nBufYSize = 1;
+        }
+        if( nBlockXOff * nBlockXSize > poGDS->GetRasterXSize() - nBufXSize )
+        {
+            memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
+            nBufXSize = poGDS->GetRasterXSize() - nBlockXOff * nBlockXSize;
+        }
+        if( nBlockYOff * nBlockYSize > poGDS->GetRasterYSize() - nBufYSize )
+        {
+            memset(pImage, 0, nBlockXSize * nBlockYSize * nDataTypeSize);
+            nBufYSize = poGDS->GetRasterYSize() - nBlockYOff * nBlockYSize;
         }
 
         const int nSrcBand =
@@ -4016,6 +4047,12 @@ int GTiffRasterBand::IGetDataCoverageStatus( int nXOff, int nYOff,
     if( eAccess == GA_Update )
         poGDS->FlushCache();
 
+    if( !poGDS->SetDirectory() )
+    {
+        return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
+               GDAL_DATA_COVERAGE_STATUS_DATA;
+    }
+
     const int iXBlockStart = nXOff / nBlockXSize;
     const int iXBlockEnd = (nXOff + nXSize - 1) / nBlockXSize;
     const int iYBlockStart = nYOff / nBlockYSize;
@@ -5391,6 +5428,11 @@ class GTiffSplitBand CPL_FINAL : public GTiffRasterBand
              GTiffSplitBand( GTiffDataset *, int );
     virtual ~GTiffSplitBand() {};
 
+    virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
+                                        int nXSize, int nYSize,
+                                        int nMaskFlagStop,
+                                        double* pdfDataPct) override;
+
     virtual CPLErr IReadBlock( int, int, void * ) override;
     virtual CPLErr IWriteBlock( int, int, void * ) override;
 };
@@ -5407,6 +5449,19 @@ GTiffSplitBand::GTiffSplitBand( GTiffDataset *poDSIn, int nBandIn ) :
 }
 
 /************************************************************************/
+/*                       IGetDataCoverageStatus()                       */
+/************************************************************************/
+
+int GTiffSplitBand::IGetDataCoverageStatus( int , int ,
+                                             int , int ,
+                                             int ,
+                                             double* )
+{
+     return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
+            GDAL_DATA_COVERAGE_STATUS_DATA;
+}
+
+/************************************************************************/
 /*                             IReadBlock()                             */
 /************************************************************************/
 
@@ -5521,6 +5576,11 @@ class GTiffRGBABand CPL_FINAL : public GTiffRasterBand
                    GTiffRGBABand( GTiffDataset *, int );
     virtual ~GTiffRGBABand() {}
 
+    virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
+                                        int nXSize, int nYSize,
+                                        int nMaskFlagStop,
+                                        double* pdfDataPct) override;
+
     virtual CPLErr IReadBlock( int, int, void * ) override;
     virtual CPLErr IWriteBlock( int, int, void * ) override;
 
@@ -5538,6 +5598,19 @@ GTiffRGBABand::GTiffRGBABand( GTiffDataset *poDSIn, int nBandIn ) :
 }
 
 /************************************************************************/
+/*                       IGetDataCoverageStatus()                       */
+/************************************************************************/
+
+int GTiffRGBABand::IGetDataCoverageStatus( int , int ,
+                                             int , int ,
+                                             int ,
+                                             double* )
+{
+     return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
+            GDAL_DATA_COVERAGE_STATUS_DATA;
+}
+
+/************************************************************************/
 /*                            IWriteBlock()                             */
 /************************************************************************/
 
@@ -6719,6 +6792,11 @@ class GTiffSplitBitmapBand CPL_FINAL : public GTiffBitmapBand
                    GTiffSplitBitmapBand( GTiffDataset *, int );
     virtual       ~GTiffSplitBitmapBand();
 
+    virtual int IGetDataCoverageStatus( int nXOff, int nYOff,
+                                        int nXSize, int nYSize,
+                                        int nMaskFlagStop,
+                                        double* pdfDataPct) override;
+
     virtual CPLErr IReadBlock( int, int, void * ) override;
     virtual CPLErr IWriteBlock( int, int, void * ) override;
 };
@@ -7195,7 +7273,10 @@ int GTiffDataset::GetJPEGOverviewCount()
         return 0;
 
     if( !SetDirectory() )
+    {
+        nJPEGOverviewCount = 0;
         return 0;
+    }
 
     // Get JPEG tables.
     uint32 nJPEGTableSize = 0;
@@ -7207,6 +7288,7 @@ int GTiffDataset::GetJPEGOverviewCount()
             nJPEGTableSize > INT_MAX ||
             static_cast<GByte*>(pJPEGTable)[nJPEGTableSize-1] != 0xD9 )
         {
+            nJPEGOverviewCount = 0;
             return 0;
         }
         nJPEGTableSize--;  // Remove final 0xD9.
@@ -8965,12 +9047,13 @@ bool GTiffDataset::IsBlockAvailable( int nBlockId,
 #endif  // INTERNAL_LIBTIFF
     toff_t *panByteCounts = NULL;
     toff_t *panOffsets = NULL;
+    const bool bIsTiled = CPL_TO_BOOL( TIFFIsTiled(hTIFF) );
 
-    if( ( TIFFIsTiled( hTIFF )
+    if( ( bIsTiled
           && TIFFGetField( hTIFF, TIFFTAG_TILEBYTECOUNTS, &panByteCounts )
           && (pnOffset == NULL ||
               TIFFGetField( hTIFF, TIFFTAG_TILEOFFSETS, &panOffsets )) )
-        || ( !TIFFIsTiled( hTIFF )
+        || ( !bIsTiled
           && TIFFGetField( hTIFF, TIFFTAG_STRIPBYTECOUNTS, &panByteCounts )
           && (pnOffset == NULL ||
               TIFFGetField( hTIFF, TIFFTAG_STRIPOFFSETS, &panOffsets )) ) )
@@ -8978,6 +9061,13 @@ bool GTiffDataset::IsBlockAvailable( int nBlockId,
         if( panByteCounts == NULL || (pnOffset != NULL && panOffsets == NULL) )
             return false;
 
+        const int nBlockCount =
+            bIsTiled ? TIFFNumberOfTiles(hTIFF) : TIFFNumberOfStrips(hTIFF);
+        if( nBlockId >= nBlockCount )
+        {
+            return false;
+        }
+
         if( pnOffset )
             *pnOffset = panOffsets[nBlockId];
         if( pnSize )
@@ -11129,6 +11219,19 @@ int GTiffDataset::Identify( GDALOpenInfo *poOpenInfo )
 }
 
 /************************************************************************/
+/*                       IGetDataCoverageStatus()                       */
+/************************************************************************/
+
+int GTiffSplitBitmapBand::IGetDataCoverageStatus( int , int ,
+                                             int , int ,
+                                             int ,
+                                             double* )
+{
+     return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
+            GDAL_DATA_COVERAGE_STATUS_DATA;
+}
+
+/************************************************************************/
 /*                            GTIFFErrorHandler()                       */
 /************************************************************************/
 
@@ -13989,6 +14092,19 @@ void GTiffDataset::ScanDirectories()
         *ppoActiveDSRef = NULL;
     }
 
+    // Nasty hack. Probably something that should be fixed in libtiff
+    // In case the last directory cycles to the first directory, we have
+    // TIFFCurrentDirOffset(hTIFF) == nDirOffset, but the TIFFReadDirectory()
+    // hasn't done its job, so SetDirectory() would be confused and think it
+    // has nothing to do. To avoid that reset to a fake offset before calling
+    // SetDirectory()
+    if( TIFFCurrentDirOffset(hTIFF) == nDirOffset )
+    {
+        TIFFSetSubDirectory( hTIFF, 0 );
+        *ppoActiveDSRef = NULL;
+        SetDirectory();
+    }
+
     // If we have a mask for the main image, loop over the overviews, and if
     // they have a mask, let's set this mask as an overview of the main mask.
     if( poMaskDS != NULL )
diff --git a/frmts/gtiff/gt_wkt_srs.cpp b/frmts/gtiff/gt_wkt_srs.cpp
index dfbd4f4..a245a9f 100644
--- a/frmts/gtiff/gt_wkt_srs.cpp
+++ b/frmts/gtiff/gt_wkt_srs.cpp
@@ -66,7 +66,7 @@
 #include "tifvsi.h"
 #include "xtiffio.h"
 
-CPL_CVSID("$Id: gt_wkt_srs.cpp 38045 2017-04-17 17:48:25Z rouault $")
+CPL_CVSID("$Id: gt_wkt_srs.cpp 39898 2017-08-21 23:08:19Z rouault $")
 
 static const geokey_t ProjLinearUnitsInterpCorrectGeoKey =
     static_cast<geokey_t>(3059);
@@ -1142,7 +1142,23 @@ char *GTIFGetOGISDefn( GTIF *hGTIF, GTIFDefn * psDefn )
         OGR_SRSNode *poOldRoot = oSRS.GetRoot()->Clone();
 
         oSRS.Clear();
-        oSRS.SetNode( "COMPD_CS", "unknown" );
+
+/* -------------------------------------------------------------------- */
+/*      Set COMPD_CS name.                                              */
+/* -------------------------------------------------------------------- */
+        char szCTString[512];
+        szCTString[0] = '\0';
+        if( GDALGTIFKeyGetASCII( hGTIF, GTCitationGeoKey, szCTString,
+                                 0, sizeof(szCTString) ) &&
+            strstr( szCTString, " = " ) == NULL )
+        {
+            oSRS.SetNode( "COMPD_CS", szCTString );
+        }
+        else
+        {
+            oSRS.SetNode( "COMPD_CS", "unknown" );
+        }
+
         oSRS.GetRoot()->AddChild( poOldRoot );
 
 /* -------------------------------------------------------------------- */
diff --git a/frmts/hf2/hf2dataset.cpp b/frmts/hf2/hf2dataset.cpp
index 235d9b0..4b788d7 100644
--- a/frmts/hf2/hf2dataset.cpp
+++ b/frmts/hf2/hf2dataset.cpp
@@ -37,7 +37,7 @@
 #include <algorithm>
 #include <limits>
 
-CPL_CVSID("$Id: hf2dataset.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: hf2dataset.cpp 39384 2017-06-29 14:50:12Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -187,9 +187,14 @@ CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff,
                 GInt32 nVal;
                 VSIFReadL(&nVal, 4, 1, poGDS->fp);
                 CPL_LSBPTR32(&nVal);
-                if( VSIFReadL(pabyData, static_cast<size_t>(nWordSize * (nTileWidth - 1)), 1, poGDS->fp) != 1 )
+                const size_t nToRead = static_cast<size_t>(nWordSize * (nTileWidth - 1));
+                const size_t nRead = VSIFReadL(pabyData, 1, nToRead, poGDS->fp);
+                if( nRead != nToRead )
                 {
-                    CPLError(CE_Failure, CPLE_FileIO, "File too short");
+                    CPLError(CE_Failure, CPLE_FileIO,
+                             "File too short: got %d, expected %d",
+                             static_cast<int>(nRead),
+                             static_cast<int>(nToRead));
                     CPLFree(pabyData);
                     return CE_Failure;
                 }
diff --git a/frmts/idrisi/IdrisiDataset.cpp b/frmts/idrisi/IdrisiDataset.cpp
index 4c6b8bb..a838d11 100644
--- a/frmts/idrisi/IdrisiDataset.cpp
+++ b/frmts/idrisi/IdrisiDataset.cpp
@@ -44,7 +44,7 @@
 
 #include <cmath>
 
-CPL_CVSID( "$Id: IdrisiDataset.cpp 38148 2017-04-26 20:18:07Z rouault $" );
+CPL_CVSID( "$Id: IdrisiDataset.cpp 39328 2017-06-27 14:33:47Z rouault $" );
 
 #ifdef WIN32
 #  define PATHDELIM       '\\'
@@ -585,8 +585,8 @@ IdrisiDataset::~IdrisiDataset()
 
         CSLSetNameValueSeparator( papszRDC, ": " );
         SaveAsCRLF( papszRDC, pszDocFilename );
-        CSLDestroy( papszRDC );
     }
+    CSLDestroy( papszRDC );
 
     if( poColorTable )
     {
diff --git a/frmts/jpeg2000/jpeg2000_vsil_io.cpp b/frmts/jpeg2000/jpeg2000_vsil_io.cpp
index 9ac7f19..9ca73a3 100644
--- a/frmts/jpeg2000/jpeg2000_vsil_io.cpp
+++ b/frmts/jpeg2000/jpeg2000_vsil_io.cpp
@@ -73,10 +73,15 @@
  * __END_OF_JASPER_LICENSE__
  */
 
+#ifndef __STDC_LIMIT_MACROS
+// Needed on RHEL 6 for SIZE_MAX availability, needed by Jasper
+#define __STDC_LIMIT_MACROS 1
+#endif
+
 #include "jpeg2000_vsil_io.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: jpeg2000_vsil_io.cpp 35897 2016-10-24 11:54:24Z goatbar $");
+CPL_CVSID("$Id: jpeg2000_vsil_io.cpp 39625 2017-07-22 13:39:12Z rouault $");
 
 /*
  * File descriptor file object.
@@ -207,7 +212,7 @@ static void JPEG2000_VSIL_jas_stream_initbuf(jas_stream_t *stream, int bufmode,
             /* The buffer must be large enough to accommodate maximum
                putback. */
             assert(bufsize > JAS_STREAM_MAXPUTBACK);
-            stream->bufbase_ = JAS_CAST(uchar *, buf);
+            stream->bufbase_ = JAS_CAST(unsigned char *, buf);
             stream->bufsize_ = bufsize - JAS_STREAM_MAXPUTBACK;
         }
     } else {
diff --git a/frmts/jpeg2000/jpeg2000dataset.cpp b/frmts/jpeg2000/jpeg2000dataset.cpp
index 8a265ed..20ed6d8 100644
--- a/frmts/jpeg2000/jpeg2000dataset.cpp
+++ b/frmts/jpeg2000/jpeg2000dataset.cpp
@@ -27,6 +27,11 @@
  * DEALINGS IN THE SOFTWARE.
  ****************************************************************************/
 
+#ifndef __STDC_LIMIT_MACROS
+// Needed on RHEL 6 for SIZE_MAX availability, needed by Jasper
+ #define __STDC_LIMIT_MACROS 1
+#endif
+
 #include "cpl_string.h"
 #include "gdal_frmts.h"
 #include "gdaljp2abstractdataset.h"
@@ -39,7 +44,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: jpeg2000dataset.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: jpeg2000dataset.cpp 39440 2017-07-02 20:57:25Z rouault $");
 
 // XXX: Part of code below extracted from the JasPer internal headers and
 // must be in sync with JasPer version (this one works with JasPer 1.900.1)
diff --git a/frmts/makefile.vc b/frmts/makefile.vc
index 0b52e0a..82d7f82 100644
--- a/frmts/makefile.vc
+++ b/frmts/makefile.vc
@@ -117,13 +117,11 @@ PLUGINFLAGS	=	$(PLUGINFLAGS) -DFRMT_fits
 !ENDIF
 !ENDIF
 
-!IF DEFINED(POPPLER_LIBS) || DEFINED(PODOFO_LIBS) || DEFINED(PDFIUM_LIBS)
 !IF "$(PDF_PLUGIN)" != "YES"
 EXTRAFLAGS	=	$(EXTRAFLAGS) -DFRMT_pdf
 !ELSE
 PLUGINFLAGS	=	$(PLUGINFLAGS) -DFRMT_pdf
 !ENDIF
-!ENDIF
 
 !IFDEF DODS_DIR
 EXTRAFLAGS	=	$(EXTRAFLAGS) -DFRMT_dods
diff --git a/frmts/mbtiles/mbtilesdataset.cpp b/frmts/mbtiles/mbtilesdataset.cpp
index 85fc836..3bd3f5d 100644
--- a/frmts/mbtiles/mbtilesdataset.cpp
+++ b/frmts/mbtiles/mbtilesdataset.cpp
@@ -39,7 +39,7 @@
 #include <math.h>
 #include <algorithm>
 
-CPL_CVSID("$Id: mbtilesdataset.cpp 38115 2017-04-23 07:24:41Z rouault $");
+CPL_CVSID("$Id: mbtilesdataset.cpp 39303 2017-06-26 08:15:37Z rouault $");
 
 static const char * const apszAllowedDrivers[] = {"JPEG", "PNG", NULL};
 
@@ -1188,16 +1188,16 @@ char** MBTilesDataset::GetMetadata( const char * pszDomain )
     {
         if (OGR_F_IsFieldSetAndNotNull(hFeat, 0) && OGR_F_IsFieldSetAndNotNull(hFeat, 1))
         {
-            const char* pszName = OGR_F_GetFieldAsString(hFeat, 0);
-            const char* pszValue = OGR_F_GetFieldAsString(hFeat, 1);
-            if (pszValue[0] != '\0' &&
-                !STARTS_WITH(pszValue, "function(") &&
-                strstr(pszValue, "<img ") == NULL &&
-                strstr(pszValue, "<p>") == NULL &&
-                strstr(pszValue, "</p>") == NULL &&
-                strstr(pszValue, "<div") == NULL)
+            CPLString osName = OGR_F_GetFieldAsString(hFeat, 0);
+            CPLString osValue = OGR_F_GetFieldAsString(hFeat, 1);
+            if (osName[0] != '\0' &&
+                !STARTS_WITH(osValue, "function(") &&
+                strstr(osValue, "<img ") == NULL &&
+                strstr(osValue, "<p>") == NULL &&
+                strstr(osValue, "</p>") == NULL &&
+                strstr(osValue, "<div") == NULL)
             {
-                aosList.AddNameValue(pszName, pszValue);
+                aosList.AddNameValue(osName, osValue);
             }
         }
         OGR_F_Destroy(hFeat);
diff --git a/frmts/netcdf/netcdfdataset.cpp b/frmts/netcdf/netcdfdataset.cpp
index 5913d8a..ddb96b3 100644
--- a/frmts/netcdf/netcdfdataset.cpp
+++ b/frmts/netcdf/netcdfdataset.cpp
@@ -62,7 +62,7 @@
 #include "ogr_core.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: netcdfdataset.cpp 39160 2017-06-18 10:59:08Z rouault $");
+CPL_CVSID("$Id: netcdfdataset.cpp 39627 2017-07-22 17:59:00Z rouault $");
 
 // Internal function declarations.
 
@@ -3468,11 +3468,29 @@ int netCDFDataset::ProcessCFGeolocation( int nVarId )
             for( int i = 0; i < CSLCount(papszTokens); i++ )
             {
                 if( NCDFIsVarLongitude(cdfid, -1, papszTokens[i]) )
-                    snprintf(szGeolocXName, sizeof(szGeolocXName),
-                             "%s",papszTokens[i]);
+                {
+                    int nOtherVarId = -1;
+                    // Check that the variable actually exists
+                    // Needed on Sentinel-3 products
+                    if( nc_inq_varid(cdfid, papszTokens[i], &nOtherVarId) ==
+                                                                NC_NOERR )
+                    {
+                        snprintf(szGeolocXName, sizeof(szGeolocXName),
+                                 "%s",papszTokens[i]);
+                    }
+                }
                 else if( NCDFIsVarLatitude(cdfid, -1, papszTokens[i]) )
-                    snprintf(szGeolocYName, sizeof(szGeolocYName),
-                             "%s",papszTokens[i]);
+                {
+                    int nOtherVarId = -1;
+                    // Check that the variable actually exists
+                    // Needed on Sentinel-3 products
+                    if( nc_inq_varid(cdfid, papszTokens[i], &nOtherVarId) ==
+                                                                NC_NOERR )
+                    {
+                        snprintf(szGeolocYName, sizeof(szGeolocYName),
+                                 "%s",papszTokens[i]);
+                    }
+                }
             }
             // Add GEOLOCATION metadata.
             if( !EQUAL(szGeolocXName, "") && !EQUAL(szGeolocYName, "") )
@@ -5970,11 +5988,16 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                 {
                     int anDimIds[2] = { -1, -1 };
                     nc_inq_vardimid(poDS->cdfid, j, anDimIds);
+
+                    nc_type vartype = NC_NAT;
+                    nc_inq_vartype(poDS->cdfid, j, &vartype);
+
                     char szDimNameX[NC_MAX_NAME + 1];
                     char szDimNameY[NC_MAX_NAME + 1];
                     szDimNameX[0] = '\0';
                     szDimNameY[0] = '\0';
-                    if( nc_inq_dimname(poDS->cdfid, anDimIds[0], szDimNameY) ==
+                    if( vartype == NC_CHAR &&
+                        nc_inq_dimname(poDS->cdfid, anDimIds[0], szDimNameY) ==
                            NC_NOERR &&
                        nc_inq_dimname(poDS->cdfid, anDimIds[1], szDimNameX) ==
                            NC_NOERR &&
@@ -6257,7 +6280,7 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                 poDS->bSetProjection = false;
                 poDS->bSetGeoTransform = false;
 
-            if( (poOpenInfo->nOpenFlags & GDAL_OF_RASTER) == 0 )
+                if( (poOpenInfo->nOpenFlags & GDAL_OF_RASTER) == 0 )
                 {
                     // Strip out uninteresting metadata.
                     poDS->papszMetadata = CSLSetNameValue(
@@ -6287,10 +6310,6 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                     poLayer->SetGridMapping(osGridMapping);
                 }
                 poLayer->SetProfile(nProfileDimId, nParentIndexVarID);
-                poDS->papoLayers = static_cast<netCDFLayer **>(
-                    CPLRealloc(poDS->papoLayers,
-                               (poDS->nLayers + 1) * sizeof(netCDFLayer *)));
-                poDS->papoLayers[poDS->nLayers++] = poLayer;
 
                 for( size_t j = 0; j < anPotentialVectorVarID.size(); j++ )
                 {
@@ -6310,6 +6329,20 @@ GDALDataset *netCDFDataset::Open( GDALOpenInfo *poOpenInfo )
                         poLayer->AddField(anPotentialVectorVarID[j]);
                     }
                 }
+
+                if( poLayer->GetLayerDefn()->GetFieldCount() != 0 ||
+                    poLayer->GetGeomType() != wkbNone )
+                {
+                    poDS->papoLayers = static_cast<netCDFLayer **>(
+                        CPLRealloc(poDS->papoLayers,
+                                (poDS->nLayers + 1) * sizeof(netCDFLayer *)));
+                    poDS->papoLayers[poDS->nLayers++] = poLayer;
+                }
+                else
+                {
+                    delete poLayer;
+                }
+
             }
         }
 
diff --git a/frmts/netcdf/netcdflayer.cpp b/frmts/netcdf/netcdflayer.cpp
index 3aa9ced..7a28619 100644
--- a/frmts/netcdf/netcdflayer.cpp
+++ b/frmts/netcdf/netcdflayer.cpp
@@ -29,7 +29,7 @@
 #include "netcdfdataset.h"
 #include "cpl_time.h"
 
-CPL_CVSID("$Id: netcdflayer.cpp 37982 2017-04-13 17:30:17Z goatbar $");
+CPL_CVSID("$Id: netcdflayer.cpp 39349 2017-06-27 21:30:17Z rouault $");
 
 /************************************************************************/
 /*                            netCDFLayer()                             */
@@ -1730,8 +1730,15 @@ bool netCDFLayer::AddField(int nVarID)
     int nDimCount = 1;
     nc_inq_varndims(m_nLayerCDFId, nVarID, &nDimCount);
     int anDimIds[2] = { -1, -1 };
-    if( nDimCount <= 2 )
+    if( (vartype == NC_CHAR && nDimCount <= 2) ||
+        (vartype != NC_CHAR && nDimCount == 1) )
+    {
         nc_inq_vardimid(m_nLayerCDFId, nVarID, anDimIds);
+    }
+    else
+    {
+        return false;
+    }
 
     switch( vartype )
     {
diff --git a/frmts/openjpeg/openjpegdataset.cpp b/frmts/openjpeg/openjpegdataset.cpp
index 47d309e..2805d98 100644
--- a/frmts/openjpeg/openjpegdataset.cpp
+++ b/frmts/openjpeg/openjpegdataset.cpp
@@ -34,7 +34,9 @@
 #pragma clang diagnostic ignored "-Wdocumentation"
 #endif
 
-#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100
+#if defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20200
+#include <openjpeg-2.2/openjpeg.h>
+#elif defined(OPENJPEG_VERSION) && OPENJPEG_VERSION >= 20100
 #include <openjpeg-2.1/openjpeg.h>
 #else
 #include <stdio.h> /* openjpeg.h needs FILE* */
@@ -57,7 +59,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: openjpegdataset.cpp 38088 2017-04-21 15:05:04Z rouault $");
+CPL_CVSID("$Id: openjpegdataset.cpp 39926 2017-08-24 01:12:30Z rouault $");
 
 /************************************************************************/
 /*                  JP2OpenJPEGDataset_ErrorCallback()                  */
@@ -781,11 +783,23 @@ CPLErr JP2OpenJPEGDataset::ReadBlock( int nBand, VSILFILE* fpIn,
 
     if (bUseSetDecodeArea)
     {
+        /* We need to explicitely set the resolution factor on the image */
+        /* otherwise opj_set_decode_area() will assume we decode at full */
+        /* resolution. */
+        /* If using parameters.cp_reduce instead of opj_set_decoded_resolution_factor() */
+        /* we wouldn't need to do that, as opj_read_header() would automatically */
+        /* assign the comps[].factor to the appropriate value */
+        for(unsigned int iBand = 0; iBand < psImage->numcomps; iBand ++)
+        {
+            psImage->comps[iBand].factor = iLevel;
+        }
+        /* The decode area must be expressed in grid reference, ie at full*/
+        /* scale */
         if (!opj_set_decode_area(pCodec,psImage,
-                                 nBlockXOff*nBlockXSize,
-                                 nBlockYOff*nBlockYSize,
-                                 nBlockXOff*nBlockXSize+nWidthToRead,
-                                 nBlockYOff*nBlockYSize+nHeightToRead))
+                                 (nBlockXOff*nBlockXSize) << iLevel,
+                                 (nBlockYOff*nBlockYSize) << iLevel,
+                                 (nBlockXOff*nBlockXSize+nWidthToRead) << iLevel,
+                                 (nBlockYOff*nBlockYSize+nHeightToRead) << iLevel))
         {
             CPLError(CE_Failure, CPLE_AppDefined, "opj_set_decode_area() failed");
             eErr = CE_Failure;
@@ -1701,28 +1715,37 @@ GDALDataset *JP2OpenJPEGDataset::Open( GDALOpenInfo * poOpenInfo )
     {
         poDS->bUseSetDecodeArea = false;
     }
-    else
+    /* Some Sentinel2 preview datasets are 343x343 large, but with 8x8 blocks */
+    /* Using the tile API for that is super slow, so expose a single block */
+    else if( poDS->nRasterXSize <= 1024 &&  poDS->nRasterYSize <= 1024 &&
+             nTileW < 32 && nTileH < 32 )
     {
-    poDS->bUseSetDecodeArea =
-        (poDS->nRasterXSize == (int)nTileW &&
-         poDS->nRasterYSize == (int)nTileH &&
-         (poDS->nRasterXSize > 1024 ||
-          poDS->nRasterYSize > 1024));
-
-    /* Sentinel2 preview datasets are 343x343 and 60m are 1830x1830, but they */
-    /* are tiled with tile dimensions 2048x2048. It would be a waste of */
-    /* memory to allocate such big blocks */
-    if( poDS->nRasterXSize < (int)nTileW &&
-        poDS->nRasterYSize < (int)nTileH )
-    {
-        poDS->bUseSetDecodeArea = TRUE;
+        poDS->bUseSetDecodeArea = true;
         nTileW = poDS->nRasterXSize;
         nTileH = poDS->nRasterYSize;
-        if (nTileW > 2048) nTileW = 2048;
-        if (nTileH > 2048) nTileH = 2048;
     }
-    else if (poDS->bUseSetDecodeArea)
+    else
     {
+        poDS->bUseSetDecodeArea =
+            (poDS->nRasterXSize == (int)nTileW &&
+            poDS->nRasterYSize == (int)nTileH &&
+            (poDS->nRasterXSize > 1024 ||
+            poDS->nRasterYSize > 1024));
+
+        /* Other Sentinel2 preview datasets are 343x343 and 60m are 1830x1830, but they */
+        /* are tiled with tile dimensions 2048x2048. It would be a waste of */
+        /* memory to allocate such big blocks */
+        if( poDS->nRasterXSize < (int)nTileW &&
+            poDS->nRasterYSize < (int)nTileH )
+        {
+            poDS->bUseSetDecodeArea = TRUE;
+            nTileW = poDS->nRasterXSize;
+            nTileH = poDS->nRasterYSize;
+            if (nTileW > 2048) nTileW = 2048;
+            if (nTileH > 2048) nTileH = 2048;
+        }
+        else if (poDS->bUseSetDecodeArea)
+        {
             // Arbitrary threshold... ~4 million at least needed for the GRIB2
             // images mentioned below.
             if( nTileH == 1 && nTileW < 20 * 1024 * 1024 )
@@ -1732,9 +1755,9 @@ GDALDataset *JP2OpenJPEGDataset::Open( GDALOpenInfo * poOpenInfo )
             }
             else
             {
-        if (nTileW > 1024) nTileW = 1024;
-        if (nTileH > 1024) nTileH = 1024;
-    }
+                if (nTileW > 1024) nTileW = 1024;
+                if (nTileH > 1024) nTileH = 1024;
+            }
         }
     }
 
diff --git a/frmts/pcidsk/sdk/channel/cbandinterleavedchannel.cpp b/frmts/pcidsk/sdk/channel/cbandinterleavedchannel.cpp
index 8ff3b03..0f77877 100644
--- a/frmts/pcidsk/sdk/channel/cbandinterleavedchannel.cpp
+++ b/frmts/pcidsk/sdk/channel/cbandinterleavedchannel.cpp
@@ -187,7 +187,7 @@ int CBandInterleavedChannel::ReadBlock( int block_index, void *buffer,
         {
             memcpy( ((char *) buffer) + pixel_size * i, 
                     this_pixel, pixel_size );
-            this_pixel += pixel_size;
+            this_pixel += pixel_offset;
         }
     }
 
diff --git a/frmts/pcidsk/sdk/core/pcidsk_utils.cpp b/frmts/pcidsk/sdk/core/pcidsk_utils.cpp
index 644aec6..9ec5ed5 100644
--- a/frmts/pcidsk/sdk/core/pcidsk_utils.cpp
+++ b/frmts/pcidsk/sdk/core/pcidsk_utils.cpp
@@ -24,6 +24,7 @@
  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  ****************************************************************************/
+
 #include "pcidsk_config.h"
 #include "pcidsk_types.h"
 #include "pcidsk_exception.h"
@@ -35,8 +36,13 @@
 #include <cctype>
 #include <cstdio>
 #include <cmath>
+#include <cstdarg>
 #include <iostream>
 
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
+
 using namespace PCIDSK;
 
 #if defined(_MSC_VER) && (_MSC_VER < 1500)
diff --git a/frmts/pcidsk/sdk/core/pcidskexception.cpp b/frmts/pcidsk/sdk/core/pcidskexception.cpp
index 6e63773..44c12bf 100644
--- a/frmts/pcidsk/sdk/core/pcidskexception.cpp
+++ b/frmts/pcidsk/sdk/core/pcidskexception.cpp
@@ -31,6 +31,11 @@
 #include <cstdlib>
 #include <cstring>
 #include <cstdio>
+#include <cstdarg>
+
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
 
 using PCIDSK::PCIDSKException;
 
diff --git a/frmts/pdf/GNUmakefile b/frmts/pdf/GNUmakefile
index a032455..c7265f6 100644
--- a/frmts/pdf/GNUmakefile
+++ b/frmts/pdf/GNUmakefile
@@ -31,6 +31,10 @@ ifeq ($(POPPLER_0_23_OR_LATER),yes)
 CPPFLAGS +=  -DPOPPLER_0_23_OR_LATER
 endif
 
+ifeq ($(POPPLER_0_58_OR_LATER),yes)
+CPPFLAGS +=  -DPOPPLER_0_58_OR_LATER
+endif
+
 ifeq ($(HAVE_PODOFO),yes)
 CPPFLAGS +=  -DHAVE_PODOFO
 endif
diff --git a/frmts/pdf/makefile.vc b/frmts/pdf/makefile.vc
index 92d7b44..b4fa14d 100644
--- a/frmts/pdf/makefile.vc
+++ b/frmts/pdf/makefile.vc
@@ -14,7 +14,7 @@ OBJ = $(OBJ) ..\..\ogr\ogrsf_frmts\mem\ogrmemdatasource.obj ..\..\ogr\ogrsf_frmt
 EXTRAFLAGS =  -I..\vrt -I..\mem -I..\..\ogr\ogrsf_frmts\mem $(POPPLER_EXTRAFLAGS) $(PODOFO_EXTRAFLAGS) $(PDFIUM_EXTRAFLAGS)
 
 !IFDEF POPPLER_ENABLED
-POPPLER_EXTRAFLAGS = $(POPPLER_CFLAGS) $(POPPLER_HAS_OPTCONTENT_FLAGS) $(POPPLER_BASE_STREAM_HAS_TWO_ARGS_FLAGS) $(POPPLER_0_20_OR_LATER_FLAGS) $(POPPLER_0_23_OR_LATER_FLAGS) -DHAVE_POPPLER
+POPPLER_EXTRAFLAGS = $(POPPLER_CFLAGS) $(POPPLER_HAS_OPTCONTENT_FLAGS) $(POPPLER_BASE_STREAM_HAS_TWO_ARGS_FLAGS) $(POPPLER_0_20_OR_LATER_FLAGS) $(POPPLER_0_23_OR_LATER_FLAGS) $(POPPLER_0_58_OR_LATER_FLAGS) -DHAVE_POPPLER
 
 !IFDEF POPPLER_HAS_OPTCONTENT
 POPPLER_HAS_OPTCONTENT_FLAGS = -DPOPPLER_HAS_OPTCONTENT
@@ -32,6 +32,10 @@ POPPLER_0_20_OR_LATER_FLAGS = -DPOPPLER_0_20_OR_LATER
 POPPLER_0_23_OR_LATER_FLAGS = -DPOPPLER_0_23_OR_LATER
 !ENDIF
 
+!IFDEF POPPLER_0_58_OR_LATER
+POPPLER_0_58_OR_LATER_FLAGS = -DPOPPLER_0_58_OR_LATER
+!ENDIF
+
 !ENDIF
 
 !IFDEF PODOFO_ENABLED
diff --git a/frmts/pdf/pdfdataset.cpp b/frmts/pdf/pdfdataset.cpp
index 7d7c526..6ac74c3 100644
--- a/frmts/pdf/pdfdataset.cpp
+++ b/frmts/pdf/pdfdataset.cpp
@@ -56,7 +56,7 @@
 
 /* g++ -fPIC -g -Wall frmts/pdf/pdfdataset.cpp -shared -o gdal_PDF.so -Iport -Igcore -Iogr -L. -lgdal -lpoppler -I/usr/include/poppler */
 
-CPL_CVSID("$Id: pdfdataset.cpp 36776 2016-12-10 11:17:47Z rouault $");
+CPL_CVSID("$Id: pdfdataset.cpp 40036 2017-09-08 11:23:21Z rouault $");
 
 #if defined(HAVE_POPPLER) || defined(HAVE_PODOFO) || defined(HAVE_PDFIUM)
 
@@ -129,7 +129,11 @@ class ObjectAutoFree : public Object
 
 public:
     ObjectAutoFree() {}
-    ~ObjectAutoFree() { obj.free(); }
+    ~ObjectAutoFree() {
+#ifndef POPPLER_0_58_OR_LATER
+        obj.free();
+#endif
+    }
 
     Object* getObj() { return &obj; }
 };
@@ -2285,7 +2289,11 @@ GDALPDFObject* PDFDataset::GetCatalog()
     if (bUseLib.test(PDFLIB_POPPLER))
     {
         poCatalogObjectPoppler = new ObjectAutoFree;
+#ifdef POPPLER_0_58_OR_LATER
+        *poCatalogObjectPoppler->getObj() = poDocPoppler->getXRef()->getCatalog();
+#else
         poDocPoppler->getXRef()->getCatalog(poCatalogObjectPoppler->getObj());
+#endif
         if (!poCatalogObjectPoppler->getObj()->isNull())
             poCatalogObject = new GDALPDFObjectPoppler(poCatalogObjectPoppler->getObj(), FALSE);
     }
@@ -4026,7 +4034,11 @@ GDALDataset *PDFDataset::Open( GDALOpenInfo * poOpenInfo )
     GDALPDFObject* poPageObj = NULL;
 #ifdef HAVE_POPPLER
     PDFDoc* poDocPoppler = NULL;
+#ifdef POPPLER_0_58_OR_LATER
+    Object oObj;
+#else
     ObjectAutoFree oObj;
+#endif
     Page* poPagePoppler = NULL;
     Catalog* poCatalogPoppler = NULL;
 #endif
@@ -4073,8 +4085,12 @@ GDALDataset *PDFDataset::Open( GDALOpenInfo * poOpenInfo )
         if (pszUserPwd)
             poUserPwd = new GooString(pszUserPwd);
 
+#ifdef POPPLER_0_58_OR_LATER
+        poDocPoppler = new PDFDoc(new VSIPDFFileStream(fp, pszFilename, std::move(oObj)), NULL, poUserPwd);
+#else
         oObj.getObj()->initNull();
         poDocPoppler = new PDFDoc(new VSIPDFFileStream(fp, pszFilename, oObj.getObj()), NULL, poUserPwd);
+#endif
         delete poUserPwd;
 
         if ( !poDocPoppler->isOk() || poDocPoppler->getNumPages() == 0 )
@@ -4765,10 +4781,16 @@ GDALDataset *PDFDataset::Open( GDALOpenInfo * poOpenInfo )
     if( poDocPoppler->getXRef()->isOk() )
     {
         Object oInfo;
+#ifdef POPPLER_0_58_OR_LATER
+        oInfo = poDocPoppler->getDocInfo();
+#else
         poDocPoppler->getDocInfo(&oInfo);
+#endif
         GDALPDFObjectPoppler oInfoObjPoppler(&oInfo, FALSE);
         poDS->ParseInfo(&oInfoObjPoppler);
+#ifndef POPPLER_0_58_OR_LATER
         oInfo.free();
+#endif
     }
 
     /* Find layers */
diff --git a/frmts/pdf/pdfio.cpp b/frmts/pdf/pdfio.cpp
index 9be6189..2be5912 100644
--- a/frmts/pdf/pdfio.cpp
+++ b/frmts/pdf/pdfio.cpp
@@ -34,7 +34,7 @@
 
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: pdfio.cpp 35897 2016-10-24 11:54:24Z goatbar $");
+CPL_CVSID("$Id: pdfio.cpp 40036 2017-09-08 11:23:21Z rouault $");
 
 #ifdef POPPLER_BASE_STREAM_HAS_TWO_ARGS
 /* Poppler 0.31.0 is the first one that needs to know the file size */
@@ -52,8 +52,12 @@ static vsi_l_offset VSIPDFFileStreamGetSize(VSILFILE* f)
 /************************************************************************/
 
 VSIPDFFileStream::VSIPDFFileStream(
-    VSILFILE* fIn, const char* pszFilename, Object *dictA) :
-#ifdef POPPLER_BASE_STREAM_HAS_TWO_ARGS
+    VSILFILE* fIn, const char* pszFilename,
+    makeSubStream_object_type dictA
+) :
+#ifdef POPPLER_0_58_OR_LATER
+    BaseStream(std::move(dictA), (Goffset)VSIPDFFileStreamGetSize(fIn)),
+#elif defined(POPPLER_BASE_STREAM_HAS_TWO_ARGS)
     BaseStream(dictA, (setPos_offset_type)VSIPDFFileStreamGetSize(fIn)),
 #else
     BaseStream(dictA),
@@ -77,8 +81,11 @@ VSIPDFFileStream::VSIPDFFileStream(
 
 VSIPDFFileStream::VSIPDFFileStream( VSIPDFFileStream* poParentIn,
                                     vsi_l_offset startA, GBool limitedA,
-                                    vsi_l_offset lengthA, Object *dictA ) :
-#ifdef POPPLER_BASE_STREAM_HAS_TWO_ARGS
+                                    vsi_l_offset lengthA,
+                                    makeSubStream_object_type dictA) :
+#ifdef POPPLER_0_58_OR_LATER
+    BaseStream(std::move(dictA), (Goffset)lengthA),
+#elif defined(POPPLER_BASE_STREAM_HAS_TWO_ARGS)
     BaseStream(dictA, (makeSubStream_offset_type)lengthA),
 #else
     BaseStream(dictA),
@@ -115,7 +122,13 @@ VSIPDFFileStream::~VSIPDFFileStream()
 /*                                  copy()                              */
 /************************************************************************/
 
-#ifdef POPPLER_0_23_OR_LATER
+#ifdef POPPLER_0_58_OR_LATER
+BaseStream* VSIPDFFileStream::copy()
+{
+    return new VSIPDFFileStream(poParent, nStart, bLimited,
+                                nLength, dict.copy());
+}
+#elif defined(POPPLER_0_23_OR_LATER)
 BaseStream* VSIPDFFileStream::copy()
 {
     return new VSIPDFFileStream(poParent, nStart, bLimited,
@@ -126,13 +139,18 @@ BaseStream* VSIPDFFileStream::copy()
 /************************************************************************/
 /*                             makeSubStream()                          */
 /************************************************************************/
-
 Stream *VSIPDFFileStream::makeSubStream(makeSubStream_offset_type startA, GBool limitedA,
-                                        makeSubStream_offset_type lengthA, Object *dictA)
+                                        makeSubStream_offset_type lengthA, makeSubStream_object_type dictA)
 {
+#ifdef POPPLER_0_58_OR_LATER
+    return new VSIPDFFileStream(this,
+                                startA, limitedA,
+                                lengthA, std::move(dictA));
+#else
     return new VSIPDFFileStream(this,
                                 startA, limitedA,
                                 lengthA, dictA);
+#endif
 }
 
 /************************************************************************/
diff --git a/frmts/pdf/pdfio.h b/frmts/pdf/pdfio.h
index e96f317..0098ed0 100644
--- a/frmts/pdf/pdfio.h
+++ b/frmts/pdf/pdfio.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: pdfio.h 38070 2017-04-20 12:02:25Z rouault $
+ * $Id: pdfio.h 40036 2017-09-08 11:23:21Z rouault $
  *
  * Project:  PDF driver
  * Purpose:  GDALDataset driver for PDF dataset.
@@ -52,13 +52,21 @@
 #define moveStart_delta_type int
 #endif
 
+#ifdef POPPLER_0_58_OR_LATER
+#define makeSubStream_object_type Object&&
+#else
+#define makeSubStream_object_type Object*
+#endif
+
 class VSIPDFFileStream: public BaseStream
 {
     public:
-        VSIPDFFileStream(VSILFILE* f, const char* pszFilename, Object *dictA);
+        VSIPDFFileStream(VSILFILE* f, const char* pszFilename,
+                         makeSubStream_object_type dictA);
         VSIPDFFileStream(VSIPDFFileStream* poParent,
                          vsi_l_offset startA, GBool limitedA,
-                         vsi_l_offset lengthA, Object *dictA);
+                         vsi_l_offset lengthA,
+                         makeSubStream_object_type dictA);
         virtual ~VSIPDFFileStream();
 
 #ifdef POPPLER_0_23_OR_LATER
@@ -66,7 +74,7 @@ class VSIPDFFileStream: public BaseStream
 #endif
 
         virtual Stream *   makeSubStream(makeSubStream_offset_type startA, GBool limitedA,
-                                         makeSubStream_offset_type lengthA, Object *dictA) override;
+                                         makeSubStream_offset_type lengthA, makeSubStream_object_type dictA) override;
         virtual getPos_ret_type      getPos() override;
         virtual getStart_ret_type    getStart() override;
 
diff --git a/frmts/pdf/pdfobject.cpp b/frmts/pdf/pdfobject.cpp
index bb345a2..03e19db 100644
--- a/frmts/pdf/pdfobject.cpp
+++ b/frmts/pdf/pdfobject.cpp
@@ -38,7 +38,7 @@
 #include <vector>
 #include "pdfobject.h"
 
-CPL_CVSID("$Id: pdfobject.cpp 36776 2016-12-10 11:17:47Z rouault $");
+CPL_CVSID("$Id: pdfobject.cpp 40036 2017-09-08 11:23:21Z rouault $");
 
 /************************************************************************/
 /*                        ROUND_TO_INT_IF_CLOSE()                       */
@@ -971,7 +971,9 @@ class GDALPDFStreamPoppler : public GDALPDFStream
 
 GDALPDFObjectPoppler::~GDALPDFObjectPoppler()
 {
+#ifndef POPPLER_0_58_OR_LATER
     m_po->free();
+#endif
     if (m_bDestroy)
         delete m_po;
     delete m_poDict;
@@ -1182,6 +1184,35 @@ GDALPDFObject* GDALPDFDictionaryPoppler::Get(const char* pszKey)
     if (oIter != m_map.end())
         return oIter->second;
 
+#ifdef POPPLER_0_58_OR_LATER
+    Object o = m_poDict->lookupNF(((char*)pszKey));
+    if (!o.isNull())
+    {
+        int nRefNum = 0;
+        int nRefGen = 0;
+        if( o.isRef())
+        {
+            nRefNum = o.getRefNum();
+            nRefGen = o.getRefGen();
+            Object o2 = m_poDict->lookup((char*)pszKey);
+            if( !o2.isNull() )
+            {
+                GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(new Object(std::move(o2)), TRUE);
+                poObj->SetRefNumAndGen(nRefNum, nRefGen);
+                m_map[pszKey] = poObj;
+                return poObj;
+            }
+        }
+        else
+        {
+            GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(new Object(std::move(o)), TRUE);
+            poObj->SetRefNumAndGen(nRefNum, nRefGen);
+            m_map[pszKey] = poObj;
+            return poObj;
+        }
+    }
+    return NULL;
+#else
     Object* po = new Object;
     if (m_poDict->lookupNF((char*)pszKey, po) && !po->isNull())
     {
@@ -1210,6 +1241,7 @@ GDALPDFObject* GDALPDFDictionaryPoppler::Get(const char* pszKey)
         delete po;
         return NULL;
     }
+#endif
 }
 
 /************************************************************************/
@@ -1286,6 +1318,35 @@ GDALPDFObject* GDALPDFArrayPoppler::Get(int nIndex)
     if (m_v[nIndex] != NULL)
         return m_v[nIndex];
 
+#ifdef POPPLER_0_58_OR_LATER
+    Object o = m_poArray->getNF(nIndex);
+    if( !o.isNull() )
+    {
+        int nRefNum = 0;
+        int nRefGen = 0;
+        if( o.isRef())
+        {
+            nRefNum = o.getRefNum();
+            nRefGen = o.getRefGen();
+            Object o2 = m_poArray->get(nIndex);
+            if( !o2.isNull() )
+            {
+                GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(new Object(std::move(o2)), TRUE);
+                poObj->SetRefNumAndGen(nRefNum, nRefGen);
+                m_v[nIndex] = poObj;
+                return poObj;
+            }
+        }
+        else
+        {
+            GDALPDFObjectPoppler* poObj = new GDALPDFObjectPoppler(new Object(std::move(o)), TRUE);
+            poObj->SetRefNumAndGen(nRefNum, nRefGen);
+            m_v[nIndex] = poObj;
+            return poObj;
+        }
+    }
+    return NULL;
+#else
     Object* po = new Object;
     if (m_poArray->getNF(nIndex, po))
     {
@@ -1314,6 +1375,7 @@ GDALPDFObject* GDALPDFArrayPoppler::Get(int nIndex)
         delete po;
         return NULL;
     }
+#endif
 }
 
 /************************************************************************/
diff --git a/frmts/pds/isis3dataset.cpp b/frmts/pds/isis3dataset.cpp
index 714661f..4704767 100644
--- a/frmts/pds/isis3dataset.cpp
+++ b/frmts/pds/isis3dataset.cpp
@@ -104,7 +104,7 @@ static const char* const pszLABEL_BYTES_PLACEHOLDER = "!*^LABEL_BYTES^*!";
 static const char* const pszHISTORY_STARTBYTE_PLACEHOLDER =
                                                     "!*^HISTORY_STARTBYTE^*!";
 
-CPL_CVSID("$Id: isis3dataset.cpp 37708 2017-03-14 10:56:35Z rouault $");
+CPL_CVSID("$Id: isis3dataset.cpp 40070 2017-09-11 16:51:12Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -759,6 +759,7 @@ class ISIS3WrapperRasterBand : public GDALProxyRasterBand
 
         void    InitFile();
 
+        virtual CPLErr Fill(double dfRealValue, double dfImaginaryValue = 0) override;
         virtual CPLErr          IWriteBlock( int, int, void * ) override;
 
         virtual CPLErr  IRasterIO( GDALRWFlag, int, int, int, int,
@@ -1475,6 +1476,25 @@ void ISIS3WrapperRasterBand::InitFile()
 }
 
 /************************************************************************/
+/*                               Fill()                                 */
+/************************************************************************/
+
+CPLErr ISIS3WrapperRasterBand::Fill(double dfRealValue, double dfImaginaryValue)
+{
+    ISIS3Dataset* poGDS = reinterpret_cast<ISIS3Dataset*>(poDS);
+    if( poGDS->m_bHasSrcNoData && poGDS->m_dfSrcNoData == dfRealValue )
+    {
+        dfRealValue = m_dfNoData;
+    }
+    if( poGDS->m_bGeoTIFFAsRegularExternal && !poGDS->m_bGeoTIFFInitDone )
+    {
+        InitFile();
+    }
+
+    return GDALProxyRasterBand::Fill( dfRealValue, dfImaginaryValue );
+}
+
+/************************************************************************/
 /*                             IWriteBlock()                             */
 /************************************************************************/
 
@@ -1488,7 +1508,7 @@ CPLErr ISIS3WrapperRasterBand::IWriteBlock( int nXBlock, int nYBlock,
         RemapNoData( eDataType, pImage, nBlockXSize * nBlockYSize,
                      poGDS->m_dfSrcNoData, m_dfNoData );
     }
-    if( poGDS->m_bGeoTIFFAsRegularExternal && poGDS->m_bGeoTIFFInitDone )
+    if( poGDS->m_bGeoTIFFAsRegularExternal && !poGDS->m_bGeoTIFFInitDone )
     {
         InitFile();
     }
@@ -3098,20 +3118,27 @@ void ISIS3Dataset::BuildLabel()
     // Deal with History object
     BuildHistory();
 
-    CPLJsonObject& oHistory = oLabel["History"];
-    oHistory.clear();
-    oHistory["_type"] = "object";
-    oHistory["Name"] = "IsisCube";
-    if( m_osExternalFilename.empty() )
-        oHistory["StartByte"] = pszHISTORY_STARTBYTE_PLACEHOLDER;
+    if( !m_osHistory.empty() )
+    {
+        CPLJsonObject& oHistory = oLabel["History"];
+        oHistory.clear();
+        oHistory["_type"] = "object";
+        oHistory["Name"] = "IsisCube";
+        if( m_osExternalFilename.empty() )
+            oHistory["StartByte"] = pszHISTORY_STARTBYTE_PLACEHOLDER;
+        else
+            oHistory["StartByte"] = 1;
+        oHistory["Bytes"] = static_cast<GIntBig>(m_osHistory.size());
+        if( !m_osExternalFilename.empty() )
+        {
+            CPLString osFilename(CPLGetBasename(GetDescription()));
+            osFilename += ".History.IsisCube";
+            oHistory["^History"] = osFilename;
+        }
+    }
     else
-        oHistory["StartByte"] = 1;
-    oHistory["Bytes"] = static_cast<GIntBig>(m_osHistory.size());
-    if( !m_osExternalFilename.empty() )
     {
-        CPLString osFilename(CPLGetBasename(GetDescription()));
-        osFilename += ".History.IsisCube";
-        oHistory["^History"] = osFilename;
+        oLabel.del("History");
     }
 
     // Deal with other objects that have StartByte & Bytes
@@ -3454,9 +3481,6 @@ void ISIS3Dataset::BuildHistory()
         json_object_put(poObj);
     }
 
-    if( osHistory.empty() )
-        osHistory = " ";
-
     m_osHistory = osHistory;
 }
 
diff --git a/frmts/pds/nasakeywordhandler.cpp b/frmts/pds/nasakeywordhandler.cpp
index 0936f01..1520b34 100644
--- a/frmts/pds/nasakeywordhandler.cpp
+++ b/frmts/pds/nasakeywordhandler.cpp
@@ -54,8 +54,9 @@
 #include "nasakeywordhandler.h"
 #include "ogrgeojsonreader.h"
 #include "ogr_json_header.h"
+#include <vector>
 
-CPL_CVSID("$Id: nasakeywordhandler.cpp 38306 2017-05-14 09:21:58Z rouault $");
+CPL_CVSID("$Id: nasakeywordhandler.cpp 39701 2017-08-01 08:40:38Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -244,29 +245,37 @@ int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue,
     osValue = "";
     bool bIsString = true;
 
-    // Handle value lists like:     Name   = (Red, Red) or  {Red, Red}
+    // Handle value lists like:
+    // Name   = (Red, Red) or  {Red, Red} or even ((Red, Red), (Red, Red))
     json_object* poArray = NULL;
     if( *pszHeaderNext == '(' || *pszHeaderNext == '{' )
     {
-        const char chBeginList = *pszHeaderNext;
-        const char chEndList = *pszHeaderNext == '(' ? ')' : '}';
+        std::vector<char> oStackArrayBeginChar;
         CPLString osWord;
 
         poArray = json_object_new_array();
 
-        bool bFirst = true;
-        bool bEndOfList = false;
-        pszHeaderNext ++; // skip ( or {
         while( ReadWord( osWord, m_bStripSurroundingQuotes,
-                         true, &bIsString, &bEndOfList,
-                         chEndList ) )
+                         true, &bIsString ) )
         {
-            SkipWhite();
+            if( *pszHeaderNext == '(' ||  *pszHeaderNext == '{' )
+            {
+                oStackArrayBeginChar.push_back(*pszHeaderNext);
+                osValue += *pszHeaderNext;
+                pszHeaderNext ++;
+            }
 
+            // TODO: we could probably do better with nested json arrays
+            // instead of flattening when there are (( )) or ({ }) constructs
             if( bIsString )
             {
-                json_object_array_add( poArray,
-                                json_object_new_string( osWord.c_str() ) );
+                if( !(osWord.empty() && (*pszHeaderNext == '(' || 
+                      *pszHeaderNext == '{' || *pszHeaderNext == ')' ||
+                      *pszHeaderNext == '}')) )
+                {
+                    json_object_array_add( poArray,
+                                    json_object_new_string( osWord.c_str() ) );
+                }
             }
             else  if( CPLGetValueType(osWord) == CPL_VALUE_INTEGER )
             {
@@ -279,16 +288,45 @@ int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue,
                     json_object_new_double(CPLAtof(osWord.c_str())));
             }
 
-            if( bFirst )
-                osValue += chBeginList;
             osValue += osWord;
-            bFirst = false;
-            if( bEndOfList )
+
+            if( *pszHeaderNext == ')' )
             {
-                osValue += chEndList;
-                break;
+                osValue += *pszHeaderNext;
+                if( oStackArrayBeginChar.empty() ||
+                    oStackArrayBeginChar.back() != '(' )
+                {
+                    CPLDebug("PDS", "Unpaired ( ) for %s", osName.c_str());
+                    json_object_put(poArray);
+                    return FALSE;
+                }
+                oStackArrayBeginChar.pop_back();
+                pszHeaderNext ++;
+                if( oStackArrayBeginChar.empty() )
+                    break;
             }
-            osValue += ",";
+            else if( *pszHeaderNext == '}' )
+            {
+                osValue += *pszHeaderNext;
+                if( oStackArrayBeginChar.empty() ||
+                    oStackArrayBeginChar.back() != '{' )
+                {
+                    CPLDebug("PDS", "Unpaired { } for %s", osName.c_str());
+                    json_object_put(poArray);
+                    return FALSE;
+                }
+                oStackArrayBeginChar.pop_back();
+                pszHeaderNext ++;
+                if( oStackArrayBeginChar.empty() )
+                    break;
+            }
+            else if( *pszHeaderNext == ',' )
+            {
+                osValue += *pszHeaderNext;
+                pszHeaderNext ++;
+            }
+            SkipWhite();
+
         }
     }
 
@@ -397,9 +435,7 @@ int NASAKeywordHandler::ReadPair( CPLString &osName, CPLString &osValue,
 int NASAKeywordHandler::ReadWord( CPLString &osWord,
                                   bool bStripSurroundingQuotes,
                                   bool bParseList,
-                                  bool* pbIsString,
-                                  bool* pbEndOfList,
-                                  char chEndList )
+                                  bool* pbIsString )
 
 {
     if( pbIsString )
@@ -445,13 +481,6 @@ int NASAKeywordHandler::ReadWord( CPLString &osWord,
             osWord += *(pszHeaderNext);
         pszHeaderNext ++;
 
-        if( bParseList )
-        {
-            if( pbEndOfList )
-                *pbEndOfList = (*pszHeaderNext == chEndList );
-            if (*pszHeaderNext == ',' || *pszHeaderNext == chEndList )
-                pszHeaderNext ++;
-        }
         return TRUE;
     }
 
@@ -490,7 +519,9 @@ int NASAKeywordHandler::ReadWord( CPLString &osWord,
      */
     while( *pszHeaderNext != '\0'
            && *pszHeaderNext != '='
-           && ((bParseList && *pszHeaderNext != ',' && *pszHeaderNext != chEndList) ||
+           && ((bParseList && *pszHeaderNext != ',' && *pszHeaderNext != '(' &&
+                *pszHeaderNext != ')'&& *pszHeaderNext != '{' &&
+                *pszHeaderNext != '}' ) ||
                (!bParseList && !isspace(static_cast<unsigned char>( *pszHeaderNext ) ))) )
     {
         osWord += *pszHeaderNext;
@@ -503,13 +534,7 @@ int NASAKeywordHandler::ReadWord( CPLString &osWord,
             SkipWhite();
         }
     }
-    if( bParseList )
-    {
-        if( pbEndOfList )
-            *pbEndOfList = (*pszHeaderNext == chEndList );
-        if (*pszHeaderNext == ',' || *pszHeaderNext == chEndList )
-            pszHeaderNext ++;
-    }
+
     if( pbIsString )
         *pbIsString = CPLGetValueType(osWord) == CPL_VALUE_STRING;
 
diff --git a/frmts/pds/nasakeywordhandler.h b/frmts/pds/nasakeywordhandler.h
index 249842c..f6c59a2 100644
--- a/frmts/pds/nasakeywordhandler.h
+++ b/frmts/pds/nasakeywordhandler.h
@@ -59,9 +59,7 @@ class CPL_DLL NASAKeywordHandler
     int     ReadWord( CPLString &osWord,
                       bool bStripSurroundingQuotes = false,
                       bool bParseList = false,
-                      bool* pbIsString = NULL,
-                      bool* pbEndOfList = NULL,
-                      char chEndList = '\0' );
+                      bool* pbIsString = NULL);
     int     ReadPair( CPLString &osName, CPLString &osValue, json_object* poCur );
     int     ReadGroup( const char *pszPathPrefix, json_object* poCur );
 
diff --git a/frmts/raw/cpgdataset.cpp b/frmts/raw/cpgdataset.cpp
index 832639d..10ce217 100644
--- a/frmts/raw/cpgdataset.cpp
+++ b/frmts/raw/cpgdataset.cpp
@@ -32,7 +32,7 @@
 #include "ogr_spatialref.h"
 #include "rawdataset.h"
 
-CPL_CVSID("$Id: cpgdataset.cpp 36763 2016-12-09 22:10:55Z rouault $");
+CPL_CVSID("$Id: cpgdataset.cpp 39930 2017-08-24 09:47:34Z rouault $");
 
 enum Interleave { BSQ, BIL, BIP };
 
@@ -1117,9 +1117,9 @@ GDALDataset *CPGDataset::Open( GDALOpenInfo * poOpenInfo )
     else
       poDS = reinterpret_cast<CPGDataset *>(
           InitializeType3Dataset( poOpenInfo->pszFilename ) );
+#endif
     if( poDS == NULL )
         return NULL;
-#endif
 
 /* -------------------------------------------------------------------- */
 /*      Check for overviews.                                            */
diff --git a/frmts/raw/fastdataset.cpp b/frmts/raw/fastdataset.cpp
index b3f2238..f1c5ae7 100644
--- a/frmts/raw/fastdataset.cpp
+++ b/frmts/raw/fastdataset.cpp
@@ -32,7 +32,7 @@
 #include "ogr_spatialref.h"
 #include "rawdataset.h"
 
-CPL_CVSID("$Id: fastdataset.cpp 39148 2017-06-17 07:09:58Z rouault $");
+CPL_CVSID("$Id: fastdataset.cpp 39809 2017-08-13 13:31:07Z rouault $");
 
 // static const int ADM_STD_HEADER_SIZE = 4608;  // Format specification says it
 static const int ADM_HEADER_SIZE = 5000;  // Should be 4608, but some vendors
@@ -994,7 +994,9 @@ GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo )
     {
         // Read corner coordinates
         pszTemp = strstr( pszGeomRecord, CORNER_UPPER_LEFT );
-        if ( pszTemp && !EQUAL( pszTemp, "" ) )
+        if ( pszTemp && !EQUAL( pszTemp, "" ) &&
+             strlen(pszTemp) >= strlen( CORNER_UPPER_LEFT ) +
+                                28 + CORNER_VALUE_SIZE + 1 )
         {
             pszTemp += strlen( CORNER_UPPER_LEFT ) + 28;
             dfULX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
@@ -1003,7 +1005,9 @@ GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo )
         }
 
         pszTemp = strstr( pszGeomRecord, CORNER_UPPER_RIGHT );
-        if ( pszTemp && !EQUAL( pszTemp, "" ) )
+        if ( pszTemp && !EQUAL( pszTemp, "" ) &&
+             strlen(pszTemp) >= strlen( CORNER_UPPER_RIGHT ) +
+                                28 + CORNER_VALUE_SIZE + 1 )
         {
             pszTemp += strlen( CORNER_UPPER_RIGHT ) + 28;
             dfURX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
@@ -1012,7 +1016,9 @@ GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo )
         }
 
         pszTemp = strstr( pszGeomRecord, CORNER_LOWER_LEFT );
-        if ( pszTemp && !EQUAL( pszTemp, "" ) )
+        if ( pszTemp && !EQUAL( pszTemp, "" ) &&
+             strlen(pszTemp) >= strlen( CORNER_LOWER_LEFT ) +
+                                28 + CORNER_VALUE_SIZE + 1 )
         {
             pszTemp += strlen( CORNER_LOWER_LEFT ) + 28;
             dfLLX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
@@ -1021,7 +1027,9 @@ GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo )
         }
 
         pszTemp = strstr( pszGeomRecord, CORNER_LOWER_RIGHT );
-        if ( pszTemp && !EQUAL( pszTemp, "" ) )
+        if ( pszTemp && !EQUAL( pszTemp, "" ) &&
+             strlen(pszTemp) >= strlen( CORNER_LOWER_RIGHT ) +
+                                28 + CORNER_VALUE_SIZE + 1 )
         {
             pszTemp += strlen( CORNER_LOWER_RIGHT ) + 28;
             dfLRX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE );
diff --git a/frmts/raw/gtxdataset.cpp b/frmts/raw/gtxdataset.cpp
index f95522a..000ff7e 100644
--- a/frmts/raw/gtxdataset.cpp
+++ b/frmts/raw/gtxdataset.cpp
@@ -32,7 +32,7 @@
 #include "ogr_srs_api.h"
 #include "rawdataset.h"
 
-CPL_CVSID("$Id: gtxdataset.cpp 38048 2017-04-17 19:04:42Z rouault $");
+CPL_CVSID("$Id: gtxdataset.cpp 39791 2017-08-11 00:12:52Z rouault $");
 
 /**
 
@@ -96,6 +96,66 @@ class GTXDataset : public RawDataset
 
 /************************************************************************/
 /* ==================================================================== */
+/*                           GTXRasterBand                              */
+/* ==================================================================== */
+/************************************************************************/
+
+class GTXRasterBand : public RawRasterBand
+{
+  public:
+
+                 GTXRasterBand( GDALDataset *poDS, int nBand, VSILFILE * fpRaw,
+                                 vsi_l_offset nImgOffset, int nPixelOffset,
+                                 int nLineOffset,
+                                 GDALDataType eDataType, int bNativeOrder );
+
+    virtual ~GTXRasterBand();
+
+    virtual double GetNoDataValue( int *pbSuccess = NULL ) override;
+};
+
+
+/************************************************************************/
+/*                            GTXRasterBand()                           */
+/************************************************************************/
+
+GTXRasterBand::GTXRasterBand( GDALDataset *poDSIn, int nBandIn,
+                                VSILFILE * fpRawIn, vsi_l_offset nImgOffsetIn,
+                                int nPixelOffsetIn, int nLineOffsetIn,
+                                GDALDataType eDataTypeIn, int bNativeOrderIn ) :
+    RawRasterBand( poDSIn, nBandIn, fpRawIn,
+                   nImgOffsetIn, nPixelOffsetIn, nLineOffsetIn,
+                   eDataTypeIn, bNativeOrderIn, TRUE )
+{
+}
+
+/************************************************************************/
+/*                           ~GTXRasterBand()                           */
+/************************************************************************/
+
+GTXRasterBand::~GTXRasterBand()
+{
+}
+
+/************************************************************************/
+/*                           GetNoDataValue()                           */
+/************************************************************************/
+
+double GTXRasterBand::GetNoDataValue( int *pbSuccess )
+{
+    if( pbSuccess )
+        *pbSuccess = TRUE;
+    int bSuccess = FALSE;
+    double dfNoData = GDALPamRasterBand::GetNoDataValue(&bSuccess);
+    if( bSuccess )
+    {
+        return dfNoData;
+    }
+    return -88.8888;
+}
+
+/************************************************************************/
+/* ==================================================================== */
 /*                              GTXDataset                              */
 /* ==================================================================== */
 /************************************************************************/
@@ -230,13 +290,12 @@ GDALDataset *GTXDataset::Open( GDALOpenInfo * poOpenInfo )
 /* -------------------------------------------------------------------- */
 /*      Create band information object.                                 */
 /* -------------------------------------------------------------------- */
-    RawRasterBand *poBand = new RawRasterBand(
+    GTXRasterBand *poBand = new GTXRasterBand(
         poDS, 1, poDS->fpImage,
         (poDS->nRasterYSize-1) * poDS->nRasterXSize*nDTSize + 40,
         nDTSize, poDS->nRasterXSize * -nDTSize,
         eDT,
-        !CPL_IS_LSB, TRUE, FALSE );
-    poBand->SetNoDataValue( -88.8888 );
+        !CPL_IS_LSB );
     poDS->SetBand( 1, poBand );
 
 /* -------------------------------------------------------------------- */
diff --git a/frmts/raw/rawdataset.cpp b/frmts/raw/rawdataset.cpp
index 007f138..8b91ac8 100644
--- a/frmts/raw/rawdataset.cpp
+++ b/frmts/raw/rawdataset.cpp
@@ -50,7 +50,7 @@
 #include "gdal.h"
 #include "gdal_priv.h"
 
-CPL_CVSID("$Id: rawdataset.cpp 37414 2017-02-18 12:13:26Z goatbar $");
+CPL_CVSID("$Id: rawdataset.cpp 40082 2017-09-12 13:58:48Z rouault $");
 
 /************************************************************************/
 /*                           RawRasterBand()                            */
@@ -1160,9 +1160,10 @@ CPLErr RawDataset::IRasterIO( GDALRWFlag eRWFlag,
         int iBandIndex = 0;
         for( ; iBandIndex < nBandCount; iBandIndex++ )
         {
-            RawRasterBand *poBand = static_cast<RawRasterBand *>(
+            RawRasterBand *poBand = dynamic_cast<RawRasterBand *>(
                 GetRasterBand(panBandMap[iBandIndex]));
-            if( !poBand->CanUseDirectIO(nXOff, nYOff,
+            if( poBand == NULL ||
+                !poBand->CanUseDirectIO(nXOff, nYOff,
                                         nXSize, nYSize, eBufType) )
             {
                 break;
diff --git a/frmts/srtmhgt/srtmhgtdataset.cpp b/frmts/srtmhgt/srtmhgtdataset.cpp
index 97f63a1..86657d4 100644
--- a/frmts/srtmhgt/srtmhgtdataset.cpp
+++ b/frmts/srtmhgt/srtmhgtdataset.cpp
@@ -40,7 +40,7 @@
 
 static const GInt16 SRTMHG_NODATA_VALUE = -32768;
 
-CPL_CVSID("$Id: srtmhgtdataset.cpp 37802 2017-03-19 22:34:53Z rouault $");
+CPL_CVSID("$Id: srtmhgtdataset.cpp 39919 2017-08-23 14:16:19Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -257,7 +257,8 @@ int SRTMHGTDataset::Identify( GDALOpenInfo * poOpenInfo )
     return Identify(&oOpenInfo);
   }
 
-  if( !EQUAL(fileName + strlen(fileName) - strlen(".hgt"), ".hgt") )
+  if( !EQUAL(fileName + strlen(fileName) - strlen(".hgt"), ".hgt") &&
+      !EQUAL(fileName + strlen(fileName) - strlen(".hgt.gz"), ".hgt.gz") )
     return FALSE;
 
 /* -------------------------------------------------------------------- */
diff --git a/frmts/vrt/vrtsourcedrasterband.cpp b/frmts/vrt/vrtsourcedrasterband.cpp
index 566e420..7accc54 100644
--- a/frmts/vrt/vrtsourcedrasterband.cpp
+++ b/frmts/vrt/vrtsourcedrasterband.cpp
@@ -49,7 +49,7 @@
 #include "gdal_priv.h"
 #include "ogr_geometry.h"
 
-CPL_CVSID("$Id: vrtsourcedrasterband.cpp 37310 2017-02-06 11:42:54Z goatbar $");
+CPL_CVSID("$Id: vrtsourcedrasterband.cpp 39729 2017-08-02 15:48:49Z rouault $");
 
 /*! @cond Doxygen_Suppress */
 
@@ -246,8 +246,7 @@ CPLErr VRTSourcedRasterBand::IRasterIO( GDALRWFlag eRWFlag,
         // Do nothing
     }
     else if( nPixelSpace == GDALGetDataTypeSizeBytes(eBufType) &&
-         (!m_bNoDataValueSet || (!CPLIsNan(m_dfNoDataValue) &&
-                                 m_dfNoDataValue == 0)) )
+         (!m_bNoDataValueSet || m_dfNoDataValue == 0.0) )
     {
         if( nLineSpace == nBufXSize * nPixelSpace )
         {
@@ -264,7 +263,7 @@ CPLErr VRTSourcedRasterBand::IRasterIO( GDALRWFlag eRWFlag,
             }
         }
     }
-    else if( m_bNoDataValueSet )
+    else
     {
         double dfWriteValue = 0.0;
         if( m_bNoDataValueSet )
@@ -359,7 +358,8 @@ int  VRTSourcedRasterBand::IGetDataCoverageStatus( int nXOff,
         if( !papoSources[iSource]->IsSimpleSource() )
         {
             delete poPolyNonCoveredBySources;
-            return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED;
+            return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
+                   GDAL_DATA_COVERAGE_STATUS_DATA;
         }
         VRTSimpleSource* poSS = reinterpret_cast<VRTSimpleSource*>(papoSources[iSource]);
         // Check if the AOI is fully inside the source
diff --git a/frmts/vrt/vrtsources.cpp b/frmts/vrt/vrtsources.cpp
index 672e313..c136a4c 100644
--- a/frmts/vrt/vrtsources.cpp
+++ b/frmts/vrt/vrtsources.cpp
@@ -64,7 +64,7 @@
 #define isnan std::isnan
 #endif
 
-CPL_CVSID("$Id: vrtsources.cpp 37723 2017-03-16 17:07:53Z rouault $");
+CPL_CVSID("$Id: vrtsources.cpp 39459 2017-07-04 11:57:39Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -2573,19 +2573,21 @@ CPLErr VRTComplexSource::RasterIOInternal( int nReqXOff, int nReqYOff,
             }
             else
             {
-                WorkingDT fResult = static_cast<WorkingDT>(m_dfScaleOff);
+                WorkingDT afResult[2] = {
+                    static_cast<WorkingDT>(m_dfScaleOff),
+                    0 };
 
                 if( m_nLUTItemCount )
-                    fResult = static_cast<WorkingDT>(LookupValue( fResult ));
+                    afResult[0] = static_cast<WorkingDT>(LookupValue( afResult[0] ));
 
-                if( m_nMaxValue != 0 && fResult > m_nMaxValue )
-                    fResult = static_cast<WorkingDT>(m_nMaxValue);
+                if( m_nMaxValue != 0 && afResult[0] > m_nMaxValue )
+                    afResult[0] = static_cast<WorkingDT>(m_nMaxValue);
 
                 if( eBufType == GDT_Byte )
                     *pDstLocation = static_cast<GByte>(
-                        std::min(255.0, std::max(0.0, fResult + 0.5)) );
+                        std::min(255.0, std::max(0.0, afResult[0] + 0.5)) );
                 else
-                    GDALCopyWords( &fResult, eWrkDataType, 0,
+                    GDALCopyWords( afResult, eWrkDataType, 0,
                                    pDstLocation, eBufType, 0, 1 );
             }
         }
diff --git a/frmts/vrt/vrtwarped.cpp b/frmts/vrt/vrtwarped.cpp
index 902d0f8..b1f64dd 100644
--- a/frmts/vrt/vrtwarped.cpp
+++ b/frmts/vrt/vrtwarped.cpp
@@ -47,8 +47,9 @@
 #include "gdal_alg_priv.h"
 #include "gdal_priv.h"
 #include "gdalwarper.h"
+#include "ogr_geometry.h"
 
-CPL_CVSID("$Id: vrtwarped.cpp 37723 2017-03-16 17:07:53Z rouault $");
+CPL_CVSID("$Id: vrtwarped.cpp 39654 2017-07-24 19:24:32Z rouault $");
 
 /************************************************************************/
 /*                      GDALAutoCreateWarpedVRT()                       */
@@ -463,6 +464,70 @@ CPLErr VRTWarpedDataset::Initialize( void *psWO )
 }
 
 /************************************************************************/
+/*                        GDALWarpCoordRescaler                         */
+/************************************************************************/
+
+class GDALWarpCoordRescaler: public OGRCoordinateTransformation
+{
+    double m_dfRatioX;
+    double m_dfRatioY;
+
+public:
+    GDALWarpCoordRescaler(double dfRatioX, double dfRatioY) :
+        m_dfRatioX(dfRatioX), m_dfRatioY(dfRatioY) {}
+
+    virtual ~GDALWarpCoordRescaler() {}
+
+    virtual OGRSpatialReference *GetSourceCS() override { return NULL; }
+
+    virtual OGRSpatialReference *GetTargetCS() override { return NULL; }
+
+    virtual int Transform( int nCount, double *x, double *y, double *z )
+                                                                    override
+    {
+        return TransformEx( nCount, x, y, z, NULL );
+    }
+
+    virtual int TransformEx( int nCount, double *x, double *y, double * /*z*/,
+                             int *pabSuccess ) override
+    {
+        for( int i = 0; i < nCount; i++ )
+        {
+            x[i] *= m_dfRatioX;
+            y[i] *= m_dfRatioY;
+            if( pabSuccess )
+                pabSuccess[i] = TRUE;
+        }
+        return TRUE;
+    }
+};
+
+/************************************************************************/
+/*                        RescaleDstGeoTransform()                      */
+/************************************************************************/
+
+static void RescaleDstGeoTransform(double adfDstGeoTransform[6],
+                                   int nRasterXSize, int nDstPixels,
+                                   int nRasterYSize, int nDstLines,
+                                   double dfTargetRatio)
+{
+    if( adfDstGeoTransform[2] == 0.0 && adfDstGeoTransform[4] == 0.0 )
+    {
+        adfDstGeoTransform[1]
+            *= static_cast<double>( nRasterXSize ) / nDstPixels;
+        adfDstGeoTransform[5]
+            *= static_cast<double>( nRasterYSize ) / nDstLines;
+    }
+    else
+    {
+        adfDstGeoTransform[1] *= dfTargetRatio;
+        adfDstGeoTransform[2] *= dfTargetRatio;
+        adfDstGeoTransform[4] *= dfTargetRatio;
+        adfDstGeoTransform[5] *= dfTargetRatio;
+    }
+}
+
+/************************************************************************/
 /*                        CreateImplicitOverviews()                     */
 /*                                                                      */
 /*      For each overview of the source dataset, create an overview     */
@@ -526,20 +591,10 @@ void VRTWarpedDataset::CreateImplicitOverviews()
 
         double adfDstGeoTransform[6] = { 0.0 };
         GetGeoTransform(adfDstGeoTransform);
-        if( adfDstGeoTransform[2] == 0.0 && adfDstGeoTransform[4] == 0.0 )
-        {
-            adfDstGeoTransform[1]
-                *= static_cast<double>( nRasterXSize ) / nDstPixels;
-            adfDstGeoTransform[5]
-                *= static_cast<double>( nRasterYSize ) / nDstLines;
-        }
-        else
-        {
-            adfDstGeoTransform[1] *= dfTargetRatio;
-            adfDstGeoTransform[2] *= dfTargetRatio;
-            adfDstGeoTransform[4] *= dfTargetRatio;
-            adfDstGeoTransform[5] *= dfTargetRatio;
-        }
+        RescaleDstGeoTransform(adfDstGeoTransform,
+                               nRasterXSize, nDstPixels,
+                               nRasterYSize, nDstLines,
+                               dfTargetRatio);
 
         if( nDstPixels < 1 || nDstLines < 1 )
         {
@@ -566,10 +621,25 @@ void VRTWarpedDataset::CreateImplicitOverviews()
         psWOOvr->pTransformerArg = pTransformerArg;
 
 /* -------------------------------------------------------------------- */
-/*      Update the transformer to include an output geotransform        */
-/*      back to pixel/line coordinates.                                 */
-/*                                                                      */
+/*      We need to rescale the potential CUTLINE                        */
+/* -------------------------------------------------------------------- */
+        if( psWOOvr->hCutline )
+        {
+            GDALWarpCoordRescaler oRescaler(1.0 / dfSrcRatioX,
+                                            1.0 / dfSrcRatioY);
+            reinterpret_cast<OGRGeometry*>(psWOOvr->hCutline)->
+                                                    transform(&oRescaler);
+        }
+
 /* -------------------------------------------------------------------- */
+/*      Rescale the output geotransform on the transformer.             */
+/* -------------------------------------------------------------------- */
+        GDALGetTransformerDstGeoTransform(
+            psWOOvr->pTransformerArg, adfDstGeoTransform );
+        RescaleDstGeoTransform(adfDstGeoTransform,
+                               nRasterXSize, nDstPixels,
+                               nRasterYSize, nDstLines,
+                               dfTargetRatio);
         GDALSetTransformerDstGeoTransform(
             psWOOvr->pTransformerArg, adfDstGeoTransform );
 
diff --git a/frmts/xyz/xyzdataset.cpp b/frmts/xyz/xyzdataset.cpp
index b3c58d1..d41a3db 100644
--- a/frmts/xyz/xyzdataset.cpp
+++ b/frmts/xyz/xyzdataset.cpp
@@ -34,7 +34,7 @@
 #include <algorithm>
 #include <vector>
 
-CPL_CVSID("$Id: xyzdataset.cpp 39210 2017-06-20 18:19:21Z rouault $");
+CPL_CVSID("$Id: xyzdataset.cpp 39396 2017-06-30 09:23:09Z rouault $");
 
 static const double RELATIVE_ERROR = 1e-3;
 
@@ -64,6 +64,7 @@ class XYZDataset : public GDALPamDataset
     int         bSameNumberOfValuesPerLine;
     double      dfMinZ;
     double      dfMaxZ;
+    bool        bEOF;
 
     static int          IdentifyEx( GDALOpenInfo *, int&, int& nCommentLineCount );
 
@@ -149,11 +150,16 @@ CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
     {
         poGDS->nDataLineNum = 0;
         poGDS->nLineNum = 0;
+        poGDS->bEOF = false;
         VSIFSeekL(poGDS->fp, 0, SEEK_SET);
 
         for(int i=0;i<poGDS->nCommentLineCount;i++)
         {
-            CPLReadLine2L(poGDS->fp, 100, NULL);
+            if( CPLReadLine2L(poGDS->fp, 100, NULL) == NULL )
+            {
+                poGDS->bEOF = true;
+                return CE_Failure;
+            }
             poGDS->nLineNum ++;
         }
 
@@ -161,12 +167,15 @@ CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
         {
             const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL);
             if (pszLine == NULL)
+            {
+                poGDS->bEOF = true;
                 return CE_Failure;
+            }
             poGDS->nLineNum ++;
         }
     }
 
-    if( !poGDS->bSameNumberOfValuesPerLine && nBlockYOff != nLastYOff + 1 )
+    if( !poGDS->bSameNumberOfValuesPerLine )
     {
         if( nBlockYOff < nLastYOff )
         {
@@ -179,6 +188,10 @@ CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
         }
         else
         {
+            if( poGDS->bEOF )
+            {
+                return CE_Failure;
+            }
             for( int iY = nLastYOff + 1; iY < nBlockYOff; iY++ )
             {
                 if( IReadBlock(0, iY, NULL) != CE_None )
@@ -186,13 +199,20 @@ CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
             }
         }
     }
-    else if( poGDS->bSameNumberOfValuesPerLine )
+    else
     {
+        if( poGDS->bEOF )
+        {
+            return CE_Failure;
+        }
         while(poGDS->nDataLineNum < nLineInFile)
         {
             const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL);
             if (pszLine == NULL)
+            {
+                poGDS->bEOF = true;
                 return CE_Failure;
+            }
             poGDS->nLineNum ++;
 
             const char* pszPtr = pszLine;
@@ -242,6 +262,7 @@ CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff,
             const char* pszLine = CPLReadLine2L(poGDS->fp, 100, NULL);
             if (pszLine == NULL)
             {
+                poGDS->bEOF = true;
                 if( poGDS->bSameNumberOfValuesPerLine )
                 {
                     CPLError(CE_Failure, CPLE_AppDefined,
@@ -453,7 +474,8 @@ XYZDataset::XYZDataset() :
     nDataLineNum(GINTBIG_MAX),
     bSameNumberOfValuesPerLine(TRUE),
     dfMinZ(0),
-    dfMaxZ(0)
+    dfMaxZ(0),
+    bEOF(false)
 {
     adfGeoTransform[0] = 0;
     adfGeoTransform[1] = 1;
@@ -662,7 +684,13 @@ GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )
     int nMinTokens = 0;
 
     for( int i = 0; i < nCommentLineCount; i++ )
-        CPLReadLine2L(fp, 100, NULL);
+    {
+        if( CPLReadLine2L(fp, 100, NULL) == NULL )
+        {
+            VSIFCloseL(fp);
+            return NULL;
+        }
+    }
 
 /* -------------------------------------------------------------------- */
 /*      Parse header line                                               */
@@ -802,6 +830,7 @@ GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )
         }
 
         char chLocalDecimalSep = chDecimalSep ? chDecimalSep : '.';
+        int nUsefulColsFound = 0;
         while((ch = *pszPtr) != '\0')
         {
             if (ch == ' ')
@@ -820,11 +849,18 @@ GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )
                 if (bLastWasSep)
                 {
                     if (nCol == nXIndex)
+                    {
+                        nUsefulColsFound ++;
                         dfX = CPLAtofDelim(pszPtr, chLocalDecimalSep);
+                    }
                     else if (nCol == nYIndex)
+                    {
+                        nUsefulColsFound ++;
                         dfY = CPLAtofDelim(pszPtr, chLocalDecimalSep);
+                    }
                     else if (nCol == nZIndex)
                     {
+                        nUsefulColsFound ++;
                         dfZ = CPLAtofDelim(pszPtr, chLocalDecimalSep);
                         if( nDataLineNum == 0 )
                         {
@@ -881,6 +917,14 @@ GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo )
             VSIFCloseL(fp);
             return NULL;
         }
+        if( nUsefulColsFound != 3 )
+        {
+            CPLError(CE_Failure, CPLE_AppDefined,
+                     "At line " CPL_FRMT_GIB ", did not find X, Y and/or Z values",
+                      nLineNum);
+            VSIFCloseL(fp);
+            return NULL;
+        }
 
         if (nDataLineNum == 1)
         {
diff --git a/gcore/gdal.h b/gcore/gdal.h
index eed5437..76411f0 100644
--- a/gcore/gdal.h
+++ b/gcore/gdal.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal.h 37723 2017-03-16 17:07:53Z rouault $
+ * $Id: gdal.h 39834 2017-08-16 12:20:23Z rouault $
  *
  * Project:  GDAL Core
  * Purpose:  GDAL Core C/Public declarations.
@@ -483,6 +483,7 @@ int          CPL_DLL CPL_STDCALL GDALDumpOpenDatasets( FILE * );
 GDALDriverH CPL_DLL CPL_STDCALL GDALGetDriverByName( const char * );
 int CPL_DLL         CPL_STDCALL GDALGetDriverCount( void );
 GDALDriverH CPL_DLL CPL_STDCALL GDALGetDriver( int );
+GDALDriverH CPL_DLL CPL_STDCALL GDALCreateDriver( void );
 void        CPL_DLL CPL_STDCALL GDALDestroyDriver( GDALDriverH );
 int         CPL_DLL CPL_STDCALL GDALRegisterDriver( GDALDriverH );
 void        CPL_DLL CPL_STDCALL GDALDeregisterDriver( GDALDriverH );
diff --git a/gcore/gdal_misc.cpp b/gcore/gdal_misc.cpp
index 5ccce78..1eb545a 100644
--- a/gcore/gdal_misc.cpp
+++ b/gcore/gdal_misc.cpp
@@ -57,7 +57,7 @@
 #include "ogr_core.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: gdal_misc.cpp 36763 2016-12-09 22:10:55Z rouault $");
+CPL_CVSID("$Id: gdal_misc.cpp 39789 2017-08-10 18:42:40Z rouault $");
 
 /************************************************************************/
 /*                         GDALDataTypeUnion()                          */
@@ -2148,6 +2148,13 @@ double CPL_STDCALL GDALDecToPackedDMS( double dfDec )
  * inputs.  A special case has been implemented for corner corner coordinates
  * given in TL, TR, BR, BL order.  So when using this to get a geotransform
  * from 4 corner coordinates, pass them in this order.
+ * 
+ * Starting with GDAL 2.2.2, if bApproxOK = FALSE, the
+ * GDAL_GCPS_TO_GEOTRANSFORM_APPROX_OK configuration option will be read. If
+ * set to YES, then bApproxOK will be overriden with TRUE.
+ * Starting with GDAL 2.2.2, when exact fit is asked, the
+ * GDAL_GCPS_TO_GEOTRANSFORM_APPROX_THRESHOLD configuration option can be set to
+ * give the maximum error threshold in pixel. The default is 0.25.
  *
  * @param nGCPCount the number of GCPs being passed in.
  * @param pasGCPs the list of GCP structures.
@@ -2167,6 +2174,20 @@ GDALGCPsToGeoTransform( int nGCPCount, const GDAL_GCP *pasGCPs,
                         double *padfGeoTransform, int bApproxOK )
 
 {
+    double dfPixelThreshold = 0.25;
+    if( !bApproxOK )
+    {
+        bApproxOK =
+            CPLTestBool(CPLGetConfigOption(
+                            "GDAL_GCPS_TO_GEOTRANSFORM_APPROX_OK", "NO"));
+        if( !bApproxOK )
+        {
+            dfPixelThreshold =
+                CPLAtof(CPLGetConfigOption(
+                    "GDAL_GCPS_TO_GEOTRANSFORM_APPROX_THRESHOLD", "0.25"));
+        }
+    }
+
 /* -------------------------------------------------------------------- */
 /*      Recognise a few special cases.                                  */
 /* -------------------------------------------------------------------- */
@@ -2413,8 +2434,8 @@ GDALGCPsToGeoTransform( int nGCPCount, const GDAL_GCP *pasGCPs,
                  + padfGeoTransform[3])
                 - pasGCPs[i].dfGCPY;
 
-            if( std::abs(dfErrorX) > 0.25 * dfPixelSize
-                || std::abs(dfErrorY) > 0.25 * dfPixelSize )
+            if( std::abs(dfErrorX) > dfPixelThreshold * dfPixelSize
+                || std::abs(dfErrorY) > dfPixelThreshold * dfPixelSize )
             {
                 CPLDebug("GDAL", "dfErrorX/dfPixelSize = %.2f, "
                          "dfErrorY/dfPixelSize = %.2f",
diff --git a/gcore/gdal_priv.h b/gcore/gdal_priv.h
index c34d2f9..059435b 100644
--- a/gcore/gdal_priv.h
+++ b/gcore/gdal_priv.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal_priv.h 37723 2017-03-16 17:07:53Z rouault $
+ * $Id: gdal_priv.h 39966 2017-08-30 15:28:52Z rouault $
  *
  * Name:     gdal_priv.h
  * Project:  GDAL Core
@@ -725,6 +725,9 @@ class CPL_DLL GDALRasterBlock
     static int  FlushCacheBlock(int bDirtyBlocksOnly = FALSE);
     static void Verify();
 
+    static void EnterDisableDirtyBlockFlush();
+    static void LeaveDisableDirtyBlockFlush();
+
 #ifdef notdef
     static void CheckNonOrphanedBlocks(GDALRasterBand* poBand);
     void        DumpBlock();
diff --git a/gcore/gdal_version.h b/gcore/gdal_version.h
index 7d75746..68f26f1 100644
--- a/gcore/gdal_version.h
+++ b/gcore/gdal_version.h
@@ -1,4 +1,4 @@
-/* $Id: gdal_version.h 39236 2017-06-23 11:26:14Z rouault $ */
+/* $Id: gdal_version.h 40116 2017-09-15 10:35:19Z rouault $ */
 
 /* -------------------------------------------------------------------- */
 /*      GDAL Version Information.                                       */
@@ -7,7 +7,7 @@
 #ifndef GDAL_VERSION_MAJOR
 #  define GDAL_VERSION_MAJOR    2
 #  define GDAL_VERSION_MINOR    2
-#  define GDAL_VERSION_REV      1
+#  define GDAL_VERSION_REV      2
 #  define GDAL_VERSION_BUILD    0
 #endif
 
@@ -23,8 +23,8 @@
 #endif
 
 #ifndef GDAL_RELEASE_DATE
-#  define GDAL_RELEASE_DATE     20170623
+#  define GDAL_RELEASE_DATE     20170915
 #endif
 #ifndef GDAL_RELEASE_NAME
-#  define GDAL_RELEASE_NAME     "2.2.1"
+#  define GDAL_RELEASE_NAME     "2.2.2"
 #endif
diff --git a/gcore/gdaldriver.cpp b/gcore/gdaldriver.cpp
index e3f32c3..58cf36a 100644
--- a/gcore/gdaldriver.cpp
+++ b/gcore/gdaldriver.cpp
@@ -45,7 +45,7 @@
 #include "ogr_core.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: gdaldriver.cpp 37656 2017-03-09 13:19:58Z rouault $");
+CPL_CVSID("$Id: gdaldriver.cpp 39934 2017-08-24 14:12:19Z rouault $");
 
 CPL_C_START
 // TODO(schwehr): Why is this not in a header?
@@ -83,6 +83,21 @@ GDALDriver::~GDALDriver()
 }
 
 /************************************************************************/
+/*                         GDALCreateDriver()                           */
+/************************************************************************/
+
+/**
+ * \brief Create a GDALDriver.
+ *
+ * Creates a driver in the GDAL heap.
+ */
+
+GDALDriverH CPL_STDCALL GDALCreateDriver()
+{
+    return new GDALDriver();
+}
+
+/************************************************************************/
 /*                         GDALDestroyDriver()                          */
 /************************************************************************/
 
@@ -664,7 +679,11 @@ GDALDataset *GDALDriver::DefaultCreateCopy( const char * pszFilename,
     if( eErr != CE_None )
     {
         delete poDstDS;
-        Delete( pszFilename );
+        if( !CPLFetchBool(papszOptions, "APPEND_SUBDATASET", false) )
+        {
+            // Only delete if creating a new file
+            Delete( pszFilename );
+        }
         return NULL;
     }
     else
diff --git a/gcore/gdalproxydataset.cpp b/gcore/gdalproxydataset.cpp
index f111336..80e0d23 100644
--- a/gcore/gdalproxydataset.cpp
+++ b/gcore/gdalproxydataset.cpp
@@ -38,7 +38,7 @@
 #include "gdal.h"
 #include "gdal_priv.h"
 
-CPL_CVSID("$Id: gdalproxydataset.cpp 36526 2016-11-27 15:46:54Z goatbar $");
+CPL_CVSID("$Id: gdalproxydataset.cpp 40069 2017-09-11 16:51:01Z rouault $");
 
 /*! @cond Doxygen_Suppress */
 /* ******************************************************************** */
@@ -313,7 +313,28 @@ RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, SetMetadataItem,
                         (const char * pszName, const char * pszValue, const char * pszDomain),
                         (pszName, pszValue, pszDomain))
 
-RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, FlushCache, (), ())
+
+CPLErr GDALProxyRasterBand::FlushCache()
+{
+    // We need to make sure that all cached bocks at the proxy level are
+    // first flushed
+    CPLErr ret = GDALRasterBand::FlushCache();
+    if( ret == CE_None )
+    {
+        GDALRasterBand* poSrcBand = RefUnderlyingRasterBand();
+        if (poSrcBand)
+        {
+            ret = poSrcBand->FlushCache();
+            UnrefUnderlyingRasterBand(poSrcBand);
+        }
+        else
+        {
+            ret = CE_Failure;
+        }
+    }
+    return ret;
+}
+
 RB_PROXY_METHOD_WITH_RET(char**, NULL, GetCategoryNames, (), ())
 RB_PROXY_METHOD_WITH_RET(double, 0, GetNoDataValue, (int *pbSuccess), (pbSuccess))
 RB_PROXY_METHOD_WITH_RET(double, 0, GetMinimum, (int *pbSuccess), (pbSuccess))
diff --git a/gcore/gdalrasterblock.cpp b/gcore/gdalrasterblock.cpp
index 23c39a7..e8e0fc8 100644
--- a/gcore/gdalrasterblock.cpp
+++ b/gcore/gdalrasterblock.cpp
@@ -42,7 +42,7 @@
 #include "cpl_string.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: gdalrasterblock.cpp 36763 2016-12-09 22:10:55Z rouault $");
+CPL_CVSID("$Id: gdalrasterblock.cpp 39966 2017-08-30 15:28:52Z rouault $");
 
 static bool bCacheMaxInitialized = false;
 // Will later be overridden by the default 5% if GDAL_CACHEMAX not defined.
@@ -52,6 +52,8 @@ static volatile GIntBig nCacheUsed = 0;
 static GDALRasterBlock *poOldest = NULL;  // Tail.
 static GDALRasterBlock *poNewest = NULL;  // Head.
 
+static int nDisableDirtyBlockFlushCounter = 0;
+
 #if 0
 static CPLMutex *hRBLock = NULL;
 #define INITIALIZE_LOCK CPLMutexHolderD( &hRBLock )
@@ -436,7 +438,8 @@ int GDALRasterBlock::FlushCacheBlock( int bDirtyBlocksOnly )
 
         while( poTarget != NULL )
         {
-            if( !bDirtyBlocksOnly || poTarget->GetDirty() )
+            if( !bDirtyBlocksOnly ||
+                (poTarget->GetDirty() && nDisableDirtyBlockFlushCounter == 0) )
             {
                 if( CPLAtomicCompareAndExchange(
                         &(poTarget->nLockCount), 0, -1) )
@@ -507,6 +510,47 @@ void GDALRasterBlock::FlushDirtyBlocks()
 }
 
 /************************************************************************/
+/*                      EnterDisableDirtyBlockFlush()                   */
+/************************************************************************/
+
+/**
+ * \brief Starts preventing dirty blocks from being flushed
+ *
+ * This static method is used to prevent dirty blocks from being flushed.
+ * This might be useful when in a IWriteBlock() method, whose implementation
+ * can directly/indirectly cause the block cache to evict new blocks, to
+ * be recursively called on the same dataset.
+ *
+ * This method implements a reference counter and is thread-safe.
+ * 
+ * This call must be paired with a corresponding LeaveDisableDirtyBlockFlush().
+ *
+ * @since GDAL 2.2.2
+ */
+
+void GDALRasterBlock::EnterDisableDirtyBlockFlush()
+{
+    CPLAtomicInc(&nDisableDirtyBlockFlushCounter);
+}
+
+/************************************************************************/
+/*                      LeaveDisableDirtyBlockFlush()                   */
+/************************************************************************/
+
+/**
+ * \brief Ends preventing dirty blocks from being flushed.
+ *
+ * Undoes the effect of EnterDisableDirtyBlockFlush().
+ *
+ * @since GDAL 2.2.2
+ */
+
+void GDALRasterBlock::LeaveDisableDirtyBlockFlush()
+{
+    CPLAtomicDec(&nDisableDirtyBlockFlushCounter);
+}
+
+/************************************************************************/
 /*                          GDALRasterBlock()                           */
 /************************************************************************/
 
@@ -906,9 +950,13 @@ CPLErr GDALRasterBlock::Internalize()
             {
                 while( poTarget != NULL )
                 {
-                    if( CPLAtomicCompareAndExchange(
-                            &(poTarget->nLockCount), 0, -1) )
-                        break;
+                    if( !poTarget->GetDirty() ||
+                        nDisableDirtyBlockFlushCounter == 0 )
+                    {
+                        if( CPLAtomicCompareAndExchange(
+                                &(poTarget->nLockCount), 0, -1) )
+                            break;
+                    }
                     poTarget = poTarget->poPrevious;
                 }
 
diff --git a/man/man1/gdal-config.1 b/man/man1/gdal-config.1
index 161e398..a56e08f 100644
--- a/man/man1/gdal-config.1
+++ b/man/man1/gdal-config.1
@@ -1,4 +1,4 @@
-.TH "gdal-config" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal-config" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal2tiles.1 b/man/man1/gdal2tiles.1
index 4737a40..9e75fe5 100644
--- a/man/man1/gdal2tiles.1
+++ b/man/man1/gdal2tiles.1
@@ -1,4 +1,4 @@
-.TH "gdal2tiles" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal2tiles" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_calc.1 b/man/man1/gdal_calc.1
index bc6f63a..d03acb9 100644
--- a/man/man1/gdal_calc.1
+++ b/man/man1/gdal_calc.1
@@ -1,4 +1,4 @@
-.TH "gdal_calc" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_calc" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_contour.1 b/man/man1/gdal_contour.1
index e85245e..23094e2 100644
--- a/man/man1/gdal_contour.1
+++ b/man/man1/gdal_contour.1
@@ -1,4 +1,4 @@
-.TH "gdal_contour" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_contour" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_edit.1 b/man/man1/gdal_edit.1
index 90c6cfb..3d28ebe 100644
--- a/man/man1/gdal_edit.1
+++ b/man/man1/gdal_edit.1
@@ -1,4 +1,4 @@
-.TH "gdal_edit" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_edit" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_fillnodata.1 b/man/man1/gdal_fillnodata.1
index 5295419..7b61c92 100644
--- a/man/man1/gdal_fillnodata.1
+++ b/man/man1/gdal_fillnodata.1
@@ -1,4 +1,4 @@
-.TH "gdal_fillnodata" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_fillnodata" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_grid.1 b/man/man1/gdal_grid.1
index 0762938..29a0ef8 100644
--- a/man/man1/gdal_grid.1
+++ b/man/man1/gdal_grid.1
@@ -1,4 +1,4 @@
-.TH "gdal_grid" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_grid" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_merge.1 b/man/man1/gdal_merge.1
index fd46d8a..a73cf25 100644
--- a/man/man1/gdal_merge.1
+++ b/man/man1/gdal_merge.1
@@ -1,4 +1,4 @@
-.TH "gdal_merge" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_merge" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_pansharpen.1 b/man/man1/gdal_pansharpen.1
index 1b04e1f..1b1baf0 100644
--- a/man/man1/gdal_pansharpen.1
+++ b/man/man1/gdal_pansharpen.1
@@ -1,4 +1,4 @@
-.TH "gdal_pansharpen" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_pansharpen" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_polygonize.1 b/man/man1/gdal_polygonize.1
index da0ea3e..74a7d16 100644
--- a/man/man1/gdal_polygonize.1
+++ b/man/man1/gdal_polygonize.1
@@ -1,4 +1,4 @@
-.TH "gdal_polygonize" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_polygonize" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_proximity.1 b/man/man1/gdal_proximity.1
index d027498..8aa5863 100644
--- a/man/man1/gdal_proximity.1
+++ b/man/man1/gdal_proximity.1
@@ -1,4 +1,4 @@
-.TH "gdal_proximity" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_proximity" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_rasterize.1 b/man/man1/gdal_rasterize.1
index c5dee57..1369a9f 100644
--- a/man/man1/gdal_rasterize.1
+++ b/man/man1/gdal_rasterize.1
@@ -1,4 +1,4 @@
-.TH "gdal_rasterize" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_rasterize" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_retile.1 b/man/man1/gdal_retile.1
index f5d7d00..d44da6e 100644
--- a/man/man1/gdal_retile.1
+++ b/man/man1/gdal_retile.1
@@ -1,4 +1,4 @@
-.TH "gdal_retile" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_retile" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_sieve.1 b/man/man1/gdal_sieve.1
index 9b318c4..c3fed6d 100644
--- a/man/man1/gdal_sieve.1
+++ b/man/man1/gdal_sieve.1
@@ -1,4 +1,4 @@
-.TH "gdal_sieve" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_sieve" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_translate.1 b/man/man1/gdal_translate.1
index 3b25126..33ebda2 100644
--- a/man/man1/gdal_translate.1
+++ b/man/man1/gdal_translate.1
@@ -1,4 +1,4 @@
-.TH "gdal_translate" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_translate" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdal_utilities.1 b/man/man1/gdal_utilities.1
index 1e6243a..c2f47f6 100644
--- a/man/man1/gdal_utilities.1
+++ b/man/man1/gdal_utilities.1
@@ -1,4 +1,4 @@
-.TH "gdal_utilities" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdal_utilities" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaladdo.1 b/man/man1/gdaladdo.1
index 0857e0b..e2363ad 100644
--- a/man/man1/gdaladdo.1
+++ b/man/man1/gdaladdo.1
@@ -1,4 +1,4 @@
-.TH "gdaladdo" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaladdo" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalbuildvrt.1 b/man/man1/gdalbuildvrt.1
index 3347e69..b0e94de 100644
--- a/man/man1/gdalbuildvrt.1
+++ b/man/man1/gdalbuildvrt.1
@@ -1,4 +1,4 @@
-.TH "gdalbuildvrt" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalbuildvrt" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalcompare.1 b/man/man1/gdalcompare.1
index 5d285ef..1a02403 100644
--- a/man/man1/gdalcompare.1
+++ b/man/man1/gdalcompare.1
@@ -1,4 +1,4 @@
-.TH "gdalcompare" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalcompare" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaldem.1 b/man/man1/gdaldem.1
index 9a3a6e4..28a62dd 100644
--- a/man/man1/gdaldem.1
+++ b/man/man1/gdaldem.1
@@ -1,4 +1,4 @@
-.TH "gdaldem" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaldem" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalinfo.1 b/man/man1/gdalinfo.1
index 2294801..80ab275 100644
--- a/man/man1/gdalinfo.1
+++ b/man/man1/gdalinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalinfo" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalinfo" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdallocationinfo.1 b/man/man1/gdallocationinfo.1
index fe95694..cf7f44a 100644
--- a/man/man1/gdallocationinfo.1
+++ b/man/man1/gdallocationinfo.1
@@ -1,4 +1,4 @@
-.TH "gdallocationinfo" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdallocationinfo" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmanage.1 b/man/man1/gdalmanage.1
index 663ff57..e80a00f 100644
--- a/man/man1/gdalmanage.1
+++ b/man/man1/gdalmanage.1
@@ -1,4 +1,4 @@
-.TH "gdalmanage" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmanage" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalmove.1 b/man/man1/gdalmove.1
index 2dabd47..6d654d2 100644
--- a/man/man1/gdalmove.1
+++ b/man/man1/gdalmove.1
@@ -1,4 +1,4 @@
-.TH "gdalmove" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalmove" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalsrsinfo.1 b/man/man1/gdalsrsinfo.1
index 12d0f25..04694fa 100644
--- a/man/man1/gdalsrsinfo.1
+++ b/man/man1/gdalsrsinfo.1
@@ -1,4 +1,4 @@
-.TH "gdalsrsinfo" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalsrsinfo" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltindex.1 b/man/man1/gdaltindex.1
index 055922c..23e9651 100644
--- a/man/man1/gdaltindex.1
+++ b/man/man1/gdaltindex.1
@@ -1,4 +1,4 @@
-.TH "gdaltindex" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltindex" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdaltransform.1 b/man/man1/gdaltransform.1
index 53e1d65..1cb7dbb 100644
--- a/man/man1/gdaltransform.1
+++ b/man/man1/gdaltransform.1
@@ -1,4 +1,4 @@
-.TH "gdaltransform" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdaltransform" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gdalwarp.1 b/man/man1/gdalwarp.1
index 77871e4..81558e2 100644
--- a/man/man1/gdalwarp.1
+++ b/man/man1/gdalwarp.1
@@ -1,4 +1,4 @@
-.TH "gdalwarp" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gdalwarp" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnm_utilities.1 b/man/man1/gnm_utilities.1
index 6d9b086..f1f0cd3 100644
--- a/man/man1/gnm_utilities.1
+++ b/man/man1/gnm_utilities.1
@@ -1,4 +1,4 @@
-.TH "gnm_utilities" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gnm_utilities" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmanalyse.1 b/man/man1/gnmanalyse.1
index 5bbf260..4b107a7 100644
--- a/man/man1/gnmanalyse.1
+++ b/man/man1/gnmanalyse.1
@@ -1,4 +1,4 @@
-.TH "gnmanalyse" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmanalyse" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/gnmmanage.1 b/man/man1/gnmmanage.1
index edaebea..de93021 100644
--- a/man/man1/gnmmanage.1
+++ b/man/man1/gnmmanage.1
@@ -1,4 +1,4 @@
-.TH "gnmmanage" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "gnmmanage" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/nearblack.1 b/man/man1/nearblack.1
index 647cc57..ae4cd74 100644
--- a/man/man1/nearblack.1
+++ b/man/man1/nearblack.1
@@ -1,4 +1,4 @@
-.TH "nearblack" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "nearblack" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr2ogr.1 b/man/man1/ogr2ogr.1
index 00ff254..87e6258 100644
--- a/man/man1/ogr2ogr.1
+++ b/man/man1/ogr2ogr.1
@@ -1,4 +1,4 @@
-.TH "ogr2ogr" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr2ogr" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogr_utilities.1 b/man/man1/ogr_utilities.1
index 995383c..c11b809 100644
--- a/man/man1/ogr_utilities.1
+++ b/man/man1/ogr_utilities.1
@@ -1,4 +1,4 @@
-.TH "ogr_utilities" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogr_utilities" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrinfo.1 b/man/man1/ogrinfo.1
index 0b08dc8..53c266e 100644
--- a/man/man1/ogrinfo.1
+++ b/man/man1/ogrinfo.1
@@ -1,4 +1,4 @@
-.TH "ogrinfo" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrinfo" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrlineref.1 b/man/man1/ogrlineref.1
index 75f5b19..640fbf6 100644
--- a/man/man1/ogrlineref.1
+++ b/man/man1/ogrlineref.1
@@ -1,4 +1,4 @@
-.TH "ogrlineref" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrlineref" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrmerge.1 b/man/man1/ogrmerge.1
index 05e7080..9c76655 100644
--- a/man/man1/ogrmerge.1
+++ b/man/man1/ogrmerge.1
@@ -1,4 +1,4 @@
-.TH "ogrmerge" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrmerge" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/ogrtindex.1 b/man/man1/ogrtindex.1
index 57b5b85..b793f96 100644
--- a/man/man1/ogrtindex.1
+++ b/man/man1/ogrtindex.1
@@ -1,4 +1,4 @@
-.TH "ogrtindex" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "ogrtindex" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/pct2rgb.1 b/man/man1/pct2rgb.1
index 7efc979..6321825 100644
--- a/man/man1/pct2rgb.1
+++ b/man/man1/pct2rgb.1
@@ -1,4 +1,4 @@
-.TH "pct2rgb" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "pct2rgb" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/man/man1/rgb2pct.1 b/man/man1/rgb2pct.1
index 96130fb..da5837a 100644
--- a/man/man1/rgb2pct.1
+++ b/man/man1/rgb2pct.1
@@ -1,4 +1,4 @@
-.TH "rgb2pct" 1 "Fri Jun 23 2017" "GDAL" \" -*- nroff -*-
+.TH "rgb2pct" 1 "Fri Sep 15 2017" "GDAL" \" -*- nroff -*-
 .ad l
 .nh
 .SH NAME
diff --git a/nmake.opt b/nmake.opt
index cca273a..276686b 100644
--- a/nmake.opt
+++ b/nmake.opt
@@ -1,4 +1,4 @@
-# $Id: nmake.opt 37968 2017-04-12 07:16:55Z rouault $
+# $Id: nmake.opt 40036 2017-09-08 11:23:21Z rouault $
 #
 # nmake.opt - main configuration file for NMAKE makefiles.
 #
@@ -607,8 +607,10 @@ OCI_INCLUDE =	-I$(ORACLE_HOME)\oci\include
 #OPENJPEG_ENABLED = YES
 #OPENJPEG_CFLAGS = -IC:\openjpeg\include
 #OPENJPEG_LIB = C:\openjpeg\lib\openjp2.lib
-# For OpenJpeg >= 2.1, uncomment
+# For OpenJpeg 2.1.x, uncomment
 #OPENJPEG_VERSION = 20100
+# For OpenJpeg 2.2.x, uncomment
+#OPENJPEG_VERSION = 20200
 
 #if using an external zlib uncomment the following lines
 #ZLIB_EXTERNAL_LIB = 1
@@ -619,12 +621,14 @@ OCI_INCLUDE =	-I$(ORACLE_HOME)\oci\include
 # Uncomment POPPLER_BASE_STREAM_HAS_TWO_ARGS = YES for Poppler >= 0.16.0
 # Uncomment POPPLER_0_20_OR_LATER = YES for Poppler >= 0.20.0
 # Uncomment POPPLER_0_23_OR_LATER = YES for Poppler >= 0.23.0
+# Uncomment POPPLER_0_58_OR_LATER = YES for Poppler >= 0.58.0
 #POPPLER_ENABLED = YES
 #POPPLER_CFLAGS = -Ie:/kde/include -Ie:/kde/include/poppler
 #POPPLER_HAS_OPTCONTENT = YES
 #POPPLER_BASE_STREAM_HAS_TWO_ARGS = YES
 #POPPLER_0_20_OR_LATER = YES
 #POPPLER_0_23_OR_LATER = YES
+#POPPLER_0_58_OR_LATER = YES
 #POPPLER_LIBS = e:/kde/lib/poppler.lib e:/kde/lib/freetype.lib e:/kde/lib/liblcms-1.lib advapi32.lib gdi32.lib
 
 # Uncomment for PDF support
diff --git a/ogr/ogr_srs_esri.cpp b/ogr/ogr_srs_esri.cpp
index 486c86c..a750980 100644
--- a/ogr/ogr_srs_esri.cpp
+++ b/ogr/ogr_srs_esri.cpp
@@ -50,7 +50,7 @@
 #include "ogr_p.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: ogr_srs_esri.cpp 38677 2017-05-29 11:07:01Z rouault $");
+CPL_CVSID("$Id: ogr_srs_esri.cpp 39754 2017-08-04 19:05:00Z rouault $");
 
 extern void OGREPSGDatumNameMassage( char ** ppszDatum );
 
@@ -1666,6 +1666,8 @@ OGRErr OGRSpatialReference::morphToESRI()
     if( pszProjection != NULL && EQUAL(pszProjection, SRS_PT_MERCATOR_2SP) )
     {
         SetNode( "PROJCS|PROJECTION", "Mercator" );
+        if( (poProjCS = GetAttrNode( "PROJCS" )) != NULL )
+            poProjCSNodeChild = poProjCS->GetChild(0);
     }
 
     // See #4861.
@@ -1673,6 +1675,8 @@ OGRErr OGRSpatialReference::morphToESRI()
              EQUAL(pszProjection, SRS_PT_MERCATOR_1SP) )
     {
         SetNode( "PROJCS|PROJECTION", "Mercator" );
+        if( (poProjCS = GetAttrNode( "PROJCS" )) != NULL )
+            poProjCSNodeChild = poProjCS->GetChild(0);
 
         const double dfK0 = GetNormProjParm(SRS_PP_SCALE_FACTOR, 1.0);
 
@@ -1779,7 +1783,10 @@ OGRErr OGRSpatialReference::morphToESRI()
         CPLFree( newGcsName );
         pszGcsName = GetAttrValue( "GEOGCS" );
       }
-      RemapGeogCSName(this, pszGcsName);
+      if( pszGcsName != NULL )
+      {
+        RemapGeogCSName(this, pszGcsName);
+      }
 
       // Specific processing and remapping
       pszProjection = GetAttrValue("PROJECTION");
diff --git a/ogr/ogr_srs_proj4.cpp b/ogr/ogr_srs_proj4.cpp
index 2c750dc..477f846 100644
--- a/ogr/ogr_srs_proj4.cpp
+++ b/ogr/ogr_srs_proj4.cpp
@@ -49,7 +49,7 @@
 extern
 int EPSGGetWGS84Transform( int nGeogCS, std::vector<CPLString>& asTransform );
 
-CPL_CVSID("$Id: ogr_srs_proj4.cpp 36850 2016-12-13 23:53:14Z rouault $");
+CPL_CVSID("$Id: ogr_srs_proj4.cpp 40079 2017-09-12 13:15:16Z rouault $");
 
 /* -------------------------------------------------------------------- */
 /*      The following list comes from osrs/proj/src/pj_ellps.c.         */
@@ -922,6 +922,20 @@ OGRErr OGRSpatialReference::importFromProj4( const char * pszProj4 )
                     OSR_GDV( papszNV, "x_0", 0.0 ),
                     OSR_GDV( papszNV, "y_0", 0.0 ) );
         }
+        else if( CSLFetchNameValue(papszNV, "lat_1") &&
+                 CSLFetchNameValue(papszNV, "lon_1") &&
+                 CSLFetchNameValue(papszNV, "lat_2") &&
+                 CSLFetchNameValue(papszNV, "lon_2") )
+        {
+            SetHOM2PNO( OSR_GDV( papszNV, "lat_0", 0.0 ),
+                        OSR_GDV( papszNV, "lat_1", 0.0 ),
+                        OSR_GDV( papszNV, "lon_1", 0.0 ),
+                        OSR_GDV( papszNV, "lat_2", 0.0 ),
+                        OSR_GDV( papszNV, "lon_2", 0.0 ),
+                        OSR_GDV( papszNV, "k", 1.0 ),
+                        OSR_GDV( papszNV, "x_0", 0.0 ),
+                        OSR_GDV( papszNV, "y_0", 0.0 ) );
+        }
         else
         {
             SetHOMAC( OSR_GDV( papszNV, "lat_0", 0.0 ),
diff --git a/ogr/ogr_srs_validate.cpp b/ogr/ogr_srs_validate.cpp
index 9807505..4d8aeab 100644
--- a/ogr/ogr_srs_validate.cpp
+++ b/ogr/ogr_srs_validate.cpp
@@ -41,7 +41,7 @@
 #include "ogr_spatialref.h"
 #include "osr_cs_wkt.h"
 
-CPL_CVSID("$Id: ogr_srs_validate.cpp 36541 2016-11-28 18:32:25Z goatbar $");
+CPL_CVSID("$Id: ogr_srs_validate.cpp 40079 2017-09-12 13:15:16Z rouault $");
 
 // Why would fipszone and zone be parameters when they relate to a composite
 // projection which renders down into a non-zoned projection?
@@ -310,7 +310,7 @@ static const char * const papszProjWithParms[] = {
     SRS_PP_LATITUDE_OF_POINT_1,
     SRS_PP_LONGITUDE_OF_POINT_1,
     SRS_PP_LATITUDE_OF_POINT_2,
-    SRS_PP_LONGITUDE_OF_POINT_2
+    SRS_PP_LONGITUDE_OF_POINT_2,
     SRS_PP_SCALE_FACTOR,
     SRS_PP_FALSE_EASTING,
     SRS_PP_FALSE_NORTHING,
diff --git a/ogr/ograpispy.cpp b/ogr/ograpispy.cpp
index 9bb5970..0f1639d 100644
--- a/ogr/ograpispy.cpp
+++ b/ogr/ograpispy.cpp
@@ -40,7 +40,7 @@
 #include "ogr_spatialref.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ograpispy.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ograpispy.cpp 39853 2017-08-18 14:37:49Z rouault $");
 
 #ifdef OGRAPISPY_ENABLED
 
@@ -90,6 +90,7 @@ class FeatureDefnDescription
 }  // namespace
 
 static std::map<OGRDataSourceH, DatasetDescription> oMapDS;
+static std::set<int> oSetDSIndex;
 static std::map<OGRLayerH, CPLString> oGlobalMapLayer;
 static OGRLayerH hLayerGetNextFeature = NULL;
 static OGRLayerH hLayerGetLayerDefn = NULL;
@@ -232,8 +233,11 @@ static CPLString OGRAPISpyGetDSVar( OGRDataSourceH hDS )
 {
     if( hDS && oMapDS.find(hDS) == oMapDS.end() )
     {
-        int i = static_cast<int>(oMapDS.size()) + 1;
+        int i = 1;
+        while( oSetDSIndex.find(i) != oSetDSIndex.end() )
+            i ++;
         oMapDS[hDS] = DatasetDescription(i);
+        oSetDSIndex.insert(i);
     }
     return CPLSPrintf("ds%d", hDS ? oMapDS[hDS].iDS : 0);
 }
@@ -553,6 +557,7 @@ void OGRAPISpyPreClose( OGRDataSourceH hDS )
 {
     OGRAPISpyFlushDefered();
     fprintf(fpSpyFile, "ds%d = None\n", oMapDS[hDS].iDS);
+    oSetDSIndex.erase(oMapDS[hDS].iDS);
     oMapDS.erase(hDS);
     OGRAPISpyFileClose();
 }
diff --git a/ogr/ogrcompoundcurve.cpp b/ogr/ogrcompoundcurve.cpp
index 9d07918..badea8b 100644
--- a/ogr/ogrcompoundcurve.cpp
+++ b/ogr/ogrcompoundcurve.cpp
@@ -38,7 +38,7 @@
 #include "ogr_p.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: ogrcompoundcurve.cpp 36501 2016-11-25 14:09:24Z rouault $");
+CPL_CVSID("$Id: ogrcompoundcurve.cpp 39408 2017-06-30 19:01:20Z jef $");
 
 /************************************************************************/
 /*                         OGRCompoundCurve()                           */
@@ -590,8 +590,17 @@ OGRErr OGRCompoundCurve::addCurveDirectlyInternal( OGRCurve* poCurve,
             fabs(end.getY() - start.getY()) > dfToleranceEps ||
             fabs(end.getZ() - start.getZ()) > dfToleranceEps )
         {
-            CPLError(CE_Failure, CPLE_AppDefined, "Non contiguous curves");
-            return OGRERR_FAILURE;
+            poCurve->EndPoint(&start);
+            if( fabs(end.getX() - start.getX()) > dfToleranceEps ||
+                fabs(end.getY() - start.getY()) > dfToleranceEps ||
+                fabs(end.getZ() - start.getZ()) > dfToleranceEps )
+            {
+                CPLError(CE_Failure, CPLE_AppDefined, "Non contiguous curves");
+                return OGRERR_FAILURE;
+            }
+
+            CPLDebug("GML", "reversing curve");
+            ((OGRSimpleCurve*)poCurve)->reversePoints();
         }
         // Patch so that it matches exactly.
         ((OGRSimpleCurve*)poCurve)->setPoint(0, &end);
diff --git a/ogr/ogrcurve.cpp b/ogr/ogrcurve.cpp
index e06aeb7..25c05ef 100644
--- a/ogr/ogrcurve.cpp
+++ b/ogr/ogrcurve.cpp
@@ -29,7 +29,7 @@
 #include "ogr_geometry.h"
 #include "ogr_p.h"
 
-CPL_CVSID("$Id: ogrcurve.cpp 36883 2016-12-15 13:31:12Z rouault $");
+CPL_CVSID("$Id: ogrcurve.cpp 39950 2017-08-28 07:33:38Z rouault $");
 
 //! @cond Doxygen_Suppress
 
@@ -87,6 +87,8 @@ int OGRCurve::getDimension() const
  * Tests if a curve is closed. A curve is closed if its start point is
  * equal to its end point.
  *
+ * For equality tests, the M dimension is ignored.
+ *
  * This method relates to the SFCOM ICurve::get_IsClosed() method.
  *
  * @return TRUE if closed, else FALSE.
@@ -101,33 +103,7 @@ int OGRCurve::get_IsClosed() const
     OGRPoint oEndPoint;
     EndPoint( &oEndPoint );
 
-    if (oStartPoint.IsMeasured() && oEndPoint.IsMeasured())
-    {
-        // XYZM type
-        if (oStartPoint.Is3D() && oEndPoint.Is3D())
-        {
-            if( oStartPoint.getX() == oEndPoint.getX() && oStartPoint.getY() == oEndPoint.getY()
-                && oStartPoint.getZ() == oEndPoint.getZ() && oStartPoint.getM() == oEndPoint.getM())
-            {
-                return TRUE;
-            }
-            else
-                return FALSE;
-        }
-        // XYM type
-        else
-        {
-            if( oStartPoint.getX() == oEndPoint.getX() && oStartPoint.getY() == oEndPoint.getY()
-                && oStartPoint.getM() == oEndPoint.getM())
-            {
-                return TRUE;
-            }
-            else
-                return FALSE;
-        }
-    }
-
-    else if (oStartPoint.Is3D() && oEndPoint.Is3D())
+    if (oStartPoint.Is3D() && oEndPoint.Is3D())
     {
         // XYZ type
         if( oStartPoint.getX() == oEndPoint.getX() && oStartPoint.getY() == oEndPoint.getY()
@@ -146,13 +122,6 @@ int OGRCurve::get_IsClosed() const
         return FALSE;
     }
 
-    // one of the points is Measured
-    else if (((oStartPoint.IsMeasured() & oEndPoint.IsMeasured()) == 0) &&
-             ((oStartPoint.IsMeasured() | oEndPoint.IsMeasured()) == 1))
-    {
-        return FALSE;
-    }
-
     else
     {
         // XY type
diff --git a/ogr/ogrlinestring.cpp b/ogr/ogrlinestring.cpp
index 807f89d..060e9d4 100644
--- a/ogr/ogrlinestring.cpp
+++ b/ogr/ogrlinestring.cpp
@@ -34,7 +34,7 @@
 #include <cstdlib>
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrlinestring.cpp 36883 2016-12-15 13:31:12Z rouault $");
+CPL_CVSID("$Id: ogrlinestring.cpp 39951 2017-08-28 07:33:44Z rouault $");
 
 /************************************************************************/
 /*                           OGRSimpleCurve()                           */
@@ -507,11 +507,11 @@ void OGRSimpleCurve::setPoint( int iPoint, OGRPoint * poPoint )
 
 {
     if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) )
-        setPoint( iPoint, poPoint->getX(), poPoint->getY(), poPoint->getM() );
-    else if( flags & OGR_G_MEASURED )
-        setPointM( iPoint, poPoint->getX(), poPoint->getY(), poPoint->getM() );
+        setPoint( iPoint, poPoint->getX(), poPoint->getY(), poPoint->getZ(), poPoint->getM() );
     else if( flags & OGR_G_3D )
         setPoint( iPoint, poPoint->getX(), poPoint->getY(), poPoint->getZ() );
+    else if( flags & OGR_G_MEASURED )
+        setPointM( iPoint, poPoint->getX(), poPoint->getY(), poPoint->getM() );
     else
         setPoint( iPoint, poPoint->getX(), poPoint->getY() );
 }
@@ -763,10 +763,14 @@ void OGRSimpleCurve::setM( int iPoint, double mIn )
 void OGRSimpleCurve::addPoint( const OGRPoint * poPoint )
 
 {
-    if( poPoint->getCoordinateDimension() < 3 )
-        setPoint( nPointCount, poPoint->getX(), poPoint->getY() );
-    else
+    if( poPoint->Is3D() && poPoint->IsMeasured() )
+        setPoint( nPointCount, poPoint->getX(), poPoint->getY(), poPoint->getZ(), poPoint->getM() );
+    else if( poPoint->Is3D() )
         setPoint( nPointCount, poPoint->getX(), poPoint->getY(), poPoint->getZ() );
+    else if( poPoint->IsMeasured() )
+        setPointM( nPointCount, poPoint->getX(), poPoint->getY(), poPoint->getM() );
+    else
+        setPoint( nPointCount, poPoint->getX(), poPoint->getY() );
 }
 
 /************************************************************************/
diff --git a/ogr/ogrsf_frmts/avc/avc_rawbin.c b/ogr/ogrsf_frmts/avc/avc_rawbin.c
index d82e9a1..80adcd8 100644
--- a/ogr/ogrsf_frmts/avc/avc_rawbin.c
+++ b/ogr/ogrsf_frmts/avc/avc_rawbin.c
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: avc_rawbin.c 34524 2016-07-03 02:47:25Z goatbar $
+ * $Id: avc_rawbin.c 39390 2017-06-29 20:27:27Z rouault $
  *
  * Name:     avc_rawbin.c
  * Project:  Arc/Info vector coverage (AVC)  BIN->E00 conversion library
@@ -383,7 +383,7 @@ void AVCRawBinFSeek(AVCRawBinFile *psFile, int nOffset, int nFrom)
         psFile->nCurPos = 0;
         psFile->nCurSize = 0;
         psFile->nOffset = psFile->nOffset+nTarget;
-        if( VSIFSeek(psFile->fp, psFile->nOffset+nTarget, SEEK_SET) < 0 )
+        if( VSIFSeek(psFile->fp, psFile->nOffset, SEEK_SET) < 0 )
             return;
     }
 
diff --git a/ogr/ogrsf_frmts/dxf/ogrdxf_dimension.cpp b/ogr/ogrsf_frmts/dxf/ogrdxf_dimension.cpp
index 0f09fc9..0b19dfd 100644
--- a/ogr/ogrsf_frmts/dxf/ogrdxf_dimension.cpp
+++ b/ogr/ogrsf_frmts/dxf/ogrdxf_dimension.cpp
@@ -31,7 +31,7 @@
 #include "ogr_dxf.h"
 #include "cpl_conv.h"
 
-CPL_CVSID("$Id: ogrdxf_dimension.cpp 37040 2016-12-30 15:31:43Z rouault $");
+CPL_CVSID("$Id: ogrdxf_dimension.cpp 39427 2017-07-01 11:46:32Z rouault $");
 
 /************************************************************************/
 /*                         TranslateDIMENSION()                         */
@@ -126,7 +126,12 @@ OGRFeature *OGRDXFLayer::TranslateDIMENSION()
             break;
         }
     }
-
+    if( nCode < 0 )
+    {
+        DXF_LAYER_READER_ERROR();
+        delete poFeature;
+        return NULL;
+    }
     if( nCode == 0 )
         poDS->UnreadValue();
 
@@ -360,7 +365,11 @@ the approach is as above in all these cases.
 void OGRDXFLayer::FormatDimension( CPLString &osText, double dfValue )
 
 {
-    const int nPrecision = atoi(poDS->GetVariable("$LUPREC","4"));
+    int nPrecision = atoi(poDS->GetVariable("$LUPREC","4"));
+    if( nPrecision < 0 )
+        nPrecision = 0;
+    else if( nPrecision > 20 )
+        nPrecision = 20;
 
     // We could do a significantly more precise formatting if we want
     // to spend the effort.  See QCAD's rs_dimlinear.cpp and related files
diff --git a/ogr/ogrsf_frmts/dxf/ogrdxflayer.cpp b/ogr/ogrsf_frmts/dxf/ogrdxflayer.cpp
index b8a1248..68d95fd 100644
--- a/ogr/ogrsf_frmts/dxf/ogrdxflayer.cpp
+++ b/ogr/ogrsf_frmts/dxf/ogrdxflayer.cpp
@@ -34,7 +34,7 @@
 
 #include <cmath>
 
-CPL_CVSID("$Id: ogrdxflayer.cpp 38666 2017-05-29 10:03:12Z rouault $");
+CPL_CVSID("$Id: ogrdxflayer.cpp 40061 2017-09-10 12:00:28Z rouault $");
 
 /************************************************************************/
 /*                            OGRDXFLayer()                             */
@@ -200,8 +200,8 @@ void OGRDXFLayer::PrepareLineStyle( OGRFeature *poFeature )
 /* -------------------------------------------------------------------- */
 /*      Is the layer disabled/hidden/frozen/off?                        */
 /* -------------------------------------------------------------------- */
-    int bHidden =
-        EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1");
+    const char* pszHidden = poDS->LookupLayerProperty( osLayer, "Hidden" );
+    const bool bHidden = pszHidden && EQUAL(pszHidden, "1");
 
 /* -------------------------------------------------------------------- */
 /*      Work out the color for this feature.                            */
@@ -786,8 +786,8 @@ OGRFeature *OGRDXFLayer::TranslateTEXT()
 /* -------------------------------------------------------------------- */
     CPLString osLayer = poFeature->GetFieldAsString("Layer");
 
-    int bHidden =
-        EQUAL(poDS->LookupLayerProperty( osLayer, "Hidden" ), "1");
+    const char* pszHidden = poDS->LookupLayerProperty( osLayer, "Hidden" );
+    const bool bHidden = pszHidden && EQUAL(pszHidden, "1");
 
 /* -------------------------------------------------------------------- */
 /*      Work out the color for this feature.                            */
@@ -2520,6 +2520,17 @@ OGRFeature *OGRDXFLayer::GetNextUnfilteredFeature()
                           szLineBuf );
             }
         }
+
+        // If there are no more features, but we do still have pending features
+        // (for example, after an INSERT), return the first pending feature.
+        if ( poFeature == NULL && !apoPendingFeatures.empty() )
+        {
+            poFeature = apoPendingFeatures.front();
+            apoPendingFeatures.pop();
+
+            poFeature->SetFID( iNextFID++ );
+            return poFeature;
+        }
     }
 
 /* -------------------------------------------------------------------- */
diff --git a/ogr/ogrsf_frmts/dxf/ogrdxfwriterds.cpp b/ogr/ogrsf_frmts/dxf/ogrdxfwriterds.cpp
index 981c2e9..a4e4159 100644
--- a/ogr/ogrsf_frmts/dxf/ogrdxfwriterds.cpp
+++ b/ogr/ogrsf_frmts/dxf/ogrdxfwriterds.cpp
@@ -33,7 +33,7 @@
 #include "cpl_string.h"
 #include "cpl_vsi_error.h"
 
-CPL_CVSID("$Id: ogrdxfwriterds.cpp 37091 2017-01-10 17:25:57Z rouault $");
+CPL_CVSID("$Id: ogrdxfwriterds.cpp 39877 2017-08-19 18:06:16Z rouault $");
 
 /************************************************************************/
 /*                          OGRDXFWriterDS()                          */
@@ -749,6 +749,8 @@ bool OGRDXFWriterDS::WriteNewBlockRecords( VSILFILE * fpIn )
 bool OGRDXFWriterDS::WriteNewBlockDefinitions( VSILFILE * fpIn )
 
 {
+    if( poLayer == NULL )
+        poLayer = new OGRDXFWriterLayer( this, fpTemp );
     poLayer->ResetFP( fpIn );
 
 /* ==================================================================== */
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
index 5200694..3ed7718 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp
@@ -33,7 +33,11 @@
 #include <json.h> // JSON-C
 #include <ogr_api.h>
 
-CPL_CVSID("$Id: ogrgeojsonreader.cpp 38123 2017-04-23 11:20:44Z rouault $");
+CPL_CVSID("$Id: ogrgeojsonreader.cpp 40040 2017-09-08 22:18:53Z rouault $");
+
+static
+OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj,
+                                     OGRSpatialReference* poLayerSRS );
 
 /************************************************************************/
 /*                           OGRGeoJSONReader                           */
@@ -219,7 +223,7 @@ void OGRGeoJSONReader::ReadLayer( OGRGeoJSONDataSource* poDS,
         || GeoJSONObject::eMultiPolygon == objType
         || GeoJSONObject::eGeometryCollection == objType )
     {
-        OGRGeometry* poGeometry = ReadGeometry( poObj );
+        OGRGeometry* poGeometry = ReadGeometry( poObj, poLayer->GetSpatialRef() );
         if( !AddFeature( poLayer, poGeometry ) )
         {
             CPLDebug( "GeoJSON", "Translation of single geometry failed." );
@@ -879,7 +883,7 @@ bool OGRGeoJSONReader::GenerateFeatureDefn( OGRGeoJSONLayer* poLayer,
         json_object_object_foreachC( poObjProps, it )
         {
             int nFldIndex = poDefn->GetFieldIndex( it.key );
-            if( -1 == nFldIndex )
+            if( -1 == nFldIndex && !bIsGeocouchSpatiallistFormat )
             {
                 // Detect the special kind of GeoJSON output by a spatiallist of
                 // GeoCouch such as:
@@ -1005,9 +1009,10 @@ bool OGRGeoJSONReader::AddFeature( OGRGeoJSONLayer* poLayer,
 /*                           ReadGeometry                               */
 /************************************************************************/
 
-OGRGeometry* OGRGeoJSONReader::ReadGeometry( json_object* poObj )
+OGRGeometry* OGRGeoJSONReader::ReadGeometry( json_object* poObj,
+                                             OGRSpatialReference* poLayerSRS )
 {
-    OGRGeometry* poGeometry = OGRGeoJSONReadGeometry( poObj );
+    OGRGeometry* poGeometry = OGRGeoJSONReadGeometry( poObj, poLayerSRS );
 
 /* -------------------------------------------------------------------- */
 /*      Wrap geometry with GeometryCollection as a common denominator.  */
@@ -1344,7 +1349,8 @@ OGRFeature* OGRGeoJSONReader::ReadFeature( OGRGeoJSONLayer* poLayer,
         // NOTE: If geometry can not be parsed or read correctly
         //       then NULL geometry is assigned to a feature and
         //       geometry type for layer is classified as wkbUnknown.
-        OGRGeometry* poGeometry = ReadGeometry( poObjGeom );
+        OGRGeometry* poGeometry = ReadGeometry( poObjGeom,
+                                                poLayer->GetSpatialRef() );
         if( NULL != poGeometry )
         {
             poFeature->SetGeometryDirectly( poGeometry );
@@ -1521,6 +1527,13 @@ GeoJSONObject::Type OGRGeoJSONGetType( json_object* poObj )
 
 OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj )
 {
+    return OGRGeoJSONReadGeometry(poObj, NULL);
+}
+
+OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj,
+                                     OGRSpatialReference* poLayerSRS )
+{
+
     OGRGeometry* poGeometry = NULL;
 
     GeoJSONObject::Type objType = OGRGeoJSONGetType( poObj );
@@ -1560,9 +1573,15 @@ OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj )
                 }
             }
         }
+        else if( poLayerSRS )
+        {
+            poGeometry->assignSpatialReference(poLayerSRS);
+        }
         else
+        {
             // Assign WGS84 if no CRS defined on geometry.
             poGeometry->assignSpatialReference(OGRSpatialReference::GetWGS84SRS());
+        }
     }
     return poGeometry;
 }
diff --git a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h
index 4eee0bf..d642b96 100644
--- a/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h
+++ b/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogrgeojsonreader.h 38146 2017-04-26 14:09:40Z rouault $
+ * $Id: ogrgeojsonreader.h 39706 2017-08-01 13:54:05Z rouault $
  *
  * Project:  OpenGIS Simple Features Reference Implementation
  * Purpose:  Defines GeoJSON reader within OGR OGRGeoJSON Driver.
@@ -143,7 +143,7 @@ class OGRGeoJSONReader
     static bool AddFeature( OGRGeoJSONLayer* poLayer, OGRGeometry* poGeometry );
     static bool AddFeature( OGRGeoJSONLayer* poLayer, OGRFeature* poFeature );
 
-    OGRGeometry* ReadGeometry( json_object* poObj );
+    OGRGeometry* ReadGeometry( json_object* poObj, OGRSpatialReference* poLayerSRS );
     OGRFeature* ReadFeature( OGRGeoJSONLayer* poLayer, json_object* poObj );
     void ReadFeatureCollection( OGRGeoJSONLayer* poLayer, json_object* poObj );
 };
diff --git a/ogr/ogrsf_frmts/gml/gmlreader.cpp b/ogr/ogrsf_frmts/gml/gmlreader.cpp
index acacdb6..0f166c5 100644
--- a/ogr/ogrsf_frmts/gml/gmlreader.cpp
+++ b/ogr/ogrsf_frmts/gml/gmlreader.cpp
@@ -44,7 +44,7 @@
 #include "gmlutils.h"
 #include "ogr_geometry.h"
 
-CPL_CVSID("$Id: gmlreader.cpp 38566 2017-05-21 16:59:47Z rouault $");
+CPL_CVSID("$Id: gmlreader.cpp 39985 2017-09-02 20:44:23Z rouault $");
 
 /************************************************************************/
 /*                            ~IGMLReader()                             */
@@ -1129,7 +1129,7 @@ void GMLReader::SetFeaturePropertyDirectly( const char *pszElement,
 /* -------------------------------------------------------------------- */
 /*      Do we need to update the property type?                         */
 /* -------------------------------------------------------------------- */
-    if( !poClass->IsSchemaLocked() )
+    if( !poClass->IsSchemaLocked() && !EQUAL(pszValue, OGR_GML_NULL) )
     {
         poClass->GetProperty(iProperty)->AnalysePropertyValue(
             poFeature->GetProperty(iProperty), m_bSetWidthFlag );
diff --git a/ogr/ogrsf_frmts/gml/gmlutils.cpp b/ogr/ogrsf_frmts/gml/gmlutils.cpp
index 524a99d..06b6f99 100644
--- a/ogr/ogrsf_frmts/gml/gmlutils.cpp
+++ b/ogr/ogrsf_frmts/gml/gmlutils.cpp
@@ -43,7 +43,7 @@
 #include "ogr_p.h"
 #include "ogr_spatialref.h"
 
-CPL_CVSID("$Id: gmlutils.cpp 37914 2017-04-06 17:38:46Z rouault $");
+CPL_CVSID("$Id: gmlutils.cpp 40033 2017-09-08 07:33:53Z rouault $");
 
 /************************************************************************/
 /*                GML_ExtractSrsNameFromGeometry()                      */
@@ -100,6 +100,12 @@ bool GML_IsSRSLatLongOrder(const char *pszSRSName)
         // Shortcut.
         return true;
     }
+    /* fguuid:jgd20??.bl (Japanese FGD GML v4) */
+    else if( EQUALN(pszSRSName, "fguuid:jgd2011.bl", 17) ||
+            EQUALN(pszSRSName, "fguuid:jgd2001.bl", 17) )
+    {
+        return true;
+    }
     else if( !EQUALN(pszSRSName, "EPSG:", 5) )
     {
         OGRSpatialReference oSRS;
@@ -108,13 +114,7 @@ bool GML_IsSRSLatLongOrder(const char *pszSRSName)
             if(oSRS.EPSGTreatsAsLatLong() || oSRS.EPSGTreatsAsNorthingEasting())
                 return true;
         }
-        return false;
     }
-    /* fguuid:jgd20??.bl (Japanese FGD GML v4) */
-    else if (strncmp(pszSRSName, "fguuid:jgd", 10) == 0 && strstr(pszSRSName, ".bl") != NULL) {
-        return true;
-    }
-
     return false;
 }
 
diff --git a/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h b/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
index 2acb84c..1425847 100644
--- a/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
+++ b/ogr/ogrsf_frmts/gmlas/ogr_gmlas.h
@@ -532,6 +532,7 @@ typedef enum
     GMLAS_FT_DOUBLE,
     GMLAS_FT_DECIMAL,
     GMLAS_FT_DATE,
+    GMLAS_FT_GYEAR,
     GMLAS_FT_TIME,
     GMLAS_FT_DATETIME,
     GMLAS_FT_BASE64BINARY,
@@ -875,6 +876,11 @@ class GMLASSchemaAnalyzer
         /** Set of schemas opened */
         std::set<CPLString> m_oSetSchemaURLs;
 
+        /** Map from namespace URI to namespace prefix coming from the
+         * examination of xmlns:foo=bar attributes of the top element of the
+         * GML document */
+        std::map<CPLString,CPLString> m_oMapDocNSURIToPrefix;
+
         static bool IsSame( const XSModelGroup* poModelGroup1,
                                   const XSModelGroup* poModelGroup2 );
         XSModelGroupDefinition* GetGroupDefinition( const XSModelGroup* poModelGroup );
@@ -971,6 +977,8 @@ class GMLASSchemaAnalyzer
                                     { m_bPGIdentifierLaundering = b; }
         void SetMaximumFieldsForFlattening(int n)
                                     { m_nMaximumFieldsForFlattening = n; }
+        void SetMapDocNSURIToPrefix(const std::map<CPLString,CPLString>& oMap)
+                                    { m_oMapDocNSURIToPrefix = oMap; }
 
         bool Analyze(GMLASXSDCache& oCache,
                      const CPLString& osBaseDirname,
diff --git a/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h b/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
index 00d101e..b42ca4f 100644
--- a/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
+++ b/ogr/ogrsf_frmts/gmlas/ogr_gmlas_consts.h
@@ -290,6 +290,7 @@ namespace GMLASConstants
     STRING_CONST(szXS_DOUBLE, "double");
     STRING_CONST(szXS_DECIMAL, "decimal");
     STRING_CONST(szXS_DATE, "date");
+    STRING_CONST(szXS_GYEAR, "gYear");
     STRING_CONST(szXS_TIME, "time");
     STRING_CONST(szXS_DATETIME, "dateTime");
     STRING_CONST(szXS_ANY_URI, "anyURI");
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
index 7ca70b5..37b4639 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasdatasource.cpp
@@ -36,7 +36,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgmlasdatasource.cpp 38073 2017-04-20 17:00:47Z rouault $");
+CPL_CVSID("$Id: ogrgmlasdatasource.cpp 39652 2017-07-24 17:32:40Z rouault $");
 
 /************************************************************************/
 /*                          OGRGMLASDataSource()                        */
@@ -300,6 +300,7 @@ class GMLASTopElementParser : public DefaultHandler
             int         m_nStartElementCounter;
             bool        m_bFinish;
             bool        m_bFoundSWE;
+            std::map<CPLString,CPLString> m_oMapDocNSURIToPrefix;
 
     public:
                         GMLASTopElementParser();
@@ -311,6 +312,8 @@ class GMLASTopElementParser : public DefaultHandler
         const std::vector<PairURIFilename>& GetXSDs() const
                                             { return m_aoFilenames; }
         bool GetSWE() const { return m_bFoundSWE; }
+        const std::map<CPLString,CPLString>& GetMapDocNSURIToPrefix() const
+                                            { return m_oMapDocNSURIToPrefix; }
 
         virtual void startElement(
             const   XMLCh* const    uri,
@@ -435,6 +438,15 @@ void GMLASTopElementParser::startElement(
             CPLDebug("GMLAS", "SWE namespace found");
             m_bFoundSWE = true;
         }
+        else if( osAttrURIPrefix == szXMLNS_URI && !osAttrValue.empty() &&
+                 !osAttrLocalname.empty() )
+        {
+#ifdef DEBUG_VERBOSE
+            CPLDebug("GMLAS", "Namespace %s = %s",
+                     osAttrLocalname.c_str(), osAttrValue.c_str() );
+#endif
+            m_oMapDocNSURIToPrefix[ osAttrValue ] = osAttrLocalname;
+        }
     }
 
     if( m_nStartElementCounter == 1 )
@@ -807,6 +819,8 @@ bool OGRGMLASDataSource::Open(GDALOpenInfo* poOpenInfo)
         {
             m_bFoundSWE = true;
         }
+        oAnalyzer.SetMapDocNSURIToPrefix(
+                                    topElementParser.GetMapDocNSURIToPrefix());
     }
     std::vector<PairURIFilename> aoXSDs;
     if( osXSDFilenames.empty() )
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasfeatureclass.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasfeatureclass.cpp
index a2115dd..f98846c 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasfeatureclass.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasfeatureclass.cpp
@@ -31,7 +31,7 @@
 // Must be first for DEBUG_BOOL case
 #include "ogr_gmlas.h"
 
-CPL_CVSID("$Id: ogrgmlasfeatureclass.cpp 37133 2017-01-12 22:00:33Z rouault $");
+CPL_CVSID("$Id: ogrgmlasfeatureclass.cpp 39652 2017-07-24 17:32:40Z rouault $");
 
 /************************************************************************/
 /*                              GMLASField()                            */
@@ -99,6 +99,8 @@ GMLASFieldType GMLASField::GetTypeFromString( const CPLString& osType )
         return GMLAS_FT_DECIMAL;
     else if( osType == szXS_DATE )
         return GMLAS_FT_DATE;
+    else if( osType == szXS_GYEAR )
+        return GMLAS_FT_GYEAR;
     else if( osType == szXS_TIME )
         return GMLAS_FT_TIME;
     else if( osType == szXS_DATETIME )
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
index ce4eabe..7d35885 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlaslayer.cpp
@@ -32,7 +32,7 @@
 #include "ogr_gmlas.h"
 #include "cpl_minixml.h"
 
-CPL_CVSID("$Id: ogrgmlaslayer.cpp 38073 2017-04-20 17:00:47Z rouault $");
+CPL_CVSID("$Id: ogrgmlaslayer.cpp 39652 2017-07-24 17:32:40Z rouault $");
 
 /************************************************************************/
 /*                            OGRGMLASLayer()                           */
@@ -340,7 +340,10 @@ void OGRGMLASLayer::ProcessDataRecordCreateFields(
                     CPLXMLNode* psDupTree = CPLCloneXMLTree(psChildNode);
                     CPLXMLNode* psValue = CPLGetXMLNode(psDupTree, "value");
                     if( psValue != NULL )
+                    {
                         CPLRemoveXMLChild(psDupTree, psValue);
+                        CPLDestroyXMLNode(psValue);
+                    }
                     char* pszXML = CPLSerializeXMLTree(psDupTree);
                     CPLDestroyXMLNode(psDupTree);
                     poFieldDescFeature->SetField( szFIELD_DOCUMENTATION, pszXML);
@@ -804,6 +807,9 @@ void OGRGMLASLayer::PostInit( bool bIncludeGeometryXML )
             case GMLAS_FT_DATE:
                 eType = OFTDate;
                 break;
+            case GMLAS_FT_GYEAR:
+                eType = OFTInteger;
+                break;
             case GMLAS_FT_TIME:
                 eType = OFTTime;
                 break;
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
index bef859e..791b935 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasreader.cpp
@@ -35,7 +35,7 @@
 
 #include "ogr_json_header.h"
 
-CPL_CVSID("$Id: ogrgmlasreader.cpp 38073 2017-04-20 17:00:47Z rouault $");
+CPL_CVSID("$Id: ogrgmlasreader.cpp 39652 2017-07-24 17:32:40Z rouault $");
 
 /************************************************************************/
 /*                        GMLASBinInputStream                           */
@@ -1411,6 +1411,20 @@ void GMLASReader::startElement(
             /* in swe:extension */
             idx = m_oCurCtxt.m_poLayer->GetOGRFieldIndexFromXPath(
               m_oCurCtxt.m_poLayer->GetFeatureClass().GetXPath() + szMATCH_ALL);
+            if( idx >= 0 &&
+                m_oCurCtxt.m_poLayer->GetFeatureClass().GetFields().size() > 1 )
+            {
+                // But only match this wildcard field if it is the only child
+                // of the feature class, otherwise that is going to prevent
+                // matching regular fields
+                // Practical case  the <any processContents="lax" minOccurs="0" maxOccurs="unbounded">
+                // declaratin of
+                // http://schemas.earthresourceml.org/earthresourceml-lite/1.0/erml-lite.xsd 
+                // http://services.ga.gov.au/earthresource/ows?service=wfs&version=2.0.0&request=GetFeature&typenames=erl:CommodityResourceView&count=10
+                // FIXME: currently we will thus ignore those extra content
+                // See ogr_gmlas_any_field_at_end_of_declaration test case
+                idx = -1;
+            }
         }
 
         if( idx >= 0 || geom_idx >= 0 )
@@ -1774,7 +1788,7 @@ void GMLASReader::startElement(
             m_nCurGeomFieldIdx = -1;
         }
 
-        if( !bHasProcessedAttributes )
+        if( !bHasProcessedAttributes && m_nLevelSilentIgnoredXPath < 0 )
             ProcessAttributes(attrs);
     }
     else
@@ -1826,6 +1840,8 @@ void GMLASReader::ProcessAttributes(const Attributes& attrs)
             osAttrXPath += osAttrLocalname;
         }
 
+        //CPLDebug("GMLAS", "Attr %s=%s", osAttrXPath.c_str(), osAttrValue.c_str());
+
         const int nAttrIdx = m_oCurCtxt.m_poLayer->
                                     GetOGRFieldIndexFromXPath(osAttrXPath);
         int nFCIdx;
@@ -1911,6 +1927,17 @@ void GMLASReader::ProcessAttributes(const Attributes& attrs)
                 // In validation mode, fixed attributes not present in the
                 // document are still reported, which cause spurious warnings
             }
+            else if( m_bValidate &&
+                     (nFCIdx = m_oCurCtxt.m_poLayer->
+                        GetFCFieldIndexFromXPath(osAttrXPath)) >= 0 &&
+                     !m_oCurCtxt.m_poLayer->GetFeatureClass().
+                        GetFields()[nFCIdx].GetDefaultValue().empty() &&
+                     m_oCurCtxt.m_poLayer->GetFeatureClass().
+                        GetFields()[nFCIdx].GetDefaultValue() == m_osAttrValue )
+            {
+                // In validation mode, default attributes not present in the
+                // document are still reported, which cause spurious warnings
+            }
             else if( m_oIgnoredXPathMatcher.MatchesRefXPath(
                                         osAttrXPath, osMatchedXPath) )
             {
@@ -2728,6 +2755,21 @@ void GMLASReader::ProcessSWEDataRecord(CPLXMLNode* psRoot)
 }
 
 /************************************************************************/
+/*                            GMLASGetSRSName()                         */
+/************************************************************************/
+
+static const char* GMLASGetSRSName(CPLXMLNode* psNode)
+{
+    const char* pszSRSName = CPLGetXMLValue(psNode, szSRS_NAME, NULL);
+    if( pszSRSName == NULL )
+    {
+        // Case of a gml:Point where the srsName is on the gml:pos
+        pszSRSName = CPLGetXMLValue(psNode, "gml:pos.srsName", NULL);
+    }
+    return pszSRSName;
+}
+
+/************************************************************************/
 /*                            ProcessGeometry()                         */
 /************************************************************************/
 
@@ -2739,8 +2781,7 @@ void GMLASReader::ProcessGeometry(CPLXMLNode* psRoot)
 
     if( m_bInitialPass )
     {
-        const char* pszSRSName = CPLGetXMLValue(psRoot,
-                                                szSRS_NAME, NULL);
+        const char* pszSRSName = GMLASGetSRSName(psRoot);
         if( pszSRSName != NULL )
         {
             // If we are doing a first pass, store the SRS of the geometry
@@ -2786,8 +2827,8 @@ void GMLASReader::ProcessGeometry(CPLXMLNode* psRoot)
                     (OGR_G_CreateFromGMLTree( psRoot ));
     if( poGeom != NULL )
     {
-        const char* pszSRSName = CPLGetXMLValue(psRoot,
-                                                szSRS_NAME, NULL);
+        const char* pszSRSName = GMLASGetSRSName(psRoot);
+
         bool bSwapXY = false;
         if( pszSRSName != NULL )
         {
diff --git a/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp b/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
index 8dba4f0..6512f8f 100644
--- a/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
+++ b/ogr/ogrsf_frmts/gmlas/ogrgmlasschemaanalyzer.cpp
@@ -41,7 +41,7 @@ static XSModel* getGrammarPool(XMLGrammarPool* pool)
 #include "ogr_gmlas.h"
 #include "ogr_pgdump.h"
 
-CPL_CVSID("$Id: ogrgmlasschemaanalyzer.cpp 38073 2017-04-20 17:00:47Z rouault $");
+CPL_CVSID("$Id: ogrgmlasschemaanalyzer.cpp 39652 2017-07-24 17:32:40Z rouault $");
 
 /************************************************************************/
 /*                        IsCompatibleOfArray()                         */
@@ -67,13 +67,16 @@ static bool IsCompatibleOfArray( GMLASFieldType eType )
 class GMLASPrefixMappingHander: public DefaultHandler
 {
         std::map<CPLString, CPLString>& m_oMapURIToPrefix;
+        const std::map<CPLString, CPLString>& m_oMapDocNSURIToPrefix;
         CPLString& m_osGMLVersionFound;
 
   public:
         GMLASPrefixMappingHander(
                         std::map<CPLString, CPLString>& oMapURIToPrefix,
+                        const std::map<CPLString, CPLString>& oMapDocNSURIToPrefix,
                         CPLString& osGMLVersionFound) :
             m_oMapURIToPrefix( oMapURIToPrefix ),
+            m_oMapDocNSURIToPrefix( oMapDocNSURIToPrefix ),
             m_osGMLVersionFound( osGMLVersionFound )
         {}
 
@@ -133,7 +136,16 @@ void GMLASPrefixMappingHander::startPrefixMapping(const XMLCh* const prefix,
                                                   const XMLCh* const uri)
 {
     const CPLString osURI( transcode(uri) );
-    const CPLString osPrefix( transcode(prefix) );
+    CPLString osPrefix( transcode(prefix) );
+    if( osPrefix.empty() )
+    {
+        std::map<CPLString, CPLString>::const_iterator oIter 
+            = m_oMapDocNSURIToPrefix.find( osURI );
+        if( oIter != m_oMapDocNSURIToPrefix.end() )
+        {
+            osPrefix = oIter->second;
+        }
+    }
     if( !osPrefix.empty() )
     {
         std::map<CPLString, CPLString>::iterator oIter =
@@ -161,6 +173,7 @@ static
 void CollectNamespacePrefixes(const char* pszXSDFilename,
                               VSILFILE* fpXSD,
                               std::map<CPLString, CPLString>& oMapURIToPrefix,
+                              const std::map<CPLString, CPLString>& oMapDocNSURIToPrefix,
                               CPLString& osGMLVersionFound)
 {
     GMLASInputSource oSource(pszXSDFilename, fpXSD, false);
@@ -169,7 +182,9 @@ void CollectNamespacePrefixes(const char* pszXSDFilename,
     // loadGrammar(), so we have to parse the doc twice.
     SAX2XMLReader* poReader = XMLReaderFactory::createXMLReader ();
 
-    GMLASPrefixMappingHander contentHandler(oMapURIToPrefix, osGMLVersionFound);
+    GMLASPrefixMappingHander contentHandler(oMapURIToPrefix,
+                                            oMapDocNSURIToPrefix,
+                                            osGMLVersionFound);
     poReader->setContentHandler(&contentHandler);
 
     GMLASErrorHandler oErrorHandler;
@@ -186,13 +201,16 @@ void CollectNamespacePrefixes(const char* pszXSDFilename,
 class GMLASAnalyzerEntityResolver: public GMLASBaseEntityResolver
 {
         std::map<CPLString, CPLString>& m_oMapURIToPrefix;
+        const std::map<CPLString, CPLString>& m_oMapDocNSURIToPrefix;
 
   public:
         GMLASAnalyzerEntityResolver(const CPLString& osBasePath,
                             std::map<CPLString, CPLString>& oMapURIToPrefix,
+                            const std::map<CPLString, CPLString>& oMapDocNSURIToPrefix,
                             GMLASXSDCache& oCache)
             : GMLASBaseEntityResolver(osBasePath, oCache)
             , m_oMapURIToPrefix(oMapURIToPrefix)
+            , m_oMapDocNSURIToPrefix(oMapDocNSURIToPrefix)
         {
         }
 
@@ -209,6 +227,7 @@ void GMLASAnalyzerEntityResolver::DoExtraSchemaProcessing(
                                              VSILFILE* fp)
 {
     CollectNamespacePrefixes(osFilename, fp, m_oMapURIToPrefix,
+                             m_oMapDocNSURIToPrefix,
                              m_osGMLVersionFound);
     VSIFSeekL(fp, 0, SEEK_SET);
 }
@@ -860,6 +879,7 @@ bool GMLASSchemaAnalyzer::Analyze(GMLASXSDCache& oCache,
     std::vector<CPLString> aoNamespaces;
     GMLASAnalyzerEntityResolver oXSDEntityResolver( CPLString(),
                                                     m_oMapURIToPrefix,
+                                                    m_oMapDocNSURIToPrefix,
                                                     oCache );
 
     aoNamespaces.push_back("");
@@ -1590,8 +1610,8 @@ void GMLASSchemaAnalyzer::GetConcreteImplementationTypes(
                 {
                     apoImplEltList.push_back(poSubElt);
                 }
-                GetConcreteImplementationTypes(poSubElt, apoImplEltList);
             }
+            GetConcreteImplementationTypes(poSubElt, apoImplEltList);
         }
     }
 }
@@ -2596,7 +2616,8 @@ bool GMLASSchemaAnalyzer::ExploreModelGroup(
                 CPLDebug("GMLAS", "%s is in ignored xpaths",
                         oField.GetXPath().c_str());
 #endif
-                if( !oField.GetFixedValue().empty() )
+                if( !oField.GetFixedValue().empty() ||
+                    !oField.GetDefaultValue().empty() )
                 {
                     oField.SetIgnored();
                 }
@@ -2834,6 +2855,9 @@ bool GMLASSchemaAnalyzer::ExploreModelGroup(
             {
                 // Do nothing with it since it cannot be instantiated
                 // in a valid way.
+                CPLDebug("GMLAS",
+                         "Ignoring %s that is abstract without realizations",
+                         osElementXPath.c_str());
             }
 
             // Simple type like string, int, etc...
@@ -2980,7 +3004,8 @@ bool GMLASSchemaAnalyzer::ExploreModelGroup(
                         CPLDebug("GMLAS", "%s is in ignored xpaths",
                                  oField.GetXPath().c_str());
 #endif
-                        if( !oField.GetFixedValue().empty() )
+                        if( !oField.GetFixedValue().empty() ||
+                            !oField.GetDefaultValue().empty() )
                         {
                             oField.SetIgnored();
                         }
diff --git a/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp b/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp
index e598c9b..2c16785 100644
--- a/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp
+++ b/ogr/ogrsf_frmts/gpkg/gdalgeopackagerasterband.cpp
@@ -33,7 +33,7 @@
 #include <algorithm>
 #include <limits>
 
-CPL_CVSID("$Id: gdalgeopackagerasterband.cpp 37667 2017-03-09 22:57:57Z rouault $");
+CPL_CVSID("$Id: gdalgeopackagerasterband.cpp 39966 2017-08-30 15:28:52Z rouault $");
 
 #if !defined(DEBUG_VERBOSE) && defined(DEBUG_VERBOSE_GPKG)
 #define DEBUG_VERBOSE
@@ -1432,10 +1432,19 @@ CPLErr GDALGPKGMBTilesLikePseudoDataset::WriteTile()
     if( poMainDS->m_nTileInsertionCount < 0 )
         return CE_Failure;
 
-    CPLAssert(!m_bInWriteTile);
+    if (m_bInWriteTile)
+    {
+        // Shouldn't happen in practice, but #7022 shows that the unexpected
+        // can happen sometimes.
+        CPLError(CE_Failure, CPLE_AppDefined,
+                 "Recursive call to GDALGPKGMBTilesLikePseudoDataset::WriteTile()");
+        return CE_Failure;
+    }
+    GDALRasterBlock::EnterDisableDirtyBlockFlush();
     m_bInWriteTile = true;
     CPLErr eErr = WriteTileInternal();
     m_bInWriteTile = false;
+    GDALRasterBlock::LeaveDisableDirtyBlockFlush();
     return eErr;
 }
 
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
index 35bc12b..70c7cf8 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagedatasource.cpp
@@ -38,7 +38,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: ogrgeopackagedatasource.cpp 39212 2017-06-20 19:00:17Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagedatasource.cpp 39963 2017-08-30 09:28:04Z rouault $");
 
 /************************************************************************/
 /*                             Tiling schemes                           */
@@ -600,14 +600,24 @@ int GDALGeoPackageDataset::Open( GDALOpenInfo* poOpenInfo )
     if( STARTS_WITH_CI(poOpenInfo->pszFilename, "GPKG:") )
     {
         char** papszTokens = CSLTokenizeString2(poOpenInfo->pszFilename, ":", 0);
-        if( CSLCount(papszTokens) != 3 )
+        int nCount = CSLCount(papszTokens);
+        if( nCount != 3 && nCount != 4 )
         {
             CSLDestroy(papszTokens);
             return FALSE;
         }
 
-        osFilename = papszTokens[1];
-        osSubdatasetTableName = papszTokens[2];
+        if( nCount == 3 )
+        {
+            osFilename = papszTokens[1];
+        }
+        /* GPKG:C:\BLA.GPKG:foo */
+        else if ( nCount == 4 && strlen(papszTokens[1]) == 1 &&
+                  (papszTokens[2][0] == '/' || papszTokens[2][0] == '\\') )
+        {
+            osFilename = CPLString(papszTokens[1]) + ":" + papszTokens[2];
+        }
+        osSubdatasetTableName = papszTokens[nCount-1];
 
         CSLDestroy(papszTokens);
         VSILFILE *fp = VSIFOpenL(osFilename, "rb");
@@ -994,10 +1004,22 @@ bool GDALGeoPackageDataset::InitRaster( GDALGeoPackageDataset* poParentDS,
     if( pszContentsMinX != NULL && pszContentsMinY != NULL &&
         pszContentsMaxX != NULL && pszContentsMaxY != NULL )
     {
-        dfGDALMinX = CPLAtof(pszContentsMinX);
-        dfGDALMinY = CPLAtof(pszContentsMinY);
-        dfGDALMaxX = CPLAtof(pszContentsMaxX);
-        dfGDALMaxY = CPLAtof(pszContentsMaxY);
+        if( CPLAtof(pszContentsMinX) < CPLAtof(pszContentsMaxX) &&
+            CPLAtof(pszContentsMinY) < CPLAtof(pszContentsMaxY) )
+        {
+            dfGDALMinX = CPLAtof(pszContentsMinX);
+            dfGDALMinY = CPLAtof(pszContentsMinY);
+            dfGDALMaxX = CPLAtof(pszContentsMaxX);
+            dfGDALMaxY = CPLAtof(pszContentsMaxY);
+        }
+        else
+        {
+            CPLError(CE_Warning, CPLE_AppDefined,
+                     "Illegal min_x/min_y/max_x/max_y values for %s in open "
+                     "options and/or gpkg_contents. Using bounds of "
+                     "gpkg_tile_matrix_set instead",
+                     pszTableName);
+        }
     }
     if( dfGDALMinX >= dfGDALMaxX || dfGDALMinY >= dfGDALMaxY )
     {
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagelayer.cpp
index 6cc55e4..cb69809 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagelayer.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagelayer.cpp
@@ -32,7 +32,7 @@
 #include "ogrsqliteutility.h"
 #include "ogr_p.h"
 
-CPL_CVSID("$Id: ogrgeopackagelayer.cpp 37809 2017-03-20 15:28:41Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagelayer.cpp 39983 2017-09-02 20:24:15Z rouault $");
 
 /************************************************************************/
 /*                      OGRGeoPackageLayer()                            */
@@ -333,6 +333,29 @@ void OGRGeoPackageLayer::BuildFeatureDefn( const char *pszLayerName,
     const bool bPromoteToInteger64 =
         CPLTestBool(CPLGetConfigOption("OGR_PROMOTE_TO_INTEGER64", "FALSE"));
 
+#ifdef SQLITE_HAS_COLUMN_METADATA
+    // Check that there are not several FID fields referenced.
+    // This is not a sufficient condition to ensure that we can get a true FID,
+    // but when this occurs, we are (almost) sure that this cannot be a FID.
+    int nFIDCandidates = 0;
+    for( int iCol = 0; iCol < nRawColumns; iCol++ )
+    {
+        const char* pszTableName = sqlite3_column_table_name( hStmt, iCol );
+        const char* pszOriginName = sqlite3_column_origin_name( hStmt, iCol );
+        if( pszTableName != NULL && pszOriginName != NULL )
+        {
+            OGRLayer* poLayer = m_poDS->GetLayerByName(pszTableName);
+            if( poLayer != NULL )
+            {
+                if( EQUAL(pszOriginName, poLayer->GetFIDColumn()) )
+                {
+                    nFIDCandidates ++;
+                }
+            }
+        }
+    }
+#endif
+
     for( int iCol = 0; iCol < nRawColumns; iCol++ )
     {
         OGRFieldDefn    oField(
@@ -381,9 +404,9 @@ void OGRGeoPackageLayer::BuildFeatureDefn( const char *pszLayerName,
                     iGeomCol = iCol;
                     continue;
                 }
-                else if( EQUAL(pszOriginName, poLayer->GetFIDColumn()) )
+                else if( EQUAL(pszOriginName, poLayer->GetFIDColumn()) &&
+                         m_pszFidColumn == NULL && nFIDCandidates == 1 )
                 {
-                    CPLFree(m_pszFidColumn);
                     m_pszFidColumn = CPLStrdup(oField.GetNameRef());
                     iFIDCol = iCol;
                     continue;
diff --git a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
index ba3677a..1d6b2b0 100644
--- a/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
+++ b/ogr/ogrsf_frmts/gpkg/ogrgeopackagetablelayer.cpp
@@ -33,7 +33,7 @@
 #include "cpl_time.h"
 #include "ogr_p.h"
 
-CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 38922 2017-06-06 20:38:20Z rouault $");
+CPL_CVSID("$Id: ogrgeopackagetablelayer.cpp 39649 2017-07-24 15:43:36Z rouault $");
 
 static const char UNSUPPORTED_OP_READ_ONLY[] =
   "%s : unsupported operation on a read-only datasource.";
@@ -696,7 +696,8 @@ OGRErr OGRGeoPackageTableLayer::ReadTableDefinition(bool bIsSpatial, bool bIsGpk
                 oExtent.MinY = CPLAtof(pszMinY);
                 oExtent.MaxX = CPLAtof(pszMaxX);
                 oExtent.MaxY = CPLAtof(pszMaxY);
-                bReadExtent = true;
+                bReadExtent = oExtent.MinX <= oExtent.MaxX &&
+                              oExtent.MinY <= oExtent.MaxY;
             }
 
             /* Done with info from gpkg_contents now */
@@ -1572,9 +1573,13 @@ OGRErr OGRGeoPackageTableLayer::ICreateFeature( OGRFeature *poFeature )
     /* Update the layer extents with this new object */
     if( IsGeomFieldSet(poFeature) )
     {
-        OGREnvelope oEnv;
-        poFeature->GetGeomFieldRef(0)->getEnvelope(&oEnv);
-        UpdateExtent(&oEnv);
+        OGRGeometry* poGeom = poFeature->GetGeomFieldRef(0);
+        if( !poGeom->IsEmpty() )
+        {
+            OGREnvelope oEnv;
+            poGeom->getEnvelope(&oEnv);
+            UpdateExtent(&oEnv);
+        }
     }
 
     /* Read the latest FID value */
@@ -1662,6 +1667,9 @@ OGRErr OGRGeoPackageTableLayer::ISetFeature( OGRFeature *poFeature )
         sqlite3_stmt* hBackupStmt = m_poUpdateStatement;
         m_poUpdateStatement = NULL;
 
+#ifdef ENABLE_GPKG_OGR_CONTENTS
+        GIntBig nTotalFeatureCountBackup = m_nTotalFeatureCount;
+#endif
         OGRErr errOgr = DeleteFeature( poFeature->GetFID() );
 
         m_poUpdateStatement = hBackupStmt;
@@ -1673,6 +1681,9 @@ OGRErr OGRGeoPackageTableLayer::ISetFeature( OGRFeature *poFeature )
         errOgr = FeatureBindInsertParameters(poFeature, m_poUpdateStatement, true, true);
         if ( errOgr != OGRERR_NONE )
             return errOgr;
+#ifdef ENABLE_GPKG_OGR_CONTENTS
+        m_nTotalFeatureCount = nTotalFeatureCountBackup;
+#endif
     }
     else
 #endif
@@ -1728,9 +1739,13 @@ OGRErr OGRGeoPackageTableLayer::ISetFeature( OGRFeature *poFeature )
         /* Update the layer extents with this new object */
         if( IsGeomFieldSet(poFeature) )
         {
-            OGREnvelope oEnv;
-            poFeature->GetGeomFieldRef(0)->getEnvelope(&oEnv);
-            UpdateExtent(&oEnv);
+            OGRGeometry* poGeom = poFeature->GetGeomFieldRef(0);
+            if( !poGeom->IsEmpty() )
+            {
+                OGREnvelope oEnv;
+                poGeom->getEnvelope(&oEnv);
+                UpdateExtent(&oEnv);
+            }
         }
 
         m_bContentChanged = true;
diff --git a/ogr/ogrsf_frmts/kml/kml.cpp b/ogr/ogrsf_frmts/kml/kml.cpp
index 4b4a53e..27f3e82 100644
--- a/ogr/ogrsf_frmts/kml/kml.cpp
+++ b/ogr/ogrsf_frmts/kml/kml.cpp
@@ -37,7 +37,7 @@
 #include <iostream>
 #include <string>
 
-CPL_CVSID("$Id: kml.cpp 38409 2017-05-16 09:58:58Z rouault $");
+CPL_CVSID("$Id: kml.cpp 39692 2017-07-30 19:32:43Z rouault $");
 
 KML::KML() :
     poTrunk_(NULL),
@@ -212,6 +212,10 @@ void XMLCALL KML::startElement( void* pUserData, const char* pszName,
 
     poKML->nWithoutEventCounter = 0;
 
+    const char* pszColumn = strchr(pszName, ':');
+    if( pszColumn)
+        pszName = pszColumn + 1;
+
     if(poKML->poTrunk_ == NULL
     || (poKML->poCurrent_ != NULL &&
         poKML->poCurrent_->getName().compare("description") != 0))
@@ -275,6 +279,10 @@ void XMLCALL KML::startElementValidate( void* pUserData, const char* pszName,
 
     poKML->validity = KML_VALIDITY_INVALID;
 
+    const char* pszColumn = strchr(pszName, ':');
+    if( pszColumn)
+        pszName = pszColumn + 1;
+
     if(strcmp(pszName, "kml") == 0 || strcmp(pszName, "Document") == 0)
     {
         // Check all Attributes
@@ -343,6 +351,10 @@ void XMLCALL KML::endElement(void* pUserData, const char* pszName)
 
     poKML->nWithoutEventCounter = 0;
 
+    const char* pszColumn = strchr(pszName, ':');
+    if( pszColumn)
+        pszName = pszColumn + 1;
+
     if(poKML->poCurrent_ != NULL &&
        poKML->poCurrent_->getName().compare(pszName) == 0)
     {
diff --git a/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp b/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp
index a9431b2..23ff5f5 100644
--- a/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp
+++ b/ogr/ogrsf_frmts/kml/ogrkmldriver.cpp
@@ -33,7 +33,7 @@
 #include "cpl_conv.h"
 #include "cpl_error.h"
 
-CPL_CVSID("$Id: ogrkmldriver.cpp 37108 2017-01-12 10:16:27Z rouault $");
+CPL_CVSID("$Id: ogrkmldriver.cpp 39692 2017-07-30 19:32:43Z rouault $");
 
 /************************************************************************/
 /*                         OGRKMLDriverIdentify()                       */
@@ -45,9 +45,10 @@ static int OGRKMLDriverIdentify( GDALOpenInfo* poOpenInfo )
     if( poOpenInfo->fpL == NULL )
         return FALSE;
 
-    return
-        strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader),
-               "<kml") != NULL;
+    return strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader),
+                  "<kml") != NULL ||
+           strstr(reinterpret_cast<char *>(poOpenInfo->pabyHeader),
+                  "<kml:kml") != NULL;
 }
 
 /************************************************************************/
diff --git a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
index dbe0afe..7acab55 100644
--- a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
+++ b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp
@@ -35,7 +35,7 @@
 #include "ogr_p.h"
 #include "cpl_vsi_error.h"
 
-CPL_CVSID("$Id: ogrlibkmldatasource.cpp 37108 2017-01-12 10:16:27Z rouault $");
+CPL_CVSID("$Id: ogrlibkmldatasource.cpp 39692 2017-07-30 19:32:43Z rouault $");
 
 using kmlbase::Attributes;
 using kmldom::ContainerPtr;
@@ -67,6 +67,22 @@ static const char OGRLIBKMLSRSWKT[] =
     "           AUTHORITY[\"EPSG\",\"9122\"]],"
     "           AUTHORITY[\"EPSG\",\"4326\"]]";
 
+/************************************************************************/
+/*                           OGRLIBKMLParse()                           */
+/************************************************************************/
+
+static ElementPtr OGRLIBKMLParse(std::string oKml, std::string *posError)
+{
+    // To allow reading files using an explict namespace prefix like <kml:kml>
+    // we need to use ParseNS (see #6981). But if we use ParseNS, we have
+    // issues reading gx: elements. So use ParseNS only when we have errors
+    // with Parse. This is not completely satisfactory...
+    ElementPtr element = kmldom::Parse(oKml, posError);
+    if( element == NULL )
+        element = kmldom::ParseNS(oKml, posError);
+    return element;
+}
+
 /******************************************************************************
  OGRLIBKMLDataSource Constructor
 
@@ -904,7 +920,7 @@ int OGRLIBKMLDataSource::ParseIntoStyleTable(
 {
     /***** parse the kml into the dom *****/
     std::string oKmlErrors;
-    ElementPtr poKmlRoot = kmldom::Parse( *poKmlStyleKml, &oKmlErrors );
+    ElementPtr poKmlRoot = OGRLIBKMLParse( *poKmlStyleKml, &oKmlErrors );
 
     if( !poKmlRoot )
     {
@@ -974,7 +990,7 @@ int OGRLIBKMLDataSource::OpenKml( const char *pszFilename, int bUpdateIn )
     /***** parse the kml into the DOM *****/
     std::string oKmlErrors;
 
-    ElementPtr poKmlRoot = kmldom::Parse( oKmlKml, &oKmlErrors );
+    ElementPtr poKmlRoot = OGRLIBKMLParse( oKmlKml, &oKmlErrors );
 
     if( !poKmlRoot )
     {
@@ -1090,7 +1106,7 @@ int OGRLIBKMLDataSource::OpenKmz( const char *pszFilename, int bUpdateIn )
 
     /***** parse the kml into the DOM *****/
     std::string oKmlErrors;
-    ElementPtr poKmlDocKmlRoot = kmldom::Parse( oKmlKml, &oKmlErrors );
+    ElementPtr poKmlDocKmlRoot = OGRLIBKMLParse( oKmlKml, &oKmlErrors );
 
     if( !poKmlDocKmlRoot )
     {
@@ -1158,7 +1174,7 @@ int OGRLIBKMLDataSource::OpenKmz( const char *pszFilename, int bUpdateIn )
             {
                 /***** parse the kml into the DOM *****/
                 oKmlErrors.clear();
-                ElementPtr poKmlLyrRoot = kmldom::Parse( oKml, &oKmlErrors );
+                ElementPtr poKmlLyrRoot = OGRLIBKMLParse( oKml, &oKmlErrors );
 
                 if( !poKmlLyrRoot )
                 {
@@ -1315,7 +1331,7 @@ int OGRLIBKMLDataSource::OpenDir( const char *pszFilename, int bUpdateIn )
 
         /***** parse the kml into the DOM *****/
         std::string oKmlErrors;
-        ElementPtr poKmlRoot = kmldom::Parse( oKmlKml, &oKmlErrors );
+        ElementPtr poKmlRoot = OGRLIBKMLParse( oKmlKml, &oKmlErrors );
 
         if( !poKmlRoot )
         {
diff --git a/ogr/ogrsf_frmts/mitab/mitab_feature_mif.cpp b/ogr/ogrsf_frmts/mitab/mitab_feature_mif.cpp
index da266a0..1eed222 100644
--- a/ogr/ogrsf_frmts/mitab/mitab_feature_mif.cpp
+++ b/ogr/ogrsf_frmts/mitab/mitab_feature_mif.cpp
@@ -49,7 +49,7 @@
 #include "ogr_feature.h"
 #include "ogr_geometry.h"
 
-CPL_CVSID("$Id: mitab_feature_mif.cpp 38426 2017-05-16 19:38:58Z rouault $");
+CPL_CVSID("$Id: mitab_feature_mif.cpp 39591 2017-07-15 15:08:47Z rouault $");
 
 /*=====================================================================
  *                      class TABFeature
@@ -2211,7 +2211,10 @@ int TABCollection::ReadGeometryFromMIFFile(MIDDATAFile *fp)
             pszLine++;  // skip leading spaces
 
         if (*pszLine == '\0')
+        {
+            pszLine = fp->GetLine();
             continue;  // Skip blank lines
+        }
 
         if (STARTS_WITH_CI(pszLine, "REGION"))
         {
diff --git a/ogr/ogrsf_frmts/mssqlspatial/ogr_mssqlspatial.h b/ogr/ogrsf_frmts/mssqlspatial/ogr_mssqlspatial.h
index 2765ee8..964e116 100644
--- a/ogr/ogrsf_frmts/mssqlspatial/ogr_mssqlspatial.h
+++ b/ogr/ogrsf_frmts/mssqlspatial/ogr_mssqlspatial.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: ogr_mssqlspatial.h 36501 2016-11-25 14:09:24Z rouault $
+ * $Id: ogr_mssqlspatial.h 39756 2017-08-05 10:26:05Z tamas $
  *
  * Project:  MSSQL Spatial driver
  * Purpose:  Definition of classes for OGR MSSQL Spatial driver.
@@ -281,12 +281,12 @@ typedef union {
     } Float;
 
     struct {
-        int     nSize;
+        SQLLEN  nSize;
         char* pData[8000];
     } VarChar;
 
     struct {
-        int     nSize;
+        SQLLEN  nSize;
         GByte*  pData;
     } RawData;
 
diff --git a/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialtablelayer.cpp b/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialtablelayer.cpp
index 841bfae..20842cd 100644
--- a/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialtablelayer.cpp
+++ b/ogr/ogrsf_frmts/mssqlspatial/ogrmssqlspatialtablelayer.cpp
@@ -33,7 +33,7 @@
 #include <sqlncli.h>
 #endif
 
-CPL_CVSID("$Id: ogrmssqlspatialtablelayer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrmssqlspatialtablelayer.cpp 40101 2017-09-13 14:25:46Z rouault $");
 
 /************************************************************************/
 /*                         OGRMSSQLAppendEscaped( )                     */
@@ -1148,8 +1148,8 @@ OGRErr OGRMSSQLSpatialTableLayer::DeleteFeature( GIntBig nFID )
 /* -------------------------------------------------------------------- */
     CPLODBCStatement oStatement( poDS->GetSession() );
 
-    oStatement.Appendf("DELETE FROM [%s] WHERE [%s] = " CPL_FRMT_GIB,
-            poFeatureDefn->GetName(), pszFIDColumn, nFID);
+    oStatement.Appendf("DELETE FROM [%s].[%s] WHERE [%s] = " CPL_FRMT_GIB,
+            pszSchemaName, pszTableName, pszFIDColumn, nFID);
 
     if( !oStatement.ExecuteSQL() )
     {
@@ -1561,11 +1561,11 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
                 OGRMSSQLGeometryWriter poWriter(poGeom, nGeomColumnType, nSRSId);
                 papstBindBuffer[iCol]->RawData.nSize = poWriter.GetDataLen();
                 papstBindBuffer[iCol]->RawData.pData = (GByte *) CPLMalloc(papstBindBuffer[iCol]->RawData.nSize + 1);
-                if (poWriter.WriteSqlGeometry(papstBindBuffer[iCol]->RawData.pData, papstBindBuffer[iCol]->RawData.nSize) != OGRERR_NONE)
+                if (poWriter.WriteSqlGeometry(papstBindBuffer[iCol]->RawData.pData, (int)papstBindBuffer[iCol]->RawData.nSize) != OGRERR_NONE)
                     return OGRERR_FAILURE;
 
                 /* set data length */
-                if (Failed2( bcp_collen( hDBCBCP, papstBindBuffer[iCol]->RawData.nSize, iCol + 1) ))
+                if (Failed2( bcp_collen( hDBCBCP, (DBINT)papstBindBuffer[iCol]->RawData.nSize, iCol + 1) ))
                     return OGRERR_FAILURE;
             }
             else
@@ -1671,9 +1671,9 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
                     else
                     {
 
-                        papstBindBuffer[iCol]->VarChar.nSize = CPLStrlenUTF8(poFeature->GetFieldAsString(iField)) * 2;
+                        papstBindBuffer[iCol]->VarChar.nSize = (SQLLEN)CPLStrlenUTF8(poFeature->GetFieldAsString(iField)) * 2;
                         wchar_t* buffer = CPLRecodeToWChar( poFeature->GetFieldAsString(iField), CPL_ENC_UTF8, CPL_ENC_UCS2);
-                        memcpy(papstBindBuffer[iCol]->VarChar.pData, buffer, papstBindBuffer[iCol]->VarChar.nSize + 2);
+                        memcpy(papstBindBuffer[iCol]->VarChar.pData, buffer, (DBINT)papstBindBuffer[iCol]->VarChar.nSize + 2);
                         CPLFree(buffer);
 
                         if (Failed2( bcp_collen( hDBCBCP, papstBindBuffer[iCol]->VarChar.nSize, iCol + 1) ))
@@ -1781,10 +1781,12 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
                 else
                 {
                     /* image */
-                    papstBindBuffer[iCol]->RawData.pData = poFeature->GetFieldAsBinary(iField, &papstBindBuffer[iCol]->RawData.nSize);
+                    int nLen;
+                    papstBindBuffer[iCol]->RawData.pData = poFeature->GetFieldAsBinary(iField, &nLen);
+                    papstBindBuffer[iCol]->RawData.nSize = nLen;
 
                     /* set data length */
-                    if (Failed2( bcp_collen( hDBCBCP, papstBindBuffer[iCol]->RawData.nSize, iCol + 1) ))
+                    if (Failed2( bcp_collen( hDBCBCP, (DBINT)papstBindBuffer[iCol]->RawData.nSize, iCol + 1) ))
                         return OGRERR_FAILURE;
                 }
             }
@@ -1815,7 +1817,7 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
             if (papstBindBuffer[iCol]->RawData.nSize != SQL_NULL_DATA)
             {
                 if (Failed2( bcp_moretext( hDBCBCP,
-                    papstBindBuffer[iCol]->RawData.nSize,
+                    (DBINT)papstBindBuffer[iCol]->RawData.nSize,
                     papstBindBuffer[iCol]->RawData.pData ) ))
                 {
 
@@ -1849,12 +1851,12 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
                 {
                     if (poFeature->IsFieldSetAndNotNull( iField ))
                     {
-                        papstBindBuffer[iCol]->VarChar.nSize = CPLStrlenUTF8(poFeature->GetFieldAsString(iField)) * 2;
+                        papstBindBuffer[iCol]->VarChar.nSize = (SQLLEN)CPLStrlenUTF8(poFeature->GetFieldAsString(iField)) * 2;
                         if (papstBindBuffer[iCol]->VarChar.nSize > 0)
                         {
                             wchar_t* buffer = CPLRecodeToWChar( poFeature->GetFieldAsString(iField), CPL_ENC_UTF8, CPL_ENC_UCS2);
                             if (Failed2( bcp_moretext( hDBCBCP,
-                                papstBindBuffer[iCol]->VarChar.nSize,
+                                (DBINT)papstBindBuffer[iCol]->VarChar.nSize,
                                 (LPCBYTE)buffer ) ))
                             {
 
@@ -1884,7 +1886,7 @@ OGRErr OGRMSSQLSpatialTableLayer::CreateFeatureBCP( OGRFeature *poFeature )
                     if (papstBindBuffer[iCol]->RawData.nSize > 0)
                     {
                         if (Failed2( bcp_moretext( hDBCBCP,
-                            papstBindBuffer[iCol]->RawData.nSize,
+                            (DBINT)papstBindBuffer[iCol]->RawData.nSize,
                             papstBindBuffer[iCol]->RawData.pData ) ))
                         {
 
@@ -2007,7 +2009,7 @@ OGRErr OGRMSSQLSpatialTableLayer::ICreateFeature( OGRFeature *poFeature )
     int bind_num = 0;
     void** bind_buffer = (void**)CPLMalloc(sizeof(void*) * (nFieldCount + 1));
 #ifdef SQL_SS_UDT
-    int* bind_datalen = (int*)CPLMalloc(sizeof(int) * (nFieldCount + 1));
+    SQLLEN* bind_datalen = (SQLLEN*)CPLMalloc(sizeof(SQLLEN) * (nFieldCount + 1));
 #endif
 
     int i;
@@ -2045,7 +2047,7 @@ OGRErr OGRMSSQLSpatialTableLayer::ICreateFeature( OGRFeature *poFeature )
                 OGRMSSQLGeometryWriter poWriter(poGeom, nGeomColumnType, nSRSId);
                 bind_datalen[bind_num] = poWriter.GetDataLen();
                 GByte *pabyData = (GByte *) CPLMalloc(bind_datalen[bind_num] + 1);
-                if (poWriter.WriteSqlGeometry(pabyData, bind_datalen[bind_num]) == OGRERR_NONE)
+                if (poWriter.WriteSqlGeometry(pabyData, (int)bind_datalen[bind_num]) == OGRERR_NONE)
                 {
                     SQLHANDLE ipd;
                     if ((!poSession->Failed( SQLBindParameter(oStatement.GetStatement(), (SQLUSMALLINT)(bind_num + 1),
diff --git a/ogr/ogrsf_frmts/nas/nashandler.cpp b/ogr/ogrsf_frmts/nas/nashandler.cpp
index 01da31b..bf44b01 100644
--- a/ogr/ogrsf_frmts/nas/nashandler.cpp
+++ b/ogr/ogrsf_frmts/nas/nashandler.cpp
@@ -33,7 +33,7 @@
 #include "cpl_string.h"
 #include "ogr_xerces.h"
 
-CPL_CVSID("$Id: nashandler.cpp 36682 2016-12-04 20:34:45Z rouault $");
+CPL_CVSID("$Id: nashandler.cpp 39560 2017-07-12 08:53:28Z rouault $");
 
 /*
   Update modes:
@@ -90,7 +90,10 @@ NASHandler::NASHandler( NASReader *poReader ) :
     m_bIgnoreFeature(false),
     m_bInUpdate(false),
     m_bInUpdateProperty(false),
-    m_nDepthElement(0)
+    m_nDepthElement(0),
+    m_nUpdateOrDeleteDepth(0),
+    m_nUpdatePropertyDepth(0),
+    m_nNameOrValueDepth(0)
 {}
 
 /************************************************************************/
@@ -316,7 +319,8 @@ void NASHandler::startElement( const XMLCh* const /* uri */,
 /* -------------------------------------------------------------------- */
 /*      Is it a feature?  If so push a whole new state, and return.     */
 /* -------------------------------------------------------------------- */
-    else if( m_poReader->IsFeatureElement( m_osElementName ) )
+    else if( !m_bInUpdateProperty && m_nDepthFeature == 0 &&
+             m_poReader->IsFeatureElement( m_osElementName ) )
     {
         m_osLastTypeName = m_osElementName;
 
@@ -376,7 +380,8 @@ void NASHandler::startElement( const XMLCh* const /* uri */,
 /*      the typeName attribute so we can assign it to the feature that  */
 /*      will be produced when we process the Filter element.            */
 /* -------------------------------------------------------------------- */
-    else if( m_osElementName == "Delete" || m_osElementName == "Update" )
+    else if( m_nUpdateOrDeleteDepth == 0 &&
+             (m_osElementName == "Delete" || m_osElementName == "Update") )
     {
         const XMLCh Name[] = { 't', 'y', 'p', 'e', 'N', 'a', 'm', 'e', '\0' };
 
@@ -394,19 +399,24 @@ void NASHandler::startElement( const XMLCh* const /* uri */,
         {
             m_bInUpdate = true;
         }
+        m_nUpdateOrDeleteDepth = m_nDepth;
     }
 
-    else if ( m_bInUpdate && m_osElementName == "Property" )
+    else if ( m_nUpdatePropertyDepth  == 0 &&
+              m_bInUpdate && m_osElementName == "Property" )
     {
         m_bInUpdateProperty = true;
+        m_nUpdatePropertyDepth = m_nDepth;
     }
 
-    else if ( m_bInUpdateProperty && ( m_osElementName == "Name" ||
+    else if ( m_nNameOrValueDepth == 0 &&
+              m_bInUpdateProperty && ( m_osElementName == "Name" ||
                                        m_osElementName == "Value" ) )
     {
         // collect attribute name or value
         CPLFree( m_pszCurField );
         m_pszCurField = CPLStrdup("");
+        m_nNameOrValueDepth = m_nDepth;
     }
 
 /* -------------------------------------------------------------------- */
@@ -505,19 +515,21 @@ void NASHandler::endElement( const XMLCh* const /* uri */ ,
 
    if( m_bInUpdateProperty )
    {
-       if( m_osElementName == "Name" )
+       if( m_osElementName == "Name" && m_nDepth == m_nNameOrValueDepth )
        {
            CPLAssert( m_osLastPropertyName == "" );
            m_osLastPropertyName = m_pszCurField;
            m_pszCurField = NULL;
+           m_nNameOrValueDepth = 0;
        }
-       else if( m_osElementName == "Value" )
+       else if( m_osElementName == "Value" && m_nDepth == m_nNameOrValueDepth )
        {
            CPLAssert( m_osLastPropertyValue == "" );
            m_osLastPropertyValue = m_pszCurField;
            m_pszCurField = NULL;
+           m_nNameOrValueDepth = 0;
        }
-       else if( m_osElementName == "Property" )
+       else if( m_nDepth == m_nUpdatePropertyDepth && m_osElementName == "Property" )
        {
            if( EQUAL( m_osLastPropertyName, "adv:lebenszeitintervall/adv:AA_Lebenszeitintervall/adv:endet" ) )
            {
@@ -539,6 +551,7 @@ void NASHandler::endElement( const XMLCh* const /* uri */ ,
            m_osLastPropertyName = "";
            m_osLastPropertyValue = "";
            m_bInUpdateProperty = false;
+           m_nUpdatePropertyDepth = 0;
        }
 
        poState->PopPath();
@@ -546,9 +559,14 @@ void NASHandler::endElement( const XMLCh* const /* uri */ ,
        return;
    }
 
-   if ( m_bInUpdate && m_osElementName == "Update" )
+   if( m_nUpdateOrDeleteDepth > 0 &&
+             (m_osElementName == "Delete" || m_osElementName == "Update") )
    {
-       m_bInUpdate = false;
+        if ( m_bInUpdate && m_osElementName == "Update" )
+        {
+            m_bInUpdate = false;
+        }
+        m_nUpdateOrDeleteDepth = 0;
    }
 
 /* -------------------------------------------------------------------- */
diff --git a/ogr/ogrsf_frmts/nas/nasreaderp.h b/ogr/ogrsf_frmts/nas/nasreaderp.h
index f0a71a4..1aa0f1a 100644
--- a/ogr/ogrsf_frmts/nas/nasreaderp.h
+++ b/ogr/ogrsf_frmts/nas/nasreaderp.h
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: nasreaderp.h 36501 2016-11-25 14:09:24Z rouault $
+ * $Id: nasreaderp.h 39272 2017-06-24 10:49:55Z rouault $
  *
  * Project:  NAS Reader
  * Purpose:  Private Declarations for OGR NAS Reader code.
@@ -73,6 +73,9 @@ class NASHandler : public DefaultHandler
     bool       m_bInUpdate;
     bool       m_bInUpdateProperty;
     int        m_nDepthElement;
+    int        m_nUpdateOrDeleteDepth;
+    int        m_nUpdatePropertyDepth;
+    int        m_nNameOrValueDepth;
     CPLString  m_osIgnoredElement;
 
     CPLString  m_osLastTypeName;
diff --git a/ogr/ogrsf_frmts/ntf/ntfrecord.cpp b/ogr/ogrsf_frmts/ntf/ntfrecord.cpp
index 71d909c..1a03e18 100644
--- a/ogr/ogrsf_frmts/ntf/ntfrecord.cpp
+++ b/ogr/ogrsf_frmts/ntf/ntfrecord.cpp
@@ -30,7 +30,7 @@
 #include "ntf.h"
 #include "cpl_conv.h"
 
-CPL_CVSID("$Id: ntfrecord.cpp 35614 2016-10-05 16:34:38Z goatbar $");
+CPL_CVSID("$Id: ntfrecord.cpp 39295 2017-06-25 21:53:21Z rouault $");
 
 static int nFieldBufSize = 0;
 static char *pszFieldBuf = NULL;
@@ -223,6 +223,9 @@ const char * NTFRecord::GetField( int nStart, int nEnd )
 {
     const int nSize = nEnd - nStart + 1;
 
+    if( pszData == NULL )
+        return "";
+
 /* -------------------------------------------------------------------- */
 /*      Reallocate working buffer larger if needed.                     */
 /* -------------------------------------------------------------------- */
diff --git a/ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp b/ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp
index 703b79b..4d7ddc6 100644
--- a/ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp
+++ b/ogr/ogrsf_frmts/oci/ogrocitablelayer.cpp
@@ -32,7 +32,7 @@
 #include "cpl_conv.h"
 #include "cpl_string.h"
 
-CPL_CVSID("$Id: ogrocitablelayer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrocitablelayer.cpp 39942 2017-08-25 19:26:57Z rouault $");
 
 static int nDiscarded = 0;
 static int nHits = 0;
@@ -200,8 +200,8 @@ OGRFeatureDefn *OGROCITableLayer::ReadTableDefinition( const char * pszTable )
 
         nStatus =
             OCIDescribeAny(poSession->hSvcCtx, poSession->hError,
-                           (dvoid *) osQuotedTableName.c_str(),
-                           static_cast<ub4>(osQuotedTableName.length()), OCI_OTYPE_NAME,
+                           (dvoid *) osUnquotedTableName.c_str(),
+                           static_cast<ub4>(osUnquotedTableName.length()), OCI_OTYPE_NAME,
                            OCI_DEFAULT, OCI_PTYPE_VIEW, poSession->hDescribe );
 
         if( poSession->Failed( nStatus, "OCIDescribeAny" ) )
diff --git a/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp b/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp
index 42ef7db..5689c7e 100644
--- a/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp
+++ b/ogr/ogrsf_frmts/openfilegdb/filegdbtable.cpp
@@ -32,8 +32,9 @@
 #include "cpl_time.h"
 #include "ogr_api.h" // for OGR_RawField_xxxxx()
 #include "ogrpgeogeometry.h" /* SHPT_ constants and OGRCreateFromMultiPatchPart() */
+#include <limits>
 
-CPL_CVSID("$Id: filegdbtable.cpp 37648 2017-03-08 02:32:09Z rouault $");
+CPL_CVSID("$Id: filegdbtable.cpp 39952 2017-08-28 07:33:52Z rouault $");
 
 #define TEST_BIT(ar, bit)                       (ar[(bit) / 8] & (1 << ((bit) % 8)))
 #define BIT_ARRAY_SIZE_IN_BYTES(bitsize)        (((bitsize)+7)/8)
@@ -2502,6 +2503,7 @@ OGRGeometry* FileGDBOGRGeometryConverterImpl::CreateCurveGeometry(
     if( bHasM ) nShapeType |= EXT_SHAPE_M_FLAG;
     GUInt32 nTmp;
     nTmp = CPL_LSBWORD32(nShapeType);
+    GByte* pabyShapeTypePtr = pabyExtShapeBuffer;
     memcpy( pabyExtShapeBuffer, &nTmp, 4 );
     memset( pabyExtShapeBuffer + 4, 0, 32 ); /* bbox: unused */
     nTmp = CPL_LSBWORD32(nParts);
@@ -2541,19 +2543,47 @@ OGRGeometry* FileGDBOGRGeometryConverterImpl::CreateCurveGeometry(
         }
         nOffset += 8 * nPoints;
     }
+
     if( bHasM )
     {
-        memset( pabyExtShapeBuffer + nOffset, 0, 16 ); /* bbox: unused */
-        nOffset += 16;
-        ZOrMBufferSetter arraymSetter(pabyExtShapeBuffer + nOffset);
-        GIntBig dm = 0;
-        if( !ReadMArray<ZOrMBufferSetter>(arraymSetter,
-                        pabyCur, pabyEnd, nPoints, dm) )
+        // It seems that absence of M is marked with a single byte
+        // with value 66.
+        if( *pabyCur == 66 )
+        {
+            pabyCur ++;
+#if 1
+            // In other code paths of this file, we drop the M component when
+            // it is at null. The disabled code path would fill it with NaN
+            // instead.
+            nShapeType &= ~EXT_SHAPE_M_FLAG;
+            nTmp = CPL_LSBWORD32(nShapeType);
+            memcpy( pabyShapeTypePtr, &nTmp, 4 );
+#else
+            memset( pabyExtShapeBuffer + nOffset, 0, 16 ); /* bbox: unused */
+            nOffset += 16;
+            const double myNan = std::numeric_limits<double>::quiet_NaN();
+            for( i = 0; i < nPoints; i++ )
+            {
+                memcpy(pabyExtShapeBuffer + nOffset + 8 * i, &myNan, 8);
+                CPL_LSBPTR64(pabyExtShapeBuffer + nOffset + 8 * i);
+            }
+            nOffset += 8 * nPoints;
+#endif
+        }
+        else
         {
-            VSIFree(pabyExtShapeBuffer);
-            returnError();
+            memset( pabyExtShapeBuffer + nOffset, 0, 16 ); /* bbox: unused */
+            nOffset += 16;
+            ZOrMBufferSetter arraymSetter(pabyExtShapeBuffer + nOffset);
+            GIntBig dm = 0;
+            if( !ReadMArray<ZOrMBufferSetter>(arraymSetter,
+                            pabyCur, pabyEnd, nPoints, dm) )
+            {
+                VSIFree(pabyExtShapeBuffer);
+                returnError();
+            }
+            nOffset += 8 * nPoints;
         }
-        nOffset += 8 * nPoints;
     }
 
     nTmp = CPL_LSBWORD32(nCurves);
diff --git a/ogr/ogrsf_frmts/osm/osm_parser.cpp b/ogr/ogrsf_frmts/osm/osm_parser.cpp
index 11098b3..204e21f 100644
--- a/ogr/ogrsf_frmts/osm/osm_parser.cpp
+++ b/ogr/ogrsf_frmts/osm/osm_parser.cpp
@@ -39,7 +39,7 @@
 
 #include <algorithm>
 
-CPL_CVSID("$Id: osm_parser.cpp 37052 2017-01-01 18:36:35Z rouault $");
+CPL_CVSID("$Id: osm_parser.cpp 39807 2017-08-13 13:24:52Z rouault $");
 
 // The buffer that are passed to GPB decoding are extended with 0's
 // to be sure that we will be able to read a single 64bit value without
@@ -474,6 +474,7 @@ bool ReadDenseNodes( GByte* pabyData, GByte* pabyDataLimit,
     GByte* pabyDataLon = NULL;
     GByte* apabyData[DENSEINFO_IDX_VISIBLE] = {NULL, NULL, NULL, NULL, NULL, NULL};
     GByte* pabyDataKeyVal = NULL;
+    unsigned int nMaxTags = 0;
 
     /* printf(">ReadDenseNodes\n"); */
     while(pabyData < pabyDataLimit)
@@ -563,12 +564,13 @@ bool ReadDenseNodes( GByte* pabyData, GByte* pabyDataLimit,
             READ_SIZE(pabyData, pabyDataLimit, nSize);
 
             pabyDataKeyVal = pabyData;
+            nMaxTags = nSize / 2;
 
-            if( nSize > psCtxt->nTagsAllocated )
+            if( nMaxTags > psCtxt->nTagsAllocated )
             {
 
                 psCtxt->nTagsAllocated = std::max(
-                    psCtxt->nTagsAllocated * 2, nSize);
+                    psCtxt->nTagsAllocated * 2, nMaxTags);
                 OSMTag* pasTagsNew = (OSMTag*) VSI_REALLOC_VERBOSE(
                     psCtxt->pasTags,
                     psCtxt->nTagsAllocated * sizeof(OSMTag));
@@ -662,7 +664,7 @@ bool ReadDenseNodes( GByte* pabyData, GByte* pabyDataLimit,
 
             if( pabyDataKeyVal != NULL && pasTags != NULL )
             {
-                while( true )
+                while( static_cast<unsigned>(nTags) < nMaxTags )
                 {
                     unsigned int nKey, nVal;
                     READ_VARUINT32(pabyDataKeyVal, pabyDataLimit, nKey);
@@ -2266,7 +2268,7 @@ OSMContext* OSM_Open( const char* pszFilename,
     {
         psCtxt->nBlobSizeAllocated = XML_BUFSIZE;
 
-        psCtxt->nStrAllocated = 65536;
+        psCtxt->nStrAllocated = 1024*1024;
         psCtxt->pszStrBuf = (char*) VSI_MALLOC_VERBOSE(psCtxt->nStrAllocated);
         if( psCtxt->pszStrBuf )
             psCtxt->pszStrBuf[0] = '\0';
diff --git a/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp b/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp
index 1e18093..ea6ebf1 100644
--- a/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp
+++ b/ogr/ogrsf_frmts/shape/ogrshapedriver.cpp
@@ -32,7 +32,7 @@
 #include "cpl_string.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ogrshapedriver.cpp 36883 2016-12-15 13:31:12Z rouault $");
+CPL_CVSID("$Id: ogrshapedriver.cpp 39740 2017-08-03 15:20:08Z rouault $");
 
 /************************************************************************/
 /*                              Identify()                              */
@@ -137,8 +137,8 @@ static GDALDataset *OGRShapeDriverCreate( const char * pszName,
 /* -------------------------------------------------------------------- */
 /*      Is the target a valid existing directory?                       */
 /* -------------------------------------------------------------------- */
-    VSIStatBuf stat;
-    if( CPLStat( pszName, &stat ) == 0 )
+    VSIStatBufL stat;
+    if( VSIStatL( pszName, &stat ) == 0 )
     {
         if( !VSI_ISDIR(stat.st_mode) )
         {
diff --git a/ogr/ogrsf_frmts/shape/ogrshapelayer.cpp b/ogr/ogrsf_frmts/shape/ogrshapelayer.cpp
index 4c8fa16..3392cc0 100644
--- a/ogr/ogrsf_frmts/shape/ogrshapelayer.cpp
+++ b/ogr/ogrsf_frmts/shape/ogrshapelayer.cpp
@@ -39,7 +39,7 @@
 static const char UNSUPPORTED_OP_READ_ONLY[] =
     "%s : unsupported operation on a read-only datasource.";
 
-CPL_CVSID("$Id: ogrshapelayer.cpp 36883 2016-12-15 13:31:12Z rouault $");
+CPL_CVSID("$Id: ogrshapelayer.cpp 40020 2017-09-07 11:41:25Z rouault $");
 
 /************************************************************************/
 /*                           OGRShapeLayer()                            */
@@ -932,10 +932,12 @@ OGRErr OGRShapeLayer::ISetFeature( OGRFeature *poFeature )
 
     unsigned int nOffset = 0;
     unsigned int nSize = 0;
+    bool bIsLastRecord = false;
     if( hSHP != NULL )
     {
         nOffset = hSHP->panRecOffset[nFID];
         nSize = hSHP->panRecSize[nFID];
+        bIsLastRecord = (nOffset + nSize + 8 == hSHP->nFileSize );
     }
 
     OGRErr eErr = SHPWriteOGRFeature( hSHP, hDBF, poFeatureDefn, poFeature,
@@ -944,7 +946,18 @@ OGRErr OGRShapeLayer::ISetFeature( OGRFeature *poFeature )
 
     if( hSHP != NULL )
     {
-        if( nOffset != hSHP->panRecOffset[nFID] ||
+        if( bIsLastRecord )
+        {
+            // Optimization: we don't need repacking if this is the last
+            // record of the file. Just potential truncation
+            CPLAssert( nOffset == hSHP->panRecOffset[nFID] );
+            CPLAssert( hSHP->panRecOffset[nFID] + hSHP->panRecSize[nFID] + 8 == hSHP->nFileSize );
+            if( hSHP->panRecSize[nFID] < nSize )
+            {
+                VSIFTruncateL(VSI_SHP_GetVSIL(hSHP->fpSHP), hSHP->nFileSize);
+            }
+        }
+        else if( nOffset != hSHP->panRecOffset[nFID] ||
             nSize != hSHP->panRecSize[nFID] )
         {
             bSHPNeedsRepack = true;
diff --git a/ogr/ogrsf_frmts/shape/shpopen.c b/ogr/ogrsf_frmts/shape/shpopen.c
index 701db8a..457c3d5 100644
--- a/ogr/ogrsf_frmts/shape/shpopen.c
+++ b/ogr/ogrsf_frmts/shape/shpopen.c
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: shpopen.c 37185 2017-01-19 13:36:59Z rouault $
+ * $Id: shpopen.c 40020 2017-09-07 11:41:25Z rouault $
  *
  * Project:  Shapelib
  * Purpose:  Implementation of core Shapefile read/write functions.
@@ -297,7 +297,7 @@
 #include <stdio.h>
 #include <errno.h>
 
-SHP_CVSID("$Id: shpopen.c 37185 2017-01-19 13:36:59Z rouault $")
+SHP_CVSID("$Id: shpopen.c 40020 2017-09-07 11:41:25Z rouault $")
 
 typedef unsigned char uchar;
 
@@ -1583,7 +1583,8 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
     int i;
     uchar	*pabyRec;
     int32	i32;
-    int     bExtendFile = FALSE;
+    int     bAppendToLastRecord = FALSE;
+    int     bAppendToFile = FALSE;
 
     psSHP->bUpdated = TRUE;
 
@@ -1880,6 +1881,7 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
                         psSHP->panRecSize[nShapeId] + 8 == psSHP->nFileSize )
     {
         nRecordOffset = psSHP->panRecOffset[nShapeId];
+        bAppendToLastRecord = TRUE;
     }
     else if( nShapeId == -1 || psSHP->panRecSize[nShapeId] < nRecordSize-8 )
     {
@@ -1895,7 +1897,7 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
             return -1;
         }
 
-        bExtendFile = TRUE;
+        bAppendToFile = TRUE;
         nRecordOffset = psSHP->nFileSize;
     }
     else
@@ -1948,7 +1950,11 @@ SHPWriteObject(SHPHandle psSHP, int nShapeId, SHPObject * psObject )
 
     free( pabyRec );
 
-    if( bExtendFile )
+    if( bAppendToLastRecord )
+    {
+        psSHP->nFileSize = psSHP->panRecOffset[nShapeId] + nRecordSize; 
+    }
+    else if( bAppendToFile )
     {
         if( nShapeId == -1 )
             nShapeId = psSHP->nRecords++;
diff --git a/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp b/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp
index 159d9bc..849d16f 100644
--- a/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp
+++ b/ogr/ogrsf_frmts/sqlite/ogrsqlitetablelayer.cpp
@@ -38,7 +38,7 @@
 static const char UNSUPPORTED_OP_READ_ONLY[] =
   "%s : unsupported operation on a read-only datasource.";
 
-CPL_CVSID("$Id: ogrsqlitetablelayer.cpp 37810 2017-03-20 16:23:30Z rouault $");
+CPL_CVSID("$Id: ogrsqlitetablelayer.cpp 39914 2017-08-23 13:07:42Z rouault $");
 
 /************************************************************************/
 /*                        OGRSQLiteTableLayer()                         */
@@ -3034,9 +3034,9 @@ OGRErr OGRSQLiteTableLayer::RunDeferredCreationIfNecessary()
 
     CPLString osCommand;
 
-    osCommand.Printf( "CREATE TABLE '%s' ( %s INTEGER PRIMARY KEY AUTOINCREMENT",
+    osCommand.Printf( "CREATE TABLE '%s' ( \"%s\" INTEGER PRIMARY KEY AUTOINCREMENT",
                       pszEscapedTableName,
-                      pszFIDColumn );
+                      SQLEscapeName(pszFIDColumn).c_str() );
 
     if ( !poDS->IsSpatialiteDB() )
     {
diff --git a/ogr/ogrsf_frmts/vrt/ogrvrtdatasource.cpp b/ogr/ogrsf_frmts/vrt/ogrvrtdatasource.cpp
index f80b22d..d6d2900 100644
--- a/ogr/ogrsf_frmts/vrt/ogrvrtdatasource.cpp
+++ b/ogr/ogrsf_frmts/vrt/ogrvrtdatasource.cpp
@@ -33,7 +33,7 @@
 #include "ogrwarpedlayer.h"
 #include "ogrunionlayer.h"
 
-CPL_CVSID("$Id: ogrvrtdatasource.cpp 36883 2016-12-15 13:31:12Z rouault $");
+CPL_CVSID("$Id: ogrvrtdatasource.cpp 39909 2017-08-22 22:14:32Z rouault $");
 
 /************************************************************************/
 /*                       OGRVRTGetGeometryType()                        */
@@ -828,6 +828,8 @@ bool OGRVRTDataSource::Initialize( CPLXMLNode *psTreeIn, const char *pszNewName,
 {
     CPLAssert( nLayers == 0 );
 
+    AddForbiddenNames(pszNewName);
+
     psTree = psTreeIn;
 
 /* -------------------------------------------------------------------- */
diff --git a/ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp b/ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp
index 681141d..b968caa 100644
--- a/ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp
+++ b/ogr/ogrsf_frmts/vrt/ogrvrtlayer.cpp
@@ -33,7 +33,7 @@
 #include "ogrpgeogeometry.h"
 #include <string>
 
-CPL_CVSID("$Id: ogrvrtlayer.cpp 37371 2017-02-13 11:41:59Z rouault $");
+CPL_CVSID("$Id: ogrvrtlayer.cpp 39817 2017-08-14 15:47:46Z rouault $");
 
 #define UNSUPPORTED_OP_READ_ONLY "%s : unsupported operation on a read-only datasource."
 
@@ -1119,7 +1119,11 @@ error:
     CPLFree( pszSrcDSName );
     poFeatureDefn->Release();
     poFeatureDefn = new OGRFeatureDefn( osName );
+    poFeatureDefn->SetGeomType(wkbNone);
     poFeatureDefn->Reference();
+    for( size_t i = 0; i < apoGeomFieldProps.size(); i++ )
+        delete apoGeomFieldProps[i];
+    apoGeomFieldProps.clear();
     return false;
 }
 
diff --git a/ogr/ogrspatialreference.cpp b/ogr/ogrspatialreference.cpp
index d0dd12d..9d859e1 100644
--- a/ogr/ogrspatialreference.cpp
+++ b/ogr/ogrspatialreference.cpp
@@ -49,7 +49,7 @@
 #include "ogr_p.h"
 #include "ogr_srs_api.h"
 
-CPL_CVSID("$Id: ogrspatialreference.cpp 37774 2017-03-18 20:52:44Z rouault $");
+CPL_CVSID("$Id: ogrspatialreference.cpp 40009 2017-09-05 21:14:33Z rouault $");
 
 // The current opinion is that WKT longitudes like central meridian
 // should be relative to Greenwich, not the prime meridian in use.
@@ -6646,6 +6646,20 @@ int OGRSpatialReference::IsSame( const OGRSpatialReference * poOtherSRS ) const
         return FALSE;
 
 /* -------------------------------------------------------------------- */
+/*      Compare proj.4 extensions.                                      */
+/* -------------------------------------------------------------------- */
+    const char* pszThisProj4Ext = GetExtension(NULL, "PROJ4", NULL);
+    const char* pszOtherProj4Ext = poOtherSRS->GetExtension(NULL, "PROJ4", NULL);
+    if( (pszThisProj4Ext == NULL && pszOtherProj4Ext != NULL) ||
+        (pszThisProj4Ext != NULL && pszOtherProj4Ext == NULL) ||
+        (pszThisProj4Ext != NULL && pszOtherProj4Ext != NULL &&
+         !EQUAL(CPLString(pszThisProj4Ext).Trim().replaceAll("  "," "),
+                CPLString(pszOtherProj4Ext).Trim().replaceAll("  "," "))) )
+    {
+        return FALSE;
+    }
+
+/* -------------------------------------------------------------------- */
 /*      Compare geographic coordinate system.                           */
 /* -------------------------------------------------------------------- */
     if( !IsSameGeogCS( poOtherSRS ) )
diff --git a/ogr/ogrutils.cpp b/ogr/ogrutils.cpp
index d687a0a..1a91a8c 100644
--- a/ogr/ogrutils.cpp
+++ b/ogr/ogrutils.cpp
@@ -48,7 +48,7 @@
 #include "ogr_geometry.h"
 #include "ogrsf_frmts.h"
 
-CPL_CVSID("$Id: ogrutils.cpp 38076 2017-04-20 19:37:14Z rouault $");
+CPL_CVSID("$Id: ogrutils.cpp 39911 2017-08-23 08:09:02Z rouault $");
 
 // Returns whether a double fits within an int.
 // Unable to put this in cpl_port.h as include limit breaks grib.
@@ -1070,6 +1070,8 @@ int OGRParseDate( const char *pszInput,
 
     if( strstr(pszInput, ":") != NULL )
     {
+        if( !(*pszInput >= '0' && *pszInput <= '9') )
+            return FALSE;
         psField->Date.Hour = static_cast<GByte>(atoi(pszInput));
         if( psField->Date.Hour > 23 )
             return FALSE;
@@ -1081,6 +1083,8 @@ int OGRParseDate( const char *pszInput,
         else
             ++pszInput;
 
+        if( !(*pszInput >= '0' && *pszInput <= '9') )
+            return FALSE;
         psField->Date.Minute = static_cast<GByte>(atoi(pszInput));
         if( psField->Date.Minute > 59 )
             return FALSE;
@@ -1091,6 +1095,8 @@ int OGRParseDate( const char *pszInput,
         {
             ++pszInput;
 
+            if( !(*pszInput >= '0' && *pszInput <= '9') )
+                return FALSE;
             psField->Date.Second = static_cast<float>(CPLAtof(pszInput));
             if( psField->Date.Second > 61 )
                 return FALSE;
diff --git a/port/cpl_error.cpp b/port/cpl_error.cpp
index 68bed85..e614e18 100644
--- a/port/cpl_error.cpp
+++ b/port/cpl_error.cpp
@@ -43,10 +43,14 @@
 #include "cpl_string.h"
 #include "cpl_vsi.h"
 
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
+
 #define TIMESTAMP_DEBUG
 // #define MEMORY_DEBUG
 
-CPL_CVSID("$Id: cpl_error.cpp 38237 2017-05-13 10:04:44Z rouault $");
+CPL_CVSID("$Id: cpl_error.cpp 39443 2017-07-02 21:20:37Z rouault $");
 
 static CPLMutex *hErrorMutex = NULL;
 static void *pErrorHandlerUserData = NULL;
diff --git a/port/cpl_string.cpp b/port/cpl_string.cpp
index cf386b1..680f735 100644
--- a/port/cpl_string.cpp
+++ b/port/cpl_string.cpp
@@ -59,7 +59,11 @@
 #include "cpl_multiproc.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: cpl_string.cpp 38379 2017-05-15 11:25:22Z rouault $");
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
+
+CPL_CVSID("$Id: cpl_string.cpp 39443 2017-07-02 21:20:37Z rouault $");
 
 /*=====================================================================
                     StringList manipulation functions.
diff --git a/port/cpl_strtod.cpp b/port/cpl_strtod.cpp
index 9d6c1f4..3dbc1cd 100644
--- a/port/cpl_strtod.cpp
+++ b/port/cpl_strtod.cpp
@@ -38,7 +38,7 @@
 
 #include "cpl_config.h"
 
-CPL_CVSID("$Id: cpl_strtod.cpp 36928 2016-12-17 06:12:35Z goatbar $");
+CPL_CVSID("$Id: cpl_strtod.cpp 40017 2017-09-07 10:31:06Z rouault $");
 
 // XXX: with GCC 2.95 strtof() function is only available when in c99 mode.
 // Fix it here not touching the compiler options.
@@ -235,8 +235,8 @@ double CPLStrtodDelim(const char *nptr, char **endptr, char point)
 
     if( nptr[0] == '-' )
     {
-        if( strcmp(nptr, "-1.#QNAN") == 0 ||
-            strcmp(nptr, "-1.#IND") == 0 )
+        if( STARTS_WITH(nptr, "-1.#QNAN") ||
+            STARTS_WITH(nptr, "-1.#IND") )
         {
             if( endptr ) *endptr = const_cast<char *>(nptr) + strlen(nptr);
             // While it is possible on some platforms to flip the sign
@@ -254,7 +254,7 @@ double CPLStrtodDelim(const char *nptr, char **endptr, char point)
     }
     else if( nptr[0] == '1' )
     {
-        if( strcmp(nptr, "1.#QNAN") == 0 )
+        if( STARTS_WITH(nptr, "1.#QNAN") )
         {
             if( endptr ) *endptr = const_cast<char *>(nptr) + strlen(nptr);
             return std::numeric_limits<double>::quiet_NaN();
diff --git a/port/cpl_vsi_error.cpp b/port/cpl_vsi_error.cpp
index 69bc3ed..fa4f186 100644
--- a/port/cpl_vsi_error.cpp
+++ b/port/cpl_vsi_error.cpp
@@ -40,6 +40,10 @@
 #include "cpl_string.h"
 #include "cpl_vsi.h"
 
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
+
 // TODO(rouault): Why is this here?
 #if !defined(WIN32)
 #include <string.h>
@@ -48,7 +52,7 @@
 #define TIMESTAMP_DEBUG
 // #define MEMORY_DEBUG
 
-CPL_CVSID("$Id: cpl_vsi_error.cpp 37003 2016-12-23 14:54:07Z goatbar $");
+CPL_CVSID("$Id: cpl_vsi_error.cpp 39443 2017-07-02 21:20:37Z rouault $");
 
 static const int DEFAULT_LAST_ERR_MSG_SIZE =
 #if !defined(HAVE_VSNPRINTF)
diff --git a/port/cpl_vsi_mem.cpp b/port/cpl_vsi_mem.cpp
index b0fee0b..662650f 100644
--- a/port/cpl_vsi_mem.cpp
+++ b/port/cpl_vsi_mem.cpp
@@ -54,7 +54,7 @@
 
 //! @cond Doxygen_Suppress
 
-CPL_CVSID("$Id: cpl_vsi_mem.cpp 36990 2016-12-21 19:42:05Z goatbar $");
+CPL_CVSID("$Id: cpl_vsi_mem.cpp 39299 2017-06-25 22:06:49Z rouault $");
 
 /*
 ** Notes on Multithreading:
@@ -377,14 +377,13 @@ size_t VSIMemHandle::Read( void * pBuffer, size_t nSize, size_t nCount )
     // FIXME: Integer overflow check should be placed here:
     size_t nBytesToRead = nSize * nCount;
 
+    if( poFile->nLength < m_nOffset )
+    {
+        bEOF = true;
+        return 0;
+    }
     if( nBytesToRead + m_nOffset > poFile->nLength )
     {
-        if( poFile->nLength < m_nOffset )
-        {
-            bEOF = true;
-            return 0;
-        }
-
         nBytesToRead = static_cast<size_t>(poFile->nLength - m_nOffset);
         nCount = nBytesToRead / nSize;
         bEOF = true;
diff --git a/port/cpl_vsil_crypt.cpp b/port/cpl_vsil_crypt.cpp
index 32d3b2b..83ec771 100644
--- a/port/cpl_vsil_crypt.cpp
+++ b/port/cpl_vsil_crypt.cpp
@@ -44,7 +44,7 @@ void CPL_DLL VSIInstallCryptFileHandler();
 void CPL_DLL VSISetCryptKey( const GByte* pabyKey, int nKeySize );
 CPL_C_END
 
-CPL_CVSID("$Id: cpl_vsil_crypt.cpp 37003 2016-12-23 14:54:07Z goatbar $");
+CPL_CVSID("$Id: cpl_vsil_crypt.cpp 40012 2017-09-06 12:52:12Z rouault $");
 
 static const char VSICRYPT_PREFIX[] = "/vsicrypt/";
 
@@ -2100,7 +2100,7 @@ void VSISetCryptKey( const GByte* /* pabyKey */, int /* nKeySize */ )
 
 #endif  // HAVE_CRYPTOPP
 
-// Below is only useful if using as a plugin over GDAL 1.11 or GDAL 2.0.
+// Below is only useful if using as a plugin over GDAL >= 2.0.
 #ifdef VSICRYPT_AUTOLOAD
 
 CPL_C_START
@@ -2109,22 +2109,37 @@ CPL_C_END
 
 void GDALRegisterMe()
 {
-    if( VSIFileManager::GetHandler(VSICRYPT_PREFIX) ==
-        VSIFileManager::GetHandler(".") )
-        VSIInstallCryptFileHandler();
-}
-
-#ifndef GDAL_DCAP_RASTER
-CPL_C_START
-void CPL_DLL RegisterOGRCRYPT();
-CPL_C_END
-
-void RegisterOGRCRYPT()
-{
-    if( VSIFileManager::GetHandler(VSICRYPT_PREFIX) ==
-        VSIFileManager::GetHandler(".") )
+    VSIFilesystemHandler* poExistingHandler =
+                    VSIFileManager::GetHandler(VSICRYPT_PREFIX);
+    if( poExistingHandler == VSIFileManager::GetHandler(".") )
+    {
+        // In the case where VSICRYPT_PREFIX is just handled by the regular
+        // handler, install the vsicrypt handler (shouldn't happen)
         VSIInstallCryptFileHandler();
+    }
+    else
+    {
+        // If there's already an installed handler, then check if it is a
+        // dummy one (should normally be the case) or a real one
+        CPLErrorReset();
+        CPLPushErrorHandler(CPLQuietErrorHandler);
+        VSIStatBufL sStat;
+        CPL_IGNORE_RET_VAL(
+            VSIStatL((CPLString(VSICRYPT_PREFIX) + "i_do_not_exist").c_str(), &sStat));
+        CPLPopErrorHandler();
+        if( strstr(CPLGetLastErrorMsg(), "support not available in this build") )
+        {
+            // Dummy handler. Register the new one, and delete the old one
+            VSIInstallCryptFileHandler();
+            delete poExistingHandler;
+        }
+        else
+        {
+            CPLDebug("VSICRYPT", "GDAL has already a working %s implementation",
+                     VSICRYPT_PREFIX);
+        }
+        CPLErrorReset();
+    }
 }
-#endif
 
 #endif /* VSICRYPT_AUTOLOAD */
diff --git a/port/cpl_vsil_curl.cpp b/port/cpl_vsil_curl.cpp
index 922543b..5d7a5b9 100644
--- a/port/cpl_vsil_curl.cpp
+++ b/port/cpl_vsil_curl.cpp
@@ -42,7 +42,7 @@
 #include "cpl_vsi_virtual.h"
 #include "cpl_http.h"
 
-CPL_CVSID("$Id: cpl_vsil_curl.cpp 39224 2017-06-21 08:50:19Z rouault $");
+CPL_CVSID("$Id: cpl_vsil_curl.cpp 39326 2017-06-27 14:31:43Z rouault $");
 
 #ifndef HAVE_CURL
 
@@ -4761,6 +4761,7 @@ char** VSIGSFSHandler::GetFileList( const char *pszDirname,
         }
         else
         {
+            CPLFree(sWriteFuncData.pBuffer);
             delete poHandleHelper;
             return NULL;
         }
diff --git a/port/cpl_vsil_gzip.cpp b/port/cpl_vsil_gzip.cpp
index a39f173..edfd80c 100644
--- a/port/cpl_vsil_gzip.cpp
+++ b/port/cpl_vsil_gzip.cpp
@@ -108,7 +108,7 @@
 #include "cpl_vsi_virtual.h"
 
 
-CPL_CVSID("$Id: cpl_vsil_gzip.cpp 38248 2017-05-13 12:58:34Z rouault $");
+CPL_CVSID("$Id: cpl_vsil_gzip.cpp 39920 2017-08-23 14:16:26Z rouault $");
 
 static const int Z_BUFSIZE = 65536;  // Original size is 16384
 static const int gz_magic[2] = {0x1f, 0x8b};  // gzip magic header
@@ -836,7 +836,9 @@ int VSIGZipHandle::gzseek( vsi_l_offset offset, int whence )
     {
         m_uncompressed_size = out;
 
-        if( m_pszBaseFileName )
+        if( m_pszBaseFileName &&
+            !STARTS_WITH_CI(m_pszBaseFileName, "/vsicurl/") &&
+            CPLTestBool(CPLGetConfigOption("CPL_VSIL_GZIP_WRITE_PROPERTIES", "YES")) )
         {
             CPLString osCacheFilename (m_pszBaseFileName);
             osCacheFilename += ".properties";
@@ -1024,10 +1026,6 @@ size_t VSIGZipHandle::Read( void * const buf, size_t const nSize,
                     z_err = Z_ERRNO;
                     break;
                 }
-                // if( ferror (file) ) {
-                //    z_err = Z_ERRNO;
-                //    break;
-                // }
             }
             stream.next_in = inbuf;
         }
@@ -1094,7 +1092,7 @@ size_t VSIGZipHandle::Read( void * const buf, size_t const nSize,
     crc = crc32(crc, pStart, static_cast<uInt>(stream.next_out - pStart));
 
     if( len == stream.avail_out &&
-        (z_err == Z_DATA_ERROR || z_err == Z_ERRNO) )
+        (z_err == Z_DATA_ERROR || z_err == Z_ERRNO || z_err == Z_BUF_ERROR) )
     {
         z_eof = 1;
         in = 0;
diff --git a/port/cplkeywordparser.cpp b/port/cplkeywordparser.cpp
index 131ef6a..a7898c2 100644
--- a/port/cplkeywordparser.cpp
+++ b/port/cplkeywordparser.cpp
@@ -42,7 +42,7 @@
 #include "cpl_string.h"
 #include "cpl_vsi.h"
 
-CPL_CVSID("$Id: cplkeywordparser.cpp 36979 2016-12-20 18:40:40Z rouault $");
+CPL_CVSID("$Id: cplkeywordparser.cpp 39685 2017-07-29 19:55:24Z rouault $");
 
 /************************************************************************/
 /* ==================================================================== */
@@ -258,7 +258,7 @@ int CPLKeywordParser::ReadWord( CPLString &osWord )
 
     SkipWhite();
 
-    if( *pszHeaderNext == '\0' )
+    if( *pszHeaderNext == '\0' || *pszHeaderNext == '=' )
         return FALSE;
 
     while( *pszHeaderNext != '\0'
@@ -330,6 +330,8 @@ void CPLKeywordParser::SkipWhite()
             {
                 pszHeaderNext++;
             }
+            if( *pszHeaderNext == '\0' )
+                break;
 
             pszHeaderNext += 2;
             continue;
diff --git a/port/cplstring.cpp b/port/cplstring.cpp
index bc98411..4faaf3e 100644
--- a/port/cplstring.cpp
+++ b/port/cplstring.cpp
@@ -39,7 +39,11 @@
 #include "cpl_config.h"
 #include "cpl_conv.h"
 
-CPL_CVSID("$Id: cplstring.cpp 36981 2016-12-20 19:46:41Z rouault $");
+#if !defined(va_copy) && defined(__va_copy)
+#define va_copy __va_copy
+#endif
+
+CPL_CVSID("$Id: cplstring.cpp 39443 2017-07-02 21:20:37Z rouault $");
 
 /*
  * The CPLString class is derived from std::string, so the vast majority
diff --git a/swig/csharp/apps/GDALDatasetRasterIOEx.cs b/swig/csharp/apps/GDALDatasetRasterIOEx.cs
new file mode 100644
index 0000000..80c8afe
--- /dev/null
+++ b/swig/csharp/apps/GDALDatasetRasterIOEx.cs
@@ -0,0 +1,329 @@
+/******************************************************************************
+ * $Id: GDALReadDirect.cs 13437 2007-12-21 21:02:38Z tamas $
+ *
+ * Name:     GDALDatasetRasterIO.cs
+ * Project:  GDAL CSharp Interface
+ * Purpose:  A sample app to read GDAL raster data directly to a C# bitmap.
+ * Author:   Tamas Szekeres, szekerest at gmail.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2007, Tamas Szekeres
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *****************************************************************************/
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Runtime.InteropServices;
+
+using OSGeo.GDAL;
+
+
+/**
+
+ * <p>Title: GDAL C# GDALDatasetRasterIO example.</p>
+ * <p>Description: A sample app to read GDAL raster data directly to a C# bitmap.</p>
+ * @author Tamas Szekeres (szekerest at gmail.com)
+ * @version 1.0
+ */
+
+
+
+/// <summary>
+/// A C# based sample to read GDAL raster data directly to a C# bitmap.
+/// </summary> 
+
+class GDALReadDirect {
+	
+	public static void usage() 
+
+	{
+        Console.WriteLine("usage: GDALDatasetRasterIOEx {GDAL dataset name} {output file name} {scale = 0.5} {version = 1} {resample alg = GRIORA_NearestNeighbour}");
+		System.Environment.Exit(-1);
+	}
+
+    public static int ProgressFunc(double Complete, IntPtr Message, IntPtr Data)
+    {
+        Console.Write("Processing ... " + Complete * 100 + "% Completed.");
+        if (Message != IntPtr.Zero)
+            Console.Write(" Message:" + System.Runtime.InteropServices.Marshal.PtrToStringAnsi(Message));
+        if (Data != IntPtr.Zero)
+            Console.Write(" Data:" + System.Runtime.InteropServices.Marshal.PtrToStringUni(Data));
+
+        Console.WriteLine("");
+        return 1;
+    }
+
+    private static RIOResampleAlg resampleAlg = RIOResampleAlg.GRIORA_NearestNeighbour;
+    private static int argVersion = 1;
+    private static double scale = 0.5;
+ 
+    public static void Main(string[] args) 
+    {
+        if (args.Length < 2) usage();
+
+        // Using early initialization of System.Console
+        Console.WriteLine("");
+
+        try 
+        {
+            /* -------------------------------------------------------------------- */
+            /*      Register driver(s).                                             */
+            /* -------------------------------------------------------------------- */
+            Gdal.AllRegister();
+
+            /* -------------------------------------------------------------------- */
+            /*      Open dataset.                                                   */
+            /* -------------------------------------------------------------------- */
+            Dataset ds = Gdal.Open( args[0], Access.GA_ReadOnly );
+		
+            if (ds == null) 
+            {
+                Console.WriteLine("Can't open " + args[0]);
+                System.Environment.Exit(-1);
+            }
+
+            Console.WriteLine("Raster dataset parameters:");
+            Console.WriteLine("  Projection: " + ds.GetProjectionRef());
+            Console.WriteLine("  RasterCount: " + ds.RasterCount);
+            Console.WriteLine("  RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");
+            
+            /* -------------------------------------------------------------------- */
+            /*      Get driver                                                      */
+            /* -------------------------------------------------------------------- */	
+            Driver drv = ds.GetDriver();
+
+            if (drv == null) 
+            {
+                Console.WriteLine("Can't get driver.");
+                System.Environment.Exit(-1);
+            }
+            
+            Console.WriteLine("Using driver " + drv.LongName);
+
+            if (args.Length > 2)
+                scale = double.Parse(args[2]);
+
+            if (args.Length > 3)
+                argVersion = int.Parse(args[3]);
+
+            if (args.Length > 4)
+                resampleAlg = (RIOResampleAlg)Enum.Parse(typeof(RIOResampleAlg), args[4]);
+
+            /* -------------------------------------------------------------------- */
+            /*      Processing the raster                                           */
+            /* -------------------------------------------------------------------- */
+            SaveBitmapDirect(args[1], ds, 0, 0, ds.RasterXSize, ds.RasterYSize, Convert.ToInt32(scale * ds.RasterXSize), Convert.ToInt32(scale * ds.RasterYSize));
+            
+        }
+        catch (Exception e)
+        {
+            Console.WriteLine("Application error: " + e.Message);
+        }
+    }
+
+    private static void SaveBitmapDirect(string filename, Dataset ds, int xOff, int yOff, int width, int height, int imageWidth, int imageHeight)
+    {
+        if (ds.RasterCount == 0)
+            return;
+
+        int[] bandMap = new int[4] { 1, 1, 1, 1 };
+        int channelCount = 1;
+        bool hasAlpha = false;
+        bool isIndexed = false;
+        int channelSize = 8;
+        ColorTable ct = null;
+        // Evaluate the bands and find out a proper image transfer format
+        for (int i = 0; i < ds.RasterCount; i++)
+        {
+            Band band = ds.GetRasterBand(i + 1);
+            if (Gdal.GetDataTypeSize(band.DataType) > 8)
+                channelSize = 16;
+            switch (band.GetRasterColorInterpretation())
+            {
+                case ColorInterp.GCI_AlphaBand:
+                    channelCount = 4;
+                    hasAlpha = true;
+                    bandMap[3] = i + 1;
+                    break;
+                case ColorInterp.GCI_BlueBand:
+                    if (channelCount < 3)
+                        channelCount = 3;
+                    bandMap[0] = i + 1;
+                    break;
+                case ColorInterp.GCI_RedBand:
+                    if (channelCount < 3)
+                        channelCount = 3;
+                    bandMap[2] = i + 1;
+                    break;
+                case ColorInterp.GCI_GreenBand:
+                    if (channelCount < 3)
+                        channelCount = 3;
+                    bandMap[1] = i + 1;
+                    break;
+                case ColorInterp.GCI_PaletteIndex:
+                    ct = band.GetRasterColorTable();
+                    isIndexed = true;
+                    bandMap[0] = i + 1;
+                    break;
+                case ColorInterp.GCI_GrayIndex:
+                    isIndexed = true;
+                    bandMap[0] = i + 1;
+                    break;
+                default:
+                    // we create the bandmap using the dataset ordering by default
+                    if (i < 4 && bandMap[i] == 0)
+                    {
+                        if (channelCount < i)
+                            channelCount = i;
+                        bandMap[i] = i + 1;
+                    }
+                    break;
+            }
+        }
+
+        // find out the pixel format based on the gathered information
+        PixelFormat pixelFormat;
+        DataType dataType;
+        int pixelSpace;
+
+        if (isIndexed)
+        {
+            pixelFormat = PixelFormat.Format8bppIndexed;
+            dataType = DataType.GDT_Byte;
+            pixelSpace = 1;
+        }
+        else
+        {
+            if (channelCount == 1)
+            {
+                if (channelSize > 8)
+                {
+                    pixelFormat = PixelFormat.Format16bppGrayScale;
+                    dataType = DataType.GDT_Int16;
+                    pixelSpace = 2;
+                }
+                else
+                {
+                    pixelFormat = PixelFormat.Format24bppRgb;
+                    channelCount = 3;
+                    dataType = DataType.GDT_Byte;
+                    pixelSpace = 3;
+                }
+            }
+            else
+            {
+                if (hasAlpha)
+                {
+                    if (channelSize > 8)
+                    {
+                        pixelFormat = PixelFormat.Format64bppArgb;
+                        dataType = DataType.GDT_UInt16;
+                        pixelSpace = 8;
+                    }
+                    else
+                    {
+                        pixelFormat = PixelFormat.Format32bppArgb;
+                        dataType = DataType.GDT_Byte;
+                        pixelSpace = 4;
+                    }
+                    channelCount = 4;
+                }
+                else
+                {
+                    if (channelSize > 8)
+                    {
+                        pixelFormat = PixelFormat.Format48bppRgb;
+                        dataType = DataType.GDT_UInt16;
+                        pixelSpace = 6;
+                    }
+                    else
+                    {
+                        pixelFormat = PixelFormat.Format24bppRgb;
+                        dataType = DataType.GDT_Byte;
+                        pixelSpace = 3;
+                    }
+                    channelCount = 3;
+                }
+            }
+        }
+
+
+        // Create a Bitmap to store the GDAL image in
+        Bitmap bitmap = new Bitmap(imageWidth, imageHeight, pixelFormat);
+
+        if (isIndexed)
+        {
+            // setting up the color table
+            if (ct != null)
+            {
+                int iCol = ct.GetCount();
+                ColorPalette pal = bitmap.Palette;
+                for (int i = 0; i < iCol; i++)
+                {
+                    ColorEntry ce = ct.GetColorEntry(i);
+                    pal.Entries[i] = Color.FromArgb(ce.c4, ce.c1, ce.c2, ce.c3);
+                }
+                bitmap.Palette = pal;
+            }
+            else
+            {
+                // grayscale
+                ColorPalette pal = bitmap.Palette;
+                for (int i = 0; i < 256; i++)
+                    pal.Entries[i] = Color.FromArgb(255, i, i, i);
+                bitmap.Palette = pal;
+            }
+        }
+
+        // Use GDAL raster reading methods to read the image data directly into the Bitmap
+        BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, imageWidth, imageHeight), ImageLockMode.ReadWrite, pixelFormat);
+
+        try
+        {
+            int stride = bitmapData.Stride;
+            IntPtr buf = bitmapData.Scan0;
+
+            using (RasterIOExtraArg arg = new RasterIOExtraArg())
+            {
+                GCHandle handle = GCHandle.Alloc("Test data", GCHandleType.Pinned);
+                try {               
+                    arg.nVersion = argVersion;
+                    arg.eResampleAlg = resampleAlg;
+                    arg.pfnProgress = new Gdal.GDALProgressFuncDelegate(ProgressFunc);
+                    arg.pProgressData = handle.AddrOfPinnedObject();  // or IntPtr.Zero if not data to be added;
+                    arg.bFloatingPointWindowValidity = 0;
+                    ds.ReadRaster(xOff, yOff, width, height, buf, imageWidth, imageHeight, dataType,
+                        channelCount, bandMap, pixelSpace, stride, 1, arg);
+                }
+                finally
+                {
+                    handle.Free();
+                }
+            }
+        }
+        finally
+        {
+            bitmap.UnlockBits(bitmapData);
+        }
+
+        bitmap.Save(filename);
+    }
+}
\ No newline at end of file
diff --git a/swig/csharp/gdal/Band.cs b/swig/csharp/gdal/Band.cs
index 5b7905c..ff63df9 100644
--- a/swig/csharp/gdal/Band.cs
+++ b/swig/csharp/gdal/Band.cs
@@ -58,7 +58,7 @@ public class Band : MajorObject {
       base.Dispose();
     }
   }
-/*! Eight bit unsigned integer */ /*@SWIG:../include/csharp/gdal_csharp.i,52,%rasterio_functions@*/
+/*! Eight bit unsigned integer */ /*@SWIG:../include/csharp/gdal_csharp.i,84,%rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace) {
       CPLErr retval;
       GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
@@ -81,9 +81,31 @@ public class Band : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Byte, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Byte, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Sixteen bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,52,%rasterio_functions@*/
+/*! Sixteen bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,84,%rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace) {
       CPLErr retval;
       GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
@@ -106,9 +128,31 @@ public class Band : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int16, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int16, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Thirty two bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,52,%rasterio_functions@*/
+/*! Thirty two bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,84,%rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace) {
       CPLErr retval;
       GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
@@ -131,9 +175,31 @@ public class Band : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int32, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int32, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Thirty two bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,52,%rasterio_functions@*/
+/*! Thirty two bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,84,%rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace) {
       CPLErr retval;
       GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
@@ -156,9 +222,31 @@ public class Band : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float32, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float32, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Sixty four bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,52,%rasterio_functions@*/
+/*! Sixty four bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,84,%rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace) {
       CPLErr retval;
       GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
@@ -181,6 +269,28 @@ public class Band : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float64, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float64, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
   public int XSize {
@@ -505,13 +615,25 @@ public class Band : MajorObject {
   }
 
   public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace) {
-    CPLErr ret = (CPLErr)GdalPINVOKE.Band_ReadRaster(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace);
+    CPLErr ret = (CPLErr)GdalPINVOKE.Band_ReadRaster__SWIG_0(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace);
     if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
 
   public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace) {
-    CPLErr ret = (CPLErr)GdalPINVOKE.Band_WriteRaster(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace);
+    CPLErr ret = (CPLErr)GdalPINVOKE.Band_WriteRaster__SWIG_0(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace);
+    if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    return ret;
+  }
+
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+    CPLErr ret = (CPLErr)GdalPINVOKE.Band_ReadRaster__SWIG_1(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace, RasterIOExtraArg.getCPtr(extraArg));
+    if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    return ret;
+  }
+
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+    CPLErr ret = (CPLErr)GdalPINVOKE.Band_WriteRaster__SWIG_1(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, pixelSpace, lineSpace, RasterIOExtraArg.getCPtr(extraArg));
     if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
diff --git a/swig/csharp/gdal/Dataset.cs b/swig/csharp/gdal/Dataset.cs
index 458c1f3..02b08a0 100644
--- a/swig/csharp/gdal/Dataset.cs
+++ b/swig/csharp/gdal/Dataset.cs
@@ -62,7 +62,7 @@ public class Dataset : MajorObject {
       base.Dispose();
     }
   }
-/*! Eight bit unsigned integer */ /*@SWIG:../include/csharp/gdal_csharp.i,93,%ds_rasterio_functions@*/
+/*! Eight bit unsigned integer */ /*@SWIG:../include/csharp/gdal_csharp.i,147,%ds_rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize,
      int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
       CPLErr retval;
@@ -89,9 +89,35 @@ public class Dataset : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Byte,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Byte,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Sixteen bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,93,%ds_rasterio_functions@*/
+/*! Sixteen bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,147,%ds_rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize,
      int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
       CPLErr retval;
@@ -118,9 +144,35 @@ public class Dataset : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int16,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int16,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Thirty two bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,93,%ds_rasterio_functions@*/
+/*! Thirty two bit signed integer */ /*@SWIG:../include/csharp/gdal_csharp.i,147,%ds_rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize,
      int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
       CPLErr retval;
@@ -147,9 +199,35 @@ public class Dataset : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int32,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Int32,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Thirty two bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,93,%ds_rasterio_functions@*/
+/*! Thirty two bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,147,%ds_rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize,
      int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
       CPLErr retval;
@@ -176,9 +254,35 @@ public class Dataset : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float32,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float32,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
-/*! Sixty four bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,93,%ds_rasterio_functions@*/
+/*! Sixty four bit floating point */ /*@SWIG:../include/csharp/gdal_csharp.i,147,%ds_rasterio_functions@*/
  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize,
      int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
       CPLErr retval;
@@ -205,6 +309,32 @@ public class Dataset : MajorObject {
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float64,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, DataType.GDT_Float64,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 /*@SWIG@*/
 
@@ -408,13 +538,25 @@ public CPLErr SetGCPs(GCP[] pGCPs, string pszGCPProjection) {
   }
 
   public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
-    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_ReadRaster(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace);
+    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_ReadRaster__SWIG_0(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace);
     if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
 
   public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace) {
-    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_WriteRaster(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace);
+    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_WriteRaster__SWIG_0(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace);
+    if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    return ret;
+  }
+
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_ReadRaster__SWIG_1(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace, RasterIOExtraArg.getCPtr(extraArg));
+    if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    return ret;
+  }
+
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+    CPLErr ret = (CPLErr)GdalPINVOKE.Dataset_WriteRaster__SWIG_1(swigCPtr, xOff, yOff, xSize, ySize, buffer, buf_xSize, buf_ySize, (int)buf_type, bandCount, bandMap, pixelSpace, lineSpace, bandSpace, RasterIOExtraArg.getCPtr(extraArg));
     if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
     return ret;
   }
diff --git a/swig/csharp/gdal/GdalPINVOKE.cs b/swig/csharp/gdal/GdalPINVOKE.cs
index fffc6e9..1277e03 100644
--- a/swig/csharp/gdal/GdalPINVOKE.cs
+++ b/swig/csharp/gdal/GdalPINVOKE.cs
@@ -220,6 +220,66 @@ class GdalPINVOKE {
   [DllImport("gdal_wrap", EntryPoint="CSharp_StringListDestroy")]
   public static extern void StringListDestroy(IntPtr jarg1);
 
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_nVersion_set")]
+  public static extern void RasterIOExtraArg_nVersion_set(HandleRef jarg1, int jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_nVersion_get")]
+  public static extern int RasterIOExtraArg_nVersion_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_eResampleAlg_set")]
+  public static extern void RasterIOExtraArg_eResampleAlg_set(HandleRef jarg1, int jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_eResampleAlg_get")]
+  public static extern int RasterIOExtraArg_eResampleAlg_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_pfnProgress_set")]
+  public static extern void RasterIOExtraArg_pfnProgress_set(HandleRef jarg1, Gdal.GDALProgressFuncDelegate jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_pfnProgress_get")]
+  public static extern Gdal.GDALProgressFuncDelegate RasterIOExtraArg_pfnProgress_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_pProgressData_set")]
+  public static extern void RasterIOExtraArg_pProgressData_set(HandleRef jarg1, IntPtr jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_pProgressData_get")]
+  public static extern IntPtr RasterIOExtraArg_pProgressData_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_bFloatingPointWindowValidity_set")]
+  public static extern void RasterIOExtraArg_bFloatingPointWindowValidity_set(HandleRef jarg1, int jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_bFloatingPointWindowValidity_get")]
+  public static extern int RasterIOExtraArg_bFloatingPointWindowValidity_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfXOff_set")]
+  public static extern void RasterIOExtraArg_dfXOff_set(HandleRef jarg1, double jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfXOff_get")]
+  public static extern double RasterIOExtraArg_dfXOff_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfYOff_set")]
+  public static extern void RasterIOExtraArg_dfYOff_set(HandleRef jarg1, double jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfYOff_get")]
+  public static extern double RasterIOExtraArg_dfYOff_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfXSize_set")]
+  public static extern void RasterIOExtraArg_dfXSize_set(HandleRef jarg1, double jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfXSize_get")]
+  public static extern double RasterIOExtraArg_dfXSize_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfYSize_set")]
+  public static extern void RasterIOExtraArg_dfYSize_set(HandleRef jarg1, double jarg2);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_RasterIOExtraArg_dfYSize_get")]
+  public static extern double RasterIOExtraArg_dfYSize_get(HandleRef jarg1);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_new_RasterIOExtraArg")]
+  public static extern IntPtr new_RasterIOExtraArg();
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_delete_RasterIOExtraArg")]
+  public static extern void delete_RasterIOExtraArg(HandleRef jarg1);
+
   [DllImport("gdal_wrap", EntryPoint="CSharp_Debug")]
   public static extern void Debug(string jarg1, string jarg2);
 
@@ -697,11 +757,17 @@ class GdalPINVOKE {
   [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_RollbackTransaction")]
   public static extern int Dataset_RollbackTransaction(HandleRef jarg1);
 
-  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_ReadRaster")]
-  public static extern int Dataset_ReadRaster(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14);
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_ReadRaster__SWIG_0")]
+  public static extern int Dataset_ReadRaster__SWIG_0(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_WriteRaster__SWIG_0")]
+  public static extern int Dataset_WriteRaster__SWIG_0(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14);
 
-  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_WriteRaster")]
-  public static extern int Dataset_WriteRaster(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14);
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_ReadRaster__SWIG_1")]
+  public static extern int Dataset_ReadRaster__SWIG_1(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14, HandleRef jarg15);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset_WriteRaster__SWIG_1")]
+  public static extern int Dataset_WriteRaster__SWIG_1(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int[] jarg11, int jarg12, int jarg13, int jarg14, HandleRef jarg15);
 
   [DllImport("gdal_wrap", EntryPoint="CSharp_Dataset___GetGCPs")]
   public static extern IntPtr Dataset___GetGCPs(HandleRef jarg1);
@@ -865,11 +931,17 @@ class GdalPINVOKE {
   [DllImport("gdal_wrap", EntryPoint="CSharp_Band_SetCategoryNames")]
   public static extern int Band_SetCategoryNames(HandleRef jarg1, IntPtr[] jarg2);
 
-  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_ReadRaster")]
-  public static extern int Band_ReadRaster(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11);
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_ReadRaster__SWIG_0")]
+  public static extern int Band_ReadRaster__SWIG_0(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_WriteRaster__SWIG_0")]
+  public static extern int Band_WriteRaster__SWIG_0(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11);
+
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_ReadRaster__SWIG_1")]
+  public static extern int Band_ReadRaster__SWIG_1(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11, HandleRef jarg12);
 
-  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_WriteRaster")]
-  public static extern int Band_WriteRaster(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11);
+  [DllImport("gdal_wrap", EntryPoint="CSharp_Band_WriteRaster__SWIG_1")]
+  public static extern int Band_WriteRaster__SWIG_1(HandleRef jarg1, int jarg2, int jarg3, int jarg4, int jarg5, IntPtr jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11, HandleRef jarg12);
 
   [DllImport("gdal_wrap", EntryPoint="CSharp_new_ColorTable")]
   public static extern IntPtr new_ColorTable(int jarg1);
diff --git a/swig/csharp/gdal/RasterIOExtraArg.cs b/swig/csharp/gdal/RasterIOExtraArg.cs
new file mode 100644
index 0000000..694585e
--- /dev/null
+++ b/swig/csharp/gdal/RasterIOExtraArg.cs
@@ -0,0 +1,185 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.12
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+namespace OSGeo.GDAL {
+
+using System;
+using System.Runtime.InteropServices;
+
+public class RasterIOExtraArg : IDisposable {
+  private HandleRef swigCPtr;
+  protected bool swigCMemOwn;
+  protected object swigParentRef;
+
+  protected static object ThisOwn_true() { return null; }
+  protected object ThisOwn_false() { return this; }
+
+  public RasterIOExtraArg(IntPtr cPtr, bool cMemoryOwn, object parent) {
+    swigCMemOwn = cMemoryOwn;
+    swigParentRef = parent;
+    swigCPtr = new HandleRef(this, cPtr);
+  }
+
+  public static HandleRef getCPtr(RasterIOExtraArg obj) {
+    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
+  }
+  public static HandleRef getCPtrAndDisown(RasterIOExtraArg obj, object parent) {
+    if (obj != null)
+    {
+      obj.swigCMemOwn = false;
+      obj.swigParentRef = parent;
+      return obj.swigCPtr;
+    }
+    else
+    {
+      return new HandleRef(null, IntPtr.Zero);
+    }
+  }
+  public static HandleRef getCPtrAndSetReference(RasterIOExtraArg obj, object parent) {
+    if (obj != null)
+    {
+      obj.swigParentRef = parent;
+      return obj.swigCPtr;
+    }
+    else
+    {
+      return new HandleRef(null, IntPtr.Zero);
+    }
+  }
+
+  ~RasterIOExtraArg() {
+    Dispose();
+  }
+
+  public virtual void Dispose() {
+  lock(this) {
+      if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) {
+        swigCMemOwn = false;
+        GdalPINVOKE.delete_RasterIOExtraArg(swigCPtr);
+      }
+      swigCPtr = new HandleRef(null, IntPtr.Zero);
+      swigParentRef = null;
+      GC.SuppressFinalize(this);
+    }
+  }
+
+  public int nVersion {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_nVersion_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      int ret = GdalPINVOKE.RasterIOExtraArg_nVersion_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public RIOResampleAlg eResampleAlg {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_eResampleAlg_set(swigCPtr, (int)value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      RIOResampleAlg ret = (RIOResampleAlg)GdalPINVOKE.RasterIOExtraArg_eResampleAlg_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public Gdal.GDALProgressFuncDelegate pfnProgress {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_pfnProgress_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      Gdal.GDALProgressFuncDelegate ret = GdalPINVOKE.RasterIOExtraArg_pfnProgress_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public IntPtr pProgressData {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_pProgressData_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      IntPtr ret = GdalPINVOKE.RasterIOExtraArg_pProgressData_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public int bFloatingPointWindowValidity {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_bFloatingPointWindowValidity_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      int ret = GdalPINVOKE.RasterIOExtraArg_bFloatingPointWindowValidity_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public double dfXOff {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_dfXOff_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      double ret = GdalPINVOKE.RasterIOExtraArg_dfXOff_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public double dfYOff {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_dfYOff_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      double ret = GdalPINVOKE.RasterIOExtraArg_dfYOff_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public double dfXSize {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_dfXSize_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      double ret = GdalPINVOKE.RasterIOExtraArg_dfXSize_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public double dfYSize {
+    set {
+      GdalPINVOKE.RasterIOExtraArg_dfYSize_set(swigCPtr, value);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+    } 
+    get {
+      double ret = GdalPINVOKE.RasterIOExtraArg_dfYSize_get(swigCPtr);
+      if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+      return ret;
+    } 
+  }
+
+  public RasterIOExtraArg() : this(GdalPINVOKE.new_RasterIOExtraArg(), true, null) {
+    if (GdalPINVOKE.SWIGPendingException.Pending) throw GdalPINVOKE.SWIGPendingException.Retrieve();
+  }
+
+}
+
+}
diff --git a/swig/csharp/gdal/SWIGTYPE_p_GDALProgressFunc.cs b/swig/csharp/gdal/SWIGTYPE_p_GDALProgressFunc.cs
new file mode 100644
index 0000000..f66e135
--- /dev/null
+++ b/swig/csharp/gdal/SWIGTYPE_p_GDALProgressFunc.cs
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.12
+ *
+ * Do not make changes to this file unless you know what you are doing--modify
+ * the SWIG interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+namespace OSGeo.GDAL {
+
+using System;
+using System.Runtime.InteropServices;
+
+public class SWIGTYPE_p_GDALProgressFunc {
+  private HandleRef swigCPtr;
+
+  public SWIGTYPE_p_GDALProgressFunc(IntPtr cPtr, bool futureUse, object parent) {
+    swigCPtr = new HandleRef(this, cPtr);
+  }
+
+  protected SWIGTYPE_p_GDALProgressFunc() {
+    swigCPtr = new HandleRef(null, IntPtr.Zero);
+  }
+
+  public static HandleRef getCPtr(SWIGTYPE_p_GDALProgressFunc obj) {
+    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
+  }
+}
+
+}
diff --git a/swig/csharp/gdal/gdal_wrap.cpp b/swig/csharp/gdal/gdal_wrap.cpp
index c63d63b..ced1da5 100644
--- a/swig/csharp/gdal/gdal_wrap.cpp
+++ b/swig/csharp/gdal/gdal_wrap.cpp
@@ -971,16 +971,26 @@ SWIGINTERN OGRErr GDALDatasetShadow_CommitTransaction(GDALDatasetShadow *self){
 SWIGINTERN OGRErr GDALDatasetShadow_RollbackTransaction(GDALDatasetShadow *self){
     return GDALDatasetRollbackTransaction(self);
   }
-SWIGINTERN CPLErr GDALDatasetShadow_ReadRaster(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace){
+SWIGINTERN CPLErr GDALDatasetShadow_ReadRaster__SWIG_0(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace){
        return GDALDatasetRasterIO( self, GF_Read, xOff, yOff, xSize, ySize,
 		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
 		        bandMap, pixelSpace, lineSpace, bandSpace);
     }
-SWIGINTERN CPLErr GDALDatasetShadow_WriteRaster(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace){
+SWIGINTERN CPLErr GDALDatasetShadow_WriteRaster__SWIG_0(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace){
        return GDALDatasetRasterIO( self, GF_Write, xOff, yOff, xSize, ySize,
 		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
 		        bandMap, pixelSpace, lineSpace, bandSpace);
     }
+SWIGINTERN CPLErr GDALDatasetShadow_ReadRaster__SWIG_1(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace,GDALRasterIOExtraArg *extraArg){
+       return GDALDatasetRasterIOEx( self, GF_Read, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
+		        bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+    }
+SWIGINTERN CPLErr GDALDatasetShadow_WriteRaster__SWIG_1(GDALDatasetShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int bandCount,int *bandMap,int pixelSpace,int lineSpace,int bandSpace,GDALRasterIOExtraArg *extraArg){
+       return GDALDatasetRasterIOEx( self, GF_Write, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
+		        bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+    }
 SWIGINTERN GDAL_GCP const *GDALDatasetShadow___GetGCPs(GDALDatasetShadow *self){
       return GDALGetGCPs( self );
     }
@@ -1216,14 +1226,22 @@ SWIGINTERN char **GDALRasterBandShadow_GetCategoryNames(GDALRasterBandShadow *se
 SWIGINTERN CPLErr GDALRasterBandShadow_SetCategoryNames(GDALRasterBandShadow *self,char **papszCategoryNames){
     return GDALSetRasterCategoryNames( self, papszCategoryNames );
   }
-SWIGINTERN CPLErr GDALRasterBandShadow_ReadRaster(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace){
+SWIGINTERN CPLErr GDALRasterBandShadow_ReadRaster__SWIG_0(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace){
        return GDALRasterIO( self, GF_Read, xOff, yOff, xSize, ySize,
 		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace );
     }
-SWIGINTERN CPLErr GDALRasterBandShadow_WriteRaster(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace){
+SWIGINTERN CPLErr GDALRasterBandShadow_WriteRaster__SWIG_0(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace){
        return GDALRasterIO( self, GF_Write, xOff, yOff, xSize, ySize,
 		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace );
     }
+SWIGINTERN CPLErr GDALRasterBandShadow_ReadRaster__SWIG_1(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace,GDALRasterIOExtraArg *extraArg){
+       return GDALRasterIOEx( self, GF_Read, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace, extraArg );
+    }
+SWIGINTERN CPLErr GDALRasterBandShadow_WriteRaster__SWIG_1(GDALRasterBandShadow *self,int xOff,int yOff,int xSize,int ySize,void *buffer,int buf_xSize,int buf_ySize,GDALDataType buf_type,int pixelSpace,int lineSpace,GDALRasterIOExtraArg *extraArg){
+       return GDALRasterIOEx( self, GF_Write, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace, extraArg );
+    }
 
 GDALDataType GDALRasterBandShadow_DataType_get( GDALRasterBandShadow *h ) {
   return GDALGetRasterDataType( h );
@@ -2253,6 +2271,264 @@ SWIGEXPORT void SWIGSTDCALL CSharp_StringListDestroy(void * jarg1) {
 }
 
 
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_nVersion_set(void * jarg1, int jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  int arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (int)jarg2; 
+  if (arg1) (arg1)->nVersion = arg2;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_RasterIOExtraArg_nVersion_get(void * jarg1) {
+  int jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  int result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (int) ((arg1)->nVersion);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_eResampleAlg_set(void * jarg1, int jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  GDALRIOResampleAlg arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (GDALRIOResampleAlg)jarg2; 
+  if (arg1) (arg1)->eResampleAlg = arg2;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_RasterIOExtraArg_eResampleAlg_get(void * jarg1) {
+  int jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  GDALRIOResampleAlg result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (GDALRIOResampleAlg) ((arg1)->eResampleAlg);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_pfnProgress_set(void * jarg1, void * jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  GDALProgressFunc arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (GDALProgressFunc)jarg2; 
+  if (arg1) (arg1)->pfnProgress = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_RasterIOExtraArg_pfnProgress_get(void * jarg1) {
+  void * jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  GDALProgressFunc result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result =  ((arg1)->pfnProgress);
+  jresult = new GDALProgressFunc((const GDALProgressFunc &)result); 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_pProgressData_set(void * jarg1, void * jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  void *arg2 = (void *) 0 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (void *)jarg2; 
+  if (arg1) (arg1)->pProgressData = arg2;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_RasterIOExtraArg_pProgressData_get(void * jarg1) {
+  void * jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  void *result = 0 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (void *) ((arg1)->pProgressData);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_bFloatingPointWindowValidity_set(void * jarg1, int jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  int arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (int)jarg2; 
+  if (arg1) (arg1)->bFloatingPointWindowValidity = arg2;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_RasterIOExtraArg_bFloatingPointWindowValidity_get(void * jarg1) {
+  int jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  int result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (int) ((arg1)->bFloatingPointWindowValidity);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_dfXOff_set(void * jarg1, double jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (double)jarg2; 
+  if (arg1) (arg1)->dfXOff = arg2;
+}
+
+
+SWIGEXPORT double SWIGSTDCALL CSharp_RasterIOExtraArg_dfXOff_get(void * jarg1) {
+  double jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (double) ((arg1)->dfXOff);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_dfYOff_set(void * jarg1, double jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (double)jarg2; 
+  if (arg1) (arg1)->dfYOff = arg2;
+}
+
+
+SWIGEXPORT double SWIGSTDCALL CSharp_RasterIOExtraArg_dfYOff_get(void * jarg1) {
+  double jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (double) ((arg1)->dfYOff);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_dfXSize_set(void * jarg1, double jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (double)jarg2; 
+  if (arg1) (arg1)->dfXSize = arg2;
+}
+
+
+SWIGEXPORT double SWIGSTDCALL CSharp_RasterIOExtraArg_dfXSize_get(void * jarg1) {
+  double jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (double) ((arg1)->dfXSize);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_RasterIOExtraArg_dfYSize_set(void * jarg1, double jarg2) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double arg2 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  arg2 = (double)jarg2; 
+  if (arg1) (arg1)->dfYSize = arg2;
+}
+
+
+SWIGEXPORT double SWIGSTDCALL CSharp_RasterIOExtraArg_dfYSize_get(void * jarg1) {
+  double jresult ;
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  double result;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  result = (double) ((arg1)->dfYSize);
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void * SWIGSTDCALL CSharp_new_RasterIOExtraArg() {
+  void * jresult ;
+  GDALRasterIOExtraArg *result = 0 ;
+  
+  {
+    CPLErrorReset();
+    result = (GDALRasterIOExtraArg *)new GDALRasterIOExtraArg();
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+  jresult = (void *)result; 
+  return jresult;
+}
+
+
+SWIGEXPORT void SWIGSTDCALL CSharp_delete_RasterIOExtraArg(void * jarg1) {
+  GDALRasterIOExtraArg *arg1 = (GDALRasterIOExtraArg *) 0 ;
+  
+  arg1 = (GDALRasterIOExtraArg *)jarg1; 
+  {
+    CPLErrorReset();
+    delete arg1;
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+}
+
+
 SWIGEXPORT void SWIGSTDCALL CSharp_Debug(char * jarg1, char * jarg2) {
   char *arg1 = (char *) 0 ;
   char *arg2 = (char *) 0 ;
@@ -7740,7 +8016,131 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_RollbackTransaction(void * jarg1) {
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14) {
+SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster__SWIG_0(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14) {
+  int jresult ;
+  GDALDatasetShadow *arg1 = (GDALDatasetShadow *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int arg5 ;
+  void *arg6 = (void *) 0 ;
+  int arg7 ;
+  int arg8 ;
+  GDALDataType arg9 ;
+  int arg10 ;
+  int *arg11 = (int *) 0 ;
+  int arg12 ;
+  int arg13 ;
+  int arg14 ;
+  CPLErr result;
+  
+  arg1 = (GDALDatasetShadow *)jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  arg4 = (int)jarg4; 
+  arg5 = (int)jarg5; 
+  arg6 = (void *)jarg6; 
+  arg7 = (int)jarg7; 
+  arg8 = (int)jarg8; 
+  arg9 = (GDALDataType)jarg9; 
+  arg10 = (int)jarg10; 
+  {
+    /* %typemap(in) (int argin[ANY]) */
+    arg11 = (int *)jarg11;
+  }
+  arg12 = (int)jarg12; 
+  arg13 = (int)jarg13; 
+  arg14 = (int)jarg14; 
+  {
+    CPLErrorReset();
+    result = (CPLErr)GDALDatasetShadow_ReadRaster__SWIG_0(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14);
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_WriteRaster__SWIG_0(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14) {
+  int jresult ;
+  GDALDatasetShadow *arg1 = (GDALDatasetShadow *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int arg5 ;
+  void *arg6 = (void *) 0 ;
+  int arg7 ;
+  int arg8 ;
+  GDALDataType arg9 ;
+  int arg10 ;
+  int *arg11 = (int *) 0 ;
+  int arg12 ;
+  int arg13 ;
+  int arg14 ;
+  CPLErr result;
+  
+  arg1 = (GDALDatasetShadow *)jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  arg4 = (int)jarg4; 
+  arg5 = (int)jarg5; 
+  arg6 = (void *)jarg6; 
+  arg7 = (int)jarg7; 
+  arg8 = (int)jarg8; 
+  arg9 = (GDALDataType)jarg9; 
+  arg10 = (int)jarg10; 
+  {
+    /* %typemap(in) (int argin[ANY]) */
+    arg11 = (int *)jarg11;
+  }
+  arg12 = (int)jarg12; 
+  arg13 = (int)jarg13; 
+  arg14 = (int)jarg14; 
+  {
+    CPLErrorReset();
+    result = (CPLErr)GDALDatasetShadow_WriteRaster__SWIG_0(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14);
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster__SWIG_1(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14, void * jarg15) {
   int jresult ;
   GDALDatasetShadow *arg1 = (GDALDatasetShadow *) 0 ;
   int arg2 ;
@@ -7756,6 +8156,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster(void * jarg1, int jarg2, in
   int arg12 ;
   int arg13 ;
   int arg14 ;
+  GDALRasterIOExtraArg *arg15 = (GDALRasterIOExtraArg *) 0 ;
   CPLErr result;
   
   arg1 = (GDALDatasetShadow *)jarg1; 
@@ -7775,9 +8176,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster(void * jarg1, int jarg2, in
   arg12 = (int)jarg12; 
   arg13 = (int)jarg13; 
   arg14 = (int)jarg14; 
+  arg15 = (GDALRasterIOExtraArg *)jarg15; 
   {
     CPLErrorReset();
-    result = (CPLErr)GDALDatasetShadow_ReadRaster(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14);
+    result = (CPLErr)GDALDatasetShadow_ReadRaster__SWIG_1(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15);
     CPLErr eclass = CPLGetLastErrorType();
     if ( eclass == CE_Failure || eclass == CE_Fatal ) {
       SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
@@ -7802,7 +8204,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_ReadRaster(void * jarg1, int jarg2, in
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_WriteRaster(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14) {
+SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_WriteRaster__SWIG_1(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, void * jarg11, int jarg12, int jarg13, int jarg14, void * jarg15) {
   int jresult ;
   GDALDatasetShadow *arg1 = (GDALDatasetShadow *) 0 ;
   int arg2 ;
@@ -7818,6 +8220,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_WriteRaster(void * jarg1, int jarg2, i
   int arg12 ;
   int arg13 ;
   int arg14 ;
+  GDALRasterIOExtraArg *arg15 = (GDALRasterIOExtraArg *) 0 ;
   CPLErr result;
   
   arg1 = (GDALDatasetShadow *)jarg1; 
@@ -7837,9 +8240,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Dataset_WriteRaster(void * jarg1, int jarg2, i
   arg12 = (int)jarg12; 
   arg13 = (int)jarg13; 
   arg14 = (int)jarg14; 
+  arg15 = (GDALRasterIOExtraArg *)jarg15; 
   {
     CPLErrorReset();
-    result = (CPLErr)GDALDatasetShadow_WriteRaster(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14);
+    result = (CPLErr)GDALDatasetShadow_WriteRaster__SWIG_1(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12,arg13,arg14,arg15);
     CPLErr eclass = CPLGetLastErrorType();
     if ( eclass == CE_Failure || eclass == CE_Fatal ) {
       SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
@@ -9848,7 +10252,113 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_SetCategoryNames(void * jarg1, void * jar
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11) {
+SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster__SWIG_0(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11) {
+  int jresult ;
+  GDALRasterBandShadow *arg1 = (GDALRasterBandShadow *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int arg5 ;
+  void *arg6 = (void *) 0 ;
+  int arg7 ;
+  int arg8 ;
+  GDALDataType arg9 ;
+  int arg10 ;
+  int arg11 ;
+  CPLErr result;
+  
+  arg1 = (GDALRasterBandShadow *)jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  arg4 = (int)jarg4; 
+  arg5 = (int)jarg5; 
+  arg6 = (void *)jarg6; 
+  arg7 = (int)jarg7; 
+  arg8 = (int)jarg8; 
+  arg9 = (GDALDataType)jarg9; 
+  arg10 = (int)jarg10; 
+  arg11 = (int)jarg11; 
+  {
+    CPLErrorReset();
+    result = (CPLErr)GDALRasterBandShadow_ReadRaster__SWIG_0(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Band_WriteRaster__SWIG_0(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11) {
+  int jresult ;
+  GDALRasterBandShadow *arg1 = (GDALRasterBandShadow *) 0 ;
+  int arg2 ;
+  int arg3 ;
+  int arg4 ;
+  int arg5 ;
+  void *arg6 = (void *) 0 ;
+  int arg7 ;
+  int arg8 ;
+  GDALDataType arg9 ;
+  int arg10 ;
+  int arg11 ;
+  CPLErr result;
+  
+  arg1 = (GDALRasterBandShadow *)jarg1; 
+  arg2 = (int)jarg2; 
+  arg3 = (int)jarg3; 
+  arg4 = (int)jarg4; 
+  arg5 = (int)jarg5; 
+  arg6 = (void *)jarg6; 
+  arg7 = (int)jarg7; 
+  arg8 = (int)jarg8; 
+  arg9 = (GDALDataType)jarg9; 
+  arg10 = (int)jarg10; 
+  arg11 = (int)jarg11; 
+  {
+    CPLErrorReset();
+    result = (CPLErr)GDALRasterBandShadow_WriteRaster__SWIG_0(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
+    CPLErr eclass = CPLGetLastErrorType();
+    if ( eclass == CE_Failure || eclass == CE_Fatal ) {
+      SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
+      
+      
+      
+    }
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  }
+  jresult = result; 
+  return jresult;
+}
+
+
+SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster__SWIG_1(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11, void * jarg12) {
   int jresult ;
   GDALRasterBandShadow *arg1 = (GDALRasterBandShadow *) 0 ;
   int arg2 ;
@@ -9861,6 +10371,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster(void * jarg1, int jarg2, int j
   GDALDataType arg9 ;
   int arg10 ;
   int arg11 ;
+  GDALRasterIOExtraArg *arg12 = (GDALRasterIOExtraArg *) 0 ;
   CPLErr result;
   
   arg1 = (GDALRasterBandShadow *)jarg1; 
@@ -9874,9 +10385,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster(void * jarg1, int jarg2, int j
   arg9 = (GDALDataType)jarg9; 
   arg10 = (int)jarg10; 
   arg11 = (int)jarg11; 
+  arg12 = (GDALRasterIOExtraArg *)jarg12; 
   {
     CPLErrorReset();
-    result = (CPLErr)GDALRasterBandShadow_ReadRaster(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
+    result = (CPLErr)GDALRasterBandShadow_ReadRaster__SWIG_1(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
     CPLErr eclass = CPLGetLastErrorType();
     if ( eclass == CE_Failure || eclass == CE_Fatal ) {
       SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
@@ -9901,7 +10413,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_ReadRaster(void * jarg1, int jarg2, int j
 }
 
 
-SWIGEXPORT int SWIGSTDCALL CSharp_Band_WriteRaster(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11) {
+SWIGEXPORT int SWIGSTDCALL CSharp_Band_WriteRaster__SWIG_1(void * jarg1, int jarg2, int jarg3, int jarg4, int jarg5, void * jarg6, int jarg7, int jarg8, int jarg9, int jarg10, int jarg11, void * jarg12) {
   int jresult ;
   GDALRasterBandShadow *arg1 = (GDALRasterBandShadow *) 0 ;
   int arg2 ;
@@ -9914,6 +10426,7 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_WriteRaster(void * jarg1, int jarg2, int
   GDALDataType arg9 ;
   int arg10 ;
   int arg11 ;
+  GDALRasterIOExtraArg *arg12 = (GDALRasterIOExtraArg *) 0 ;
   CPLErr result;
   
   arg1 = (GDALRasterBandShadow *)jarg1; 
@@ -9927,9 +10440,10 @@ SWIGEXPORT int SWIGSTDCALL CSharp_Band_WriteRaster(void * jarg1, int jarg2, int
   arg9 = (GDALDataType)jarg9; 
   arg10 = (int)jarg10; 
   arg11 = (int)jarg11; 
+  arg12 = (GDALRasterIOExtraArg *)jarg12; 
   {
     CPLErrorReset();
-    result = (CPLErr)GDALRasterBandShadow_WriteRaster(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11);
+    result = (CPLErr)GDALRasterBandShadow_WriteRaster__SWIG_1(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11,arg12);
     CPLErr eclass = CPLGetLastErrorType();
     if ( eclass == CE_Failure || eclass == CE_Fatal ) {
       SWIG_CSharpException(SWIG_RuntimeError, CPLGetLastErrorMsg());
diff --git a/swig/csharp/makefile.vc b/swig/csharp/makefile.vc
index 3a6b773..51786ca 100644
--- a/swig/csharp/makefile.vc
+++ b/swig/csharp/makefile.vc
@@ -8,7 +8,7 @@
 #  - Run the VCVARS32.BAT script to initialize the VC++ environment variables
 #  - Start the build with:  nmake /f makefile.vc
 #
-# $Id: makefile.vc 28983 2015-04-23 21:46:56Z tamas $
+# $Id: makefile.vc 39863 2017-08-18 20:27:45Z tamas $
 #
 
 GDAL_ROOT	=	..\..
@@ -119,6 +119,7 @@ samples:
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /r:System.Drawing.dll /out:GDALReadDirect.exe apps\GDALReadDirect.cs
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /r:System.Drawing.dll /out:GDALAdjustContrast.exe apps\GDALAdjustContrast.cs
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /r:System.Drawing.dll /out:GDALDatasetRasterIO.exe apps\GDALDatasetRasterIO.cs
+    $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /r:System.Drawing.dll /out:GDALDatasetRasterIOEx.exe apps\GDALDatasetRasterIOEx.cs
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /out:GDALWrite.exe apps\GDALWrite.cs
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /out:GDALDatasetWrite.exe apps\GDALDatasetWrite.cs
     $(CSC) $(CSDEBUG) /r:gdal_csharp.dll /out:GDALColorTable.exe apps\GDALColorTable.cs
diff --git a/swig/include/csharp/gdal_csharp.i b/swig/include/csharp/gdal_csharp.i
index a19ac07..bc91bad 100644
--- a/swig/include/csharp/gdal_csharp.i
+++ b/swig/include/csharp/gdal_csharp.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal_csharp.i 34525 2016-07-03 02:53:47Z goatbar $
+ * $Id: gdal_csharp.i 39863 2017-08-18 20:27:45Z tamas $
  *
  * Name:     gdal_csharp.i
  * Project:  GDAL CSharp Interface
@@ -47,6 +47,38 @@
 %csmethodmodifiers __GetGCPs "private";
 %csmethodmodifiers GDALGCPsToGeoTransform "private";
 
+%apply (GDALProgressFunc callback) {GDALProgressFunc pfnProgress};
+%apply (void *buffer_ptr) {void *pProgressData};
+
+%rename (RasterIOExtraArg) GDALRasterIOExtraArg;
+typedef struct
+{
+    /*! Version of structure (to allow future extensions of the structure) */
+    int                    nVersion;
+
+    /*! Resampling algorithm */
+    GDALRIOResampleAlg     eResampleAlg;
+
+    /*! Progress callback */
+    GDALProgressFunc pfnProgress;
+    /*! Progress callback user data */
+    void *pProgressData;
+
+    /*! Indicate if dfXOff, dfYOff, dfXSize and dfYSize are set.
+        Mostly reserved from the VRT driver to communicate a more precise
+        source window. Must be such that dfXOff - nXOff < 1.0 and
+        dfYOff - nYOff < 1.0 and nXSize - dfXSize < 1.0 and nYSize - dfYSize < 1.0 */
+    int bFloatingPointWindowValidity;
+    /*! Pixel offset to the top left corner. Only valid if bFloatingPointWindowValidity = TRUE */
+    double dfXOff;
+    /*! Line offset to the top left corner. Only valid if bFloatingPointWindowValidity = TRUE */
+    double dfYOff;
+    /*! Width in pixels of the area of interest. Only valid if bFloatingPointWindowValidity = TRUE */
+    double dfXSize;
+    /*! Height in pixels of the area of interest. Only valid if bFloatingPointWindowValidity = TRUE */
+    double dfYSize;
+} GDALRasterIOExtraArg;
+
 DEFINE_EXTERNAL_CLASS(OGRLayerShadow, OSGeo.OGR.Layer)
 
 %define %rasterio_functions(GDALTYPE,CSTYPE)
@@ -72,6 +104,28 @@ DEFINE_EXTERNAL_CLASS(OGRLayerShadow, OSGeo.OGR.Layer)
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, CSTYPE[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, GDALTYPE, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, CSTYPE[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, GDALTYPE, pixelSpace, lineSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 %enddef
 
@@ -117,6 +171,32 @@ DEFINE_EXTERNAL_CLASS(OGRLayerShadow, OSGeo.OGR.Layer)
       GC.KeepAlive(this);
       return retval;
   }
+  public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, CSTYPE[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = ReadRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, GDALTYPE,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
+  public CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, CSTYPE[] buffer, int buf_xSize, int buf_ySize,
+     int bandCount, int[] bandMap, int pixelSpace, int lineSpace, int bandSpace, RasterIOExtraArg extraArg) {
+      CPLErr retval;
+      GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+      try {
+          retval = WriteRaster(xOff, yOff, xSize, ySize, handle.AddrOfPinnedObject(), buf_xSize, buf_ySize, GDALTYPE,
+                               bandCount, bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+      } finally {
+          handle.Free();
+      }
+      GC.KeepAlive(this);
+      return retval;
+  }
 
 %enddef
 
diff --git a/swig/include/csharp/gdal_csharp_extend.i b/swig/include/csharp/gdal_csharp_extend.i
index d0ce051..53d42c9 100644
--- a/swig/include/csharp/gdal_csharp_extend.i
+++ b/swig/include/csharp/gdal_csharp_extend.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal_csharp_extend.i 34525 2016-07-03 02:53:47Z goatbar $
+ * $Id: gdal_csharp_extend.i 39863 2017-08-18 20:27:45Z tamas $
  *
  * Name:     gdal_csharp_extend.i
  * Project:  GDAL CSharp Interface
@@ -48,6 +48,18 @@
        return GDALRasterIO( self, GF_Write, xOff, yOff, xSize, ySize,
 		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace );
     }
+	CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, void* buffer,
+                          int buf_xSize, int buf_ySize, GDALDataType buf_type,
+                          int pixelSpace, int lineSpace, GDALRasterIOExtraArg* extraArg) {
+       return GDALRasterIOEx( self, GF_Read, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace, extraArg );
+    }
+    CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, void* buffer,
+                          int buf_xSize, int buf_ySize, GDALDataType buf_type,
+                          int pixelSpace, int lineSpace, GDALRasterIOExtraArg* extraArg) {
+       return GDALRasterIOEx( self, GF_Write, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, pixelSpace, lineSpace, extraArg );
+    }
     %clear void *buffer;
 }
 
@@ -69,6 +81,22 @@
 		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
 		        bandMap, pixelSpace, lineSpace, bandSpace);
     }
+	CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, void* buffer,
+                          int buf_xSize, int buf_ySize, GDALDataType buf_type,
+                          int bandCount, int* bandMap, int pixelSpace, int lineSpace, int bandSpace,
+						  GDALRasterIOExtraArg* extraArg) {
+       return GDALDatasetRasterIOEx( self, GF_Read, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
+		        bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+    }
+    CPLErr WriteRaster(int xOff, int yOff, int xSize, int ySize, void* buffer,
+                          int buf_xSize, int buf_ySize, GDALDataType buf_type,
+                          int bandCount, int* bandMap, int pixelSpace, int lineSpace, int bandSpace,
+						  GDALRasterIOExtraArg* extraArg) {
+       return GDALDatasetRasterIOEx( self, GF_Write, xOff, yOff, xSize, ySize,
+		        buffer, buf_xSize, buf_ySize, buf_type, bandCount,
+		        bandMap, pixelSpace, lineSpace, bandSpace, extraArg);
+    }
     %clear void *buffer;
     %clear int* bandMap;
 
diff --git a/swig/include/csharp/typemaps_csharp.i b/swig/include/csharp/typemaps_csharp.i
index dd603bd..8cb4a83 100644
--- a/swig/include/csharp/typemaps_csharp.i
+++ b/swig/include/csharp/typemaps_csharp.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: typemaps_csharp.i 34525 2016-07-03 02:53:47Z goatbar $
+ * $Id: typemaps_csharp.i 39863 2017-08-18 20:27:45Z tamas $
  *
  * Name:     typemaps_csharp.i
  * Project:  GDAL CSharp Interface
@@ -519,6 +519,11 @@ OPTIONAL_POD(int, int);
       IntPtr ret = $imcall;$excode
       return ret;
 }
+%typemap(csvarout, excode=SWIGEXCODE2) (void *buffer_ptr)   %{
+    get {
+      IntPtr ret = $imcall;$excode
+      return ret;
+    } %}
 
 %apply (void *buffer_ptr) {GByte*, VSILFILE*};
 
@@ -546,6 +551,11 @@ OPTIONAL_POD(int, int);
 %typemap(imtype) (GDALProgressFunc callback)  "$module.GDALProgressFuncDelegate"
 %typemap(cstype) (GDALProgressFunc callback) "$module.GDALProgressFuncDelegate"
 %typemap(csin) (GDALProgressFunc callback)  "$csinput"
+%typemap(csvarout, excode=SWIGEXCODE2) (GDALProgressFunc callback)   %{
+    get {
+      Gdal.GDALProgressFuncDelegate ret = $imcall;$excode
+      return ret;
+    } %}
 %typemap(in) (GDALProgressFunc callback) %{ $1 = ($1_ltype)$input; %}
 %typemap(imtype) (void* callback_data) "string"
 %typemap(cstype) (void* callback_data) "string"
diff --git a/swig/include/gdal_array.i b/swig/include/gdal_array.i
index 3565f9c..1bf8caa 100644
--- a/swig/include/gdal_array.i
+++ b/swig/include/gdal_array.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: gdal_array.i 37276 2017-02-02 14:56:32Z rouault $
+ * $Id: gdal_array.i 39834 2017-08-16 12:20:23Z rouault $
  *
  * Name:     gdal_array.i
  * Project:  GDAL Python Interface
@@ -138,7 +138,7 @@ static void GDALRegister_NUMPY(void)
         return;
     if( GDALGetDriverByName( "NUMPY" ) == NULL )
     {
-        poDriver = new GDALDriver();
+        poDriver = static_cast<GDALDriver*>(GDALCreateDriver());
 
         poDriver->SetDescription( "NUMPY" );
         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
diff --git a/swig/include/perl/gdal_perl.i b/swig/include/perl/gdal_perl.i
index 8873f93..f87bced 100644
--- a/swig/include/perl/gdal_perl.i
+++ b/swig/include/perl/gdal_perl.i
@@ -143,8 +143,8 @@ use Geo::GDAL::Const;
 # Note that the 1/100000 digits may be used to create more than one
 # CPAN release from one GDAL release.
 
-our $VERSION = '2.0201';
-our $GDAL_VERSION = '2.2.1';
+our $VERSION = '2.0202';
+our $GDAL_VERSION = '2.2.2';
 
 =pod
 
diff --git a/swig/include/perl/ogr_perl.i b/swig/include/perl/ogr_perl.i
index 2b10317..69a11fb 100644
--- a/swig/include/perl/ogr_perl.i
+++ b/swig/include/perl/ogr_perl.i
@@ -126,7 +126,7 @@ ALTERED_DESTROY(OGRGeometryShadow, OGRc, delete_Geometry)
 %perlcode %{
 
 package Geo::OGR;
-our $VERSION = '2.0201'; # this needs to be the same as that in gdal_perl.i
+our $VERSION = '2.0202'; # this needs to be the same as that in gdal_perl.i
 
 Geo::GDAL->import(qw(:INTERNAL));
 
diff --git a/swig/include/python/typemaps_python.i b/swig/include/python/typemaps_python.i
index 4b76f64..99bd89d 100644
--- a/swig/include/python/typemaps_python.i
+++ b/swig/include/python/typemaps_python.i
@@ -1,5 +1,5 @@
 /******************************************************************************
- * $Id: typemaps_python.i 38771 2017-06-01 11:24:27Z rouault $
+ * $Id: typemaps_python.i 39332 2017-06-27 15:21:21Z rouault $
  *
  * Name:     typemaps_python.i
  * Project:  GDAL Python Interface
@@ -1840,7 +1840,10 @@ DecomposeSequenceOfCoordinates( PyObject *seq, int nCount, double *x, double *y,
   if (result == 0)
     $result = SWIG_NewPointerObj((void*)new_StatBuf( $1 ),SWIGTYPE_p_StatBuf,1);
   else
+  {
     $result = Py_None;
+    Py_INCREF($result);
+  }
 }
 
 %typemap(in,numinputs=0) (void** pptr, size_t* pnsize, GDALDataType* pdatatype, int* preadonly) (void* ptr, size_t nsize, GDALDataType datatype, int readonly)
diff --git a/swig/perl/lib/Geo/GDAL.pm b/swig/perl/lib/Geo/GDAL.pm
index 1110af6..0c116bf 100644
--- a/swig/perl/lib/Geo/GDAL.pm
+++ b/swig/perl/lib/Geo/GDAL.pm
@@ -1056,8 +1056,8 @@ use Geo::GDAL::Const;
 # Note that the 1/100000 digits may be used to create more than one
 # CPAN release from one GDAL release.
 
-our $VERSION = '2.0201';
-our $GDAL_VERSION = '2.2.1';
+our $VERSION = '2.0202';
+our $GDAL_VERSION = '2.2.2';
 
 =pod
 
diff --git a/swig/perl/lib/Geo/OGR.pm b/swig/perl/lib/Geo/OGR.pm
index b0c200c..2852978 100644
--- a/swig/perl/lib/Geo/OGR.pm
+++ b/swig/perl/lib/Geo/OGR.pm
@@ -960,7 +960,7 @@ package Geo::OGR;
 
 
 package Geo::OGR;
-our $VERSION = '2.0201'; # this needs to be the same as that in gdal_perl.i
+our $VERSION = '2.0202'; # this needs to be the same as that in gdal_perl.i
 
 Geo::GDAL->import(qw(:INTERNAL));
 
diff --git a/swig/python/README.txt b/swig/python/README.txt
index 2b077e8..169f0a4 100644
--- a/swig/python/README.txt
+++ b/swig/python/README.txt
@@ -16,7 +16,7 @@ reference documentation, but the `GDAL API Tutorial`_ includes Python examples.
 Dependencies
 ------------
  
- * libgdal (2.2.0 or greater) and header files (gdal-devel)
+ * libgdal (2.2.2 or greater) and header files (gdal-devel)
  * numpy (1.0.0 or greater) and header files (numpy-devel) (not explicitly 
    required, but many examples and utilities will not work without it)
 
diff --git a/swig/python/extensions/gdal_array_wrap.cpp b/swig/python/extensions/gdal_array_wrap.cpp
index 005b5a2..d0c2474 100644
--- a/swig/python/extensions/gdal_array_wrap.cpp
+++ b/swig/python/extensions/gdal_array_wrap.cpp
@@ -3525,7 +3525,7 @@ static void GDALRegister_NUMPY(void)
         return;
     if( GDALGetDriverByName( "NUMPY" ) == NULL )
     {
-        poDriver = new GDALDriver();
+        poDriver = static_cast<GDALDriver*>(GDALCreateDriver());
 
         poDriver->SetDescription( "NUMPY" );
         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME,
diff --git a/swig/python/extensions/gdal_wrap.cpp b/swig/python/extensions/gdal_wrap.cpp
index ffcfe51..ee022d1 100644
--- a/swig/python/extensions/gdal_wrap.cpp
+++ b/swig/python/extensions/gdal_wrap.cpp
@@ -8644,7 +8644,10 @@ SWIGINTERN PyObject *_wrap_VSIStatL(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
     if (result == 0)
     resultobj = SWIG_NewPointerObj((void*)new_StatBuf( arg2 ),SWIGTYPE_p_StatBuf,1);
     else
-    resultobj = Py_None;
+    {
+      resultobj = Py_None;
+      Py_INCREF(resultobj);
+    }
   }
   {
     /* %typemap(freearg) (const char *utf8_path) */
diff --git a/swig/python/scripts/gdal2tiles.py b/swig/python/scripts/gdal2tiles.py
index 5c67ad6..9b795d0 100755
--- a/swig/python/scripts/gdal2tiles.py
+++ b/swig/python/scripts/gdal2tiles.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # ******************************************************************************
-#  $Id: gdal2tiles.py 37426 2017-02-19 21:47:49Z rouault $
+#  $Id: gdal2tiles.py 39836 2017-08-16 12:51:57Z rouault $
 #
 # Project:  Google Summer of Code 2007, 2008 (http://code.google.com/soc/)
 # Support:  BRGM (http://www.brgm.fr)
@@ -52,7 +52,7 @@ except Exception:
     # 'antialias' resampling is not available
     pass
 
-__version__ = "$Id: gdal2tiles.py 37426 2017-02-19 21:47:49Z rouault $"
+__version__ = "$Id: gdal2tiles.py 39836 2017-08-16 12:51:57Z rouault $"
 
 resampling_list = ('average', 'near', 'bilinear', 'cubic', 'cubicspline', 'lanczos',  'antialias')
 profile_list = ('mercator', 'geodetic', 'raster')
@@ -1201,6 +1201,7 @@ class GDAL2Tiles(object):
                     f.close()
 
         # Generate tilemapresource.xml.
+        if not self.options.resume or not os.path.exists(os.path.join(self.output, 'tilemapresource.xml')):
             f = open(os.path.join(self.output, 'tilemapresource.xml'), 'wb')
             f.write(self.generate_tilemapresource().encode('utf-8'))
             f.close()
diff --git a/swig/python/setup.py b/swig/python/setup.py
index 8ac2f8e..6fac6f9 100644
--- a/swig/python/setup.py
+++ b/swig/python/setup.py
@@ -7,7 +7,7 @@
 # Howard Butler hobu.inc at gmail.com
 
 
-gdal_version = '2.2.1'
+gdal_version = '2.2.2'
 
 import sys
 import os

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



More information about the Pkg-grass-devel mailing list