Skip to content

Commit

Permalink
Use exc_wrap_int on io_* function return vals (#1619)
Browse files Browse the repository at this point in the history
To get at the GDAL error stack
  • Loading branch information
sgillies authored Feb 5, 2019
1 parent 6643327 commit 72ccea6
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 74 deletions.
112 changes: 63 additions & 49 deletions rasterio/_io.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,20 @@ cdef int io_auto(data, GDALRasterBandH band, bint write, int resampling=0) excep
cdef float height = data.shape[-2]
cdef float width = data.shape[-1]

if ndims == 2:
return io_band(band, write, 0.0, 0.0, width, height, data,
resampling=resampling)
elif ndims == 3:
indexes = np.arange(1, data.shape[0] + 1, dtype='intp')
return io_multi_band(band, write, 0.0, 0.0, width, height, data,
indexes, resampling=resampling)
else:
raise ValueError("Specified data must have 2 or 3 dimensions")
try:

if ndims == 2:
return io_band(band, write, 0.0, 0.0, width, height, data, resampling=resampling)

elif ndims == 3:
indexes = np.arange(1, data.shape[0] + 1, dtype='intp')
return io_multi_band(band, write, 0.0, 0.0, width, height, data, indexes, resampling=resampling)

else:
raise ValueError("Specified data must have 2 or 3 dimensions")

except CPLE_BaseError as cplerr:
raise RasterioIOError(str(cplerr))


cdef class DatasetReaderBase(DatasetBase):
Expand Down Expand Up @@ -673,25 +678,22 @@ cdef class DatasetReaderBase(DatasetBase):
indexes_arr = np.array(indexes, dtype='intp')
indexes_count = <int>indexes_arr.shape[0]

if masks:
# Warn if nodata attribute is shadowing an alpha band.
if self.count == 4 and self.colorinterp[3] == ColorInterp.alpha:
for flags in self.mask_flag_enums:
if MaskFlags.nodata in flags:
warnings.warn(NodataShadowWarning())
try:

if masks:
# Warn if nodata attribute is shadowing an alpha band.
if self.count == 4 and self.colorinterp[3] == ColorInterp.alpha:
for flags in self.mask_flag_enums:
if MaskFlags.nodata in flags:
warnings.warn(NodataShadowWarning())

retval = io_multi_mask(
self._hds, 0, xoff, yoff, width, height,
out, indexes_arr, resampling=resampling)
io_multi_mask(self._hds, 0, xoff, yoff, width, height, out, indexes_arr, resampling=resampling)

else:
retval = io_multi_band(self._hds, 0, xoff, yoff, width, height,
out, indexes_arr, resampling=resampling)
else:
io_multi_band(self._hds, 0, xoff, yoff, width, height, out, indexes_arr, resampling=resampling)

if retval in (1, 2, 3):
raise IOError("Read or write failed")
elif retval == 4:
raise ValueError("NULL band")
except CPLE_BaseError as cplerr:
raise RasterioIOError("Read or write failed. {}".format(cplerr))

return out

Expand Down Expand Up @@ -1354,13 +1356,11 @@ cdef class DatasetWriterBase(DatasetReaderBase):

indexes_arr = np.array(indexes, dtype='intp')
indexes_count = <int>indexes_arr.shape[0]
retval = io_multi_band(self._hds, 1, xoff, yoff, width, height,
src, indexes_arr)

if retval in (1, 2, 3):
raise IOError("Read or write failed")
elif retval == 4:
raise ValueError("NULL band")
try:
io_multi_band(self._hds, 1, xoff, yoff, width, height, src, indexes_arr)
except CPLE_BaseError as cplerr:
raise RasterioIOError("Read or write failed. {}".format(cplerr))

def write_band(self, bidx, src, window=None):
"""Write the src array into the `bidx` band.
Expand Down Expand Up @@ -1540,15 +1540,19 @@ cdef class DatasetWriterBase(DatasetReaderBase):
width = self.width
height = self.height

if mask_array is True:
GDALFillRaster(mask, 255, 0)
elif mask_array is False:
GDALFillRaster(mask, 0, 0)
elif mask_array.dtype == np.bool:
array = 255 * mask_array.astype(np.uint8)
retval = io_band(mask, 1, xoff, yoff, width, height, array)
else:
retval = io_band(mask, 1, xoff, yoff, width, height, mask_array)
try:
if mask_array is True:
GDALFillRaster(mask, 255, 0)
elif mask_array is False:
GDALFillRaster(mask, 0, 0)
elif mask_array.dtype == np.bool:
array = 255 * mask_array.astype(np.uint8)
io_band(mask, 1, xoff, yoff, width, height, array)
else:
io_band(mask, 1, xoff, yoff, width, height, mask_array)

except CPLE_BaseError as cplerr:
raise RasterioIOError("Read or write failed. {}".format(cplerr))

def build_overviews(self, factors, resampling=Resampling.nearest):
"""Build overviews at one or more decimation factors for all
Expand Down Expand Up @@ -1782,22 +1786,32 @@ cdef class InMemoryRaster:
self._hds = NULL

def read(self):

if self._image is None:
raise IOError("You need to write data before you can read the data.")
raise RasterioIOError("You need to write data before you can read the data.")

try:
if self._image.ndim == 2:
io_auto(self._image, self.band(1), False)
else:
io_auto(self._image, self._hds, False)

except CPLE_BaseError as cplerr:
raise RasterioIOError("Read or write failed. {}".format(cplerr))

if self._image.ndim == 2:
exc_wrap_int(io_auto(self._image, self.band(1), False))
else:
exc_wrap_int(io_auto(self._image, self._hds, False))
return self._image

def write(self, np.ndarray image):
self._image = image
if image.ndim == 2:
exc_wrap_int(io_auto(self._image, self.band(1), True))
else:
exc_wrap_int(io_auto(self._image, self._hds, True))

try:
if image.ndim == 2:
io_auto(self._image, self.band(1), True)
else:
io_auto(self._image, self._hds, True)

except CPLE_BaseError as cplerr:
raise RasterioIOError("Read or write failed. {}".format(cplerr))


cdef class BufferedDatasetWriterBase(DatasetWriterBase):
Expand Down
30 changes: 17 additions & 13 deletions rasterio/_shim1.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ from rasterio import dtypes
from rasterio.enums import Resampling

cimport numpy as np
from rasterio._err cimport exc_wrap_pointer
from rasterio._err cimport exc_wrap_int, exc_wrap_pointer

from rasterio.errors import GDALOptionNotImplementedError

Expand Down Expand Up @@ -88,7 +88,7 @@ cdef int io_band(
band, mode, xoff, yoff, xsize, ysize, buf, bufxsize, bufysize,
buftype, bufpixelspace, buflinespace)

return retval
return exc_wrap_int(retval)


cdef int io_multi_band(
Expand Down Expand Up @@ -121,17 +121,21 @@ cdef int io_multi_band(
cdef int xsize = <int>width
cdef int ysize = <int>height

with nogil:
bandmap = <int *>CPLMalloc(count*sizeof(int))
for i in range(count):
bandmap[i] = <int>indexes[i]
retval = GDALDatasetRasterIO(
hds, mode, xoff, yoff, xsize, ysize, buf,
bufxsize, bufysize, buftype, count, bandmap,
bufpixelspace, buflinespace, bufbandspace)
CPLFree(bandmap)
bandmap = <int *>CPLMalloc(count*sizeof(int))
for i in range(count):
bandmap[i] = <int>indexes[i]

return retval
try:
with nogil:
retval = GDALDatasetRasterIO(
hds, mode, xoff, yoff, xsize, ysize, buf,
bufxsize, bufysize, buftype, count, bandmap,
bufpixelspace, buflinespace, bufbandspace)

return exc_wrap_int(retval)

finally:
CPLFree(bandmap)


cdef int io_multi_mask(
Expand Down Expand Up @@ -183,4 +187,4 @@ cdef int io_multi_mask(
if retval:
break

return retval
return exc_wrap_int(retval)
31 changes: 19 additions & 12 deletions rasterio/shim_rasterioex.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ from rasterio.enums import Resampling

cimport numpy as np

from rasterio._err cimport exc_wrap_int


cdef extern from "cpl_progress.h":

Expand Down Expand Up @@ -73,7 +75,7 @@ cdef int io_band(GDALRasterBandH band, int mode, float x0, float y0,
band, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf, bufxsize, bufysize,
buftype, bufpixelspace, buflinespace, &extras)

return retval
return exc_wrap_int(retval)


cdef int io_multi_band(GDALDatasetH hds, int mode, float x0, float y0,
Expand Down Expand Up @@ -117,17 +119,21 @@ cdef int io_multi_band(GDALDatasetH hds, int mode, float x0, float y0,
extras.pfnProgress = NULL
extras.pProgressData = NULL

with nogil:
bandmap = <int *>CPLMalloc(count*sizeof(int))
for i in range(count):
bandmap[i] = <int>indexes[i]
retval = GDALDatasetRasterIOEx(
hds, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf,
bufxsize, bufysize, buftype, count, bandmap,
bufpixelspace, buflinespace, bufbandspace, &extras)
CPLFree(bandmap)
bandmap = <int *>CPLMalloc(count*sizeof(int))
for i in range(count):
bandmap[i] = <int>indexes[i]

return retval
try:
with nogil:
retval = GDALDatasetRasterIOEx(
hds, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf,
bufxsize, bufysize, buftype, count, bandmap,
bufpixelspace, buflinespace, bufbandspace, &extras)

return exc_wrap_int(retval)

finally:
CPLFree(bandmap)


cdef int io_multi_mask(GDALDatasetH hds, int mode, float x0, float y0,
Expand Down Expand Up @@ -187,7 +193,8 @@ cdef int io_multi_mask(GDALDatasetH hds, int mode, float x0, float y0,
retval = GDALRasterIOEx(
hmask, <GDALRWFlag>mode, xoff, yoff, xsize, ysize, buf, bufxsize,
bufysize, <GDALDataType>1, bufpixelspace, buflinespace, &extras)

if retval:
break

return retval
return exc_wrap_int(retval)

0 comments on commit 72ccea6

Please sign in to comment.