#!/usr/bin/env pytest # -*- coding: utf-8 -*- ############################################################################### # $Id$ # # Project: GDAL/OGR Test Suite # Purpose: Test GDAL functions not bound SWIG with ctypes # Author: Even Rouault, # ############################################################################### # Copyright (c) 2011-2012, Even Rouault # # 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. ############################################################################### import ctypes import gdaltest import pytest from osgeo import gdal gdal_handle_init = False gdal_handle = None gdal_handle_stdcall = None ############################################################################### # find_libgdal() def find_libgdal(): return gdaltest.find_lib("gdal") ############################################################################### # Init @pytest.fixture(scope="module", autouse=True) def setup(): global gdal_handle_init, gdal_handle, gdal_handle_stdcall if gdal_handle_init: if gdal_handle is None: pytest.skip() return gdal_handle gdal_handle_init = True name = find_libgdal() if name is None: pytest.skip() print("Found libgdal we are running against : %s" % name) static_version = gdal.VersionInfo(None) # short_static_version = static_version[0:2] try: gdal_handle = ctypes.cdll.LoadLibrary(name) try: gdal_handle_stdcall = ctypes.windll.LoadLibrary(name) except Exception: gdal_handle_stdcall = gdal_handle gdal_handle_stdcall.GDALVersionInfo.argtypes = [ctypes.c_char_p] gdal_handle_stdcall.GDALVersionInfo.restype = ctypes.c_char_p dynamic_version = gdal_handle_stdcall.GDALVersionInfo(None) dynamic_version = dynamic_version.decode("utf-8") if dynamic_version != static_version: gdal_handle = None gdal_handle_stdcall = None pytest.skip( f"dynamic version({dynamic_version}) does not match " f"static version ({static_version})" ) return gdal_handle except Exception: pytest.skip("cannot find gdal shared object") ############################################################################### # Call GDALDestroyDriverManager() def GDALDestroyDriverManager(): if gdal_handle_stdcall: gdal_handle_stdcall.GDALDestroyDriverManager.argtypes = [] gdal_handle_stdcall.GDALDestroyDriverManager.restype = None gdal_handle_stdcall.GDALDestroyDriverManager() ############################################################################### # Call OGRCleanupAll() def OGRCleanupAll(): if gdal_handle_stdcall: gdal_handle_stdcall.OGRCleanupAll.argtypes = [] gdal_handle_stdcall.OGRCleanupAll.restype = None gdal_handle_stdcall.OGRCleanupAll() ############################################################################### # Call OSRCleanup() def OSRCleanup(): if gdal_handle: gdal_handle.OSRCleanup.argtypes = [] gdal_handle.OSRCleanup.restype = None gdal_handle.OSRCleanup() ############################################################################### # Test GDALSimpleImageWarp def test_testnonboundtoswig_GDALSimpleImageWarp(): src_ds = gdal.Open("data/byte.tif") gt = src_ds.GetGeoTransform() wkt = src_ds.GetProjectionRef() src_ds = None gdal_handle_stdcall.GDALOpen.argtypes = [ctypes.c_char_p, ctypes.c_int] gdal_handle_stdcall.GDALOpen.restype = ctypes.c_void_p gdal_handle_stdcall.GDALClose.argtypes = [ctypes.c_void_p] gdal_handle_stdcall.GDALClose.restype = None gdal_handle.GDALCreateGenImgProjTransformer2.restype = ctypes.c_void_p gdal_handle.GDALCreateGenImgProjTransformer2.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ] gdal_handle_stdcall.GDALSimpleImageWarp.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ] gdal_handle_stdcall.GDALSimpleImageWarp.restype = ctypes.c_int gdal_handle.GDALDestroyGenImgProjTransformer.argtypes = [ctypes.c_void_p] gdal_handle.GDALDestroyGenImgProjTransformer.restype = None out_ds = gdal.GetDriverByName("GTiff").Create("/vsimem/out.tif", 20, 20, 1) out_ds.SetGeoTransform(gt) out_ds.SetProjection(wkt) out_ds = None filename = b"data/byte.tif" native_in_ds = gdal_handle_stdcall.GDALOpen(filename, gdal.GA_ReadOnly) assert native_in_ds is not None filename = b"/vsimem/out.tif" native_out_ds = gdal_handle_stdcall.GDALOpen(filename, gdal.GA_Update) assert native_out_ds is not None pTransformerArg = gdal_handle.GDALCreateGenImgProjTransformer2( native_in_ds, native_out_ds, None ) assert pTransformerArg is not None ret = gdal_handle_stdcall.GDALSimpleImageWarp( native_in_ds, native_out_ds, 0, None, gdal_handle_stdcall.GDALGenImgProjTransform, pTransformerArg, None, None, None, ) assert ret == 1 gdal_handle.GDALDestroyGenImgProjTransformer(pTransformerArg) gdal_handle_stdcall.GDALClose(native_in_ds) gdal_handle_stdcall.GDALClose(native_out_ds) ds = gdal.Open("/vsimem/out.tif") cs = ds.GetRasterBand(1).Checksum() ds = None gdal.Unlink("/vsimem/out.tif") assert cs == 4672 ############################################################################### # Test VRT derived bands with callback functions implemented in Python! def GDALTypeToCTypes(gdaltype): if gdaltype == gdal.GDT_Byte: return ctypes.c_ubyte if gdaltype == gdal.GDT_Int16: return ctypes.c_short if gdaltype == gdal.GDT_UInt16: return ctypes.c_ushort if gdaltype == gdal.GDT_Int32: return ctypes.c_int if gdaltype == gdal.GDT_UInt32: return ctypes.c_uint if gdaltype == gdal.GDT_Float32: return ctypes.c_float if gdaltype == gdal.GDT_Float64: return ctypes.c_double return None def my_pyDerivedPixelFunc( papoSources, nSources, pData, nBufXSize, nBufYSize, eSrcType, eBufType, nPixelSpace, nLineSpace, ): if nSources != 1: print(nSources) print("did not get expected nSources") return 1 srcctype = GDALTypeToCTypes(eSrcType) if srcctype is None: print(eSrcType) print("did not get expected eSrcType") return 1 dstctype = GDALTypeToCTypes(eBufType) if dstctype is None: print(eBufType) print("did not get expected eBufType") return 1 if nPixelSpace != gdal.GetDataTypeSize(eBufType) / 8: print(nPixelSpace) print("did not get expected nPixelSpace") return 1 if (nLineSpace % nPixelSpace) != 0: print(nLineSpace) print("did not get expected nLineSpace") return 1 nLineStride = (int)(nLineSpace / nPixelSpace) srcValues = ctypes.cast(papoSources[0], ctypes.POINTER(srcctype)) dstValues = ctypes.cast(pData, ctypes.POINTER(dstctype)) for j in range(nBufYSize): for i in range(nBufXSize): dstValues[j * nLineStride + i] = srcValues[j * nBufXSize + i] return 0 def test_testnonboundtoswig_VRTDerivedBands(): DerivedPixelFuncType = ctypes.CFUNCTYPE( ctypes.c_int, # ret CPLErr ctypes.POINTER(ctypes.c_void_p), # void **papoSources ctypes.c_int, # int nSources ctypes.c_void_p, # void *pData ctypes.c_int, # int nBufXSize ctypes.c_int, # int nBufYSize ctypes.c_int, # GDALDataType eSrcType ctypes.c_int, # GDALDataType eBufType ctypes.c_int, # int nPixelSpace ctypes.c_int, ) # int nLineSpace my_cDerivedPixelFunc = DerivedPixelFuncType(my_pyDerivedPixelFunc) # CPLErr CPL_DLL CPL_STDCALL GDALAddDerivedBandPixelFunc( const char *pszName, # GDALDerivedPixelFunc pfnPixelFunc ); gdal_handle_stdcall.GDALAddDerivedBandPixelFunc.argtypes = [ ctypes.c_char_p, DerivedPixelFuncType, ] gdal_handle_stdcall.GDALAddDerivedBandPixelFunc.restype = ctypes.c_int funcName = b"pyDerivedPixelFunc" ret = gdal_handle_stdcall.GDALAddDerivedBandPixelFunc( funcName, my_cDerivedPixelFunc ) assert ret == 0 vrt_xml = """ pyDerivedPixelFunc Byte data/byte.tif 1 """ src_ds = gdal.Open("data/byte.tif") ref_cs = src_ds.GetRasterBand(1).Checksum() ref_data = src_ds.GetRasterBand(1).ReadRaster(0, 0, 20, 20) src_ds = None ds = gdal.Open(vrt_xml) got_cs = ds.GetRasterBand(1).Checksum() got_data = ds.GetRasterBand(1).ReadRaster(0, 0, 20, 20) ds = None assert ref_cs == got_cs, "wrong checksum" assert ref_data == got_data