From efdca26f2d058ee362cfab24789d1ddddac935a7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 5 Feb 2015 20:38:27 +0100 Subject: [PATCH] gdal.input: optimize nodata handling in RGB case When the data type is Byte, instead of reading a first time the red band to deduce the value of the alpha component of the output image, read the RGB bands first. --- plugins/input/gdal/gdal_featureset.cpp | 29 +++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 0c1624c95..6981f40bd 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -309,7 +309,10 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) raster_nodata = red->GetNoDataValue(&raster_has_nodata); GDALColorTable *color_table = red->GetColorTable(); bool has_nodata = nodata_value_ || raster_has_nodata; - if (has_nodata && !color_table) + + // we can deduce the alpha channel from nodata in the Byte case + // by reusing the reading of R,G,B bands directly + if (has_nodata && !color_table && red->GetRasterDataType() != GDT_Byte) { double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; // read the data in and create an alpha channel from the nodata values @@ -372,10 +375,26 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) throw datasource_exception(CPLGetLastErrorMsg()); } } - raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2, - image.width(), image.height(), GDT_Byte, 4, 4 * image.width()); - if (raster_io_error == CE_Failure) { - throw datasource_exception(CPLGetLastErrorMsg()); + + // In the case we skipped initializing the alpha channel + if (has_nodata && !color_table && red->GetRasterDataType() == GDT_Byte) + { + double apply_nodata = nodata_value_ ? *nodata_value_ : raster_nodata; + if( apply_nodata >= 0 && apply_nodata <= 255 ) + { + int len = image.width() * image.height(); + GByte bNoData = (GByte)(apply_nodata + 0.5); + GByte* pabyBytes = (GByte*) image.getBytes(); + for (int i = 0; i < len; ++i) + { + // TODO - we assume here the nodata value for the red band applies to all bands + // more details about this at http://trac.osgeo.org/gdal/ticket/2734 + if( pabyBytes[4*i] == bNoData ) + pabyBytes[4*i + 3] = 0; + else + pabyBytes[4*i + 3] = 255; + } + } } } else if (grey)