source: trunk/autotest/gcore/testnonboundtoswig.py @ 22896

Last change on this file since 22896 was 22896, checked in by rouault, 5 years ago

Test VRT derived bands with callback functions implemented in Python

  • Property svn:keywords set to Id
File size: 10.6 KB
Line 
1#!/usr/bin/env python
2###############################################################################
3# $Id: testnonboundtoswig.py 22896 2011-08-07 18:32:01Z rouault $
4#
5# Project:  GDAL/OGR Test Suite
6# Purpose:  Test GDAL functions not bound SWIG with ctypes
7# Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
8#
9###############################################################################
10# Copyright (c) 2011 Even Rouault
11#
12# Permission is hereby granted, free of charge, to any person obtaining a
13# copy of this software and associated documentation files (the "Software"),
14# to deal in the Software without restriction, including without limitation
15# the rights to use, copy, modify, merge, publish, distribute, sublicense,
16# and/or sell copies of the Software, and to permit persons to whom the
17# Software is furnished to do so, subject to the following conditions:
18#
19# The above copyright notice and this permission notice shall be included
20# in all copies or substantial portions of the Software.
21#
22# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28# DEALINGS IN THE SOFTWARE.
29###############################################################################
30
31import gdal
32import sys
33import os
34from sys import version_info
35
36sys.path.append( '../pymod' )
37
38try:
39    import ctypes
40except:
41    pass
42
43import gdaltest
44
45gdal_handle = None
46gdal_handle_stdcall = None
47
48###############################################################################
49# Init
50
51def testnonboundtoswig_init():
52
53    global gdal_handle, gdal_handle_stdcall
54
55    try:
56        ctypes.cdll
57    except:
58        print('cannot find ctypes')
59        return 'skip'
60
61    static_version = gdal.VersionInfo(None)
62    short_static_version = static_version[0:2]
63
64    for name in ["libgdal.so", "libgdal.dylib", "gdal%s.dll" % short_static_version, "gdal%sdev.dll" % short_static_version]:
65        try:
66            gdal_handle = ctypes.cdll.LoadLibrary(name)
67            try:
68                gdal_handle_stdcall = ctypes.windll.LoadLibrary(name)
69            except:
70                gdal_handle_stdcall = gdal_handle
71
72            gdal_handle_stdcall.GDALVersionInfo.argtypes = [ ctypes.c_char_p ]
73            gdal_handle_stdcall.GDALVersionInfo.restype = ctypes.c_char_p
74
75            dynamic_version = gdal_handle_stdcall.GDALVersionInfo(None)
76            if version_info >= (3,0,0):
77                dynamic_version = str(dynamic_version, 'utf-8')
78
79            if dynamic_version != static_version:
80                gdaltest.post_reason('dynamic version(%s) does not match static version (%s)' % (dynamic_version, static_version))
81                gdal_handle = None
82                gdal_handle_stdcall = None
83                return 'skip'
84
85            return 'success'
86        except:
87            pass
88
89    print('cannot find gdal shared object')
90    return 'skip'
91
92###############################################################################
93# Test GDALSimpleImageWarp
94
95def testnonboundtoswig_GDALSimpleImageWarp():
96
97    if gdal_handle is None:
98        return 'skip'
99
100    src_ds = gdal.Open('data/byte.tif')
101    gt = src_ds.GetGeoTransform()
102    wkt = src_ds.GetProjectionRef()
103    src_ds = None
104
105    gdal_handle_stdcall.GDALOpen.argtypes = [ ctypes.c_char_p, ctypes.c_int]
106    gdal_handle_stdcall.GDALOpen.restype = ctypes.c_void_p
107
108    gdal_handle_stdcall.GDALClose.argtypes = [ ctypes.c_void_p ]
109    gdal_handle_stdcall.GDALClose.restype = None
110
111    gdal_handle.GDALCreateGenImgProjTransformer2.restype = ctypes.c_void_p
112    gdal_handle.GDALCreateGenImgProjTransformer2.argtypes = [ ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
113
114    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]
115    gdal_handle_stdcall.GDALSimpleImageWarp.restype = ctypes.c_int
116
117    gdal_handle.GDALDestroyGenImgProjTransformer.argtypes = [ ctypes.c_void_p ]
118    gdal_handle.GDALDestroyGenImgProjTransformer.restype = None
119
120    out_ds = gdal.GetDriverByName('GTiff').Create('/vsimem/out.tif', 20, 20, 1)
121    out_ds.SetGeoTransform(gt)
122    out_ds.SetProjection(wkt)
123    out_ds = None
124
125    filename = 'data/byte.tif'
126    if version_info >= (3,0,0):
127        filename = bytes(filename, 'utf-8')
128
129    native_in_ds = gdal_handle_stdcall.GDALOpen(filename, gdal.GA_ReadOnly)
130    if native_in_ds is None:
131        gdaltest.post_reason('fail')
132        return 'fail'
133
134    filename = '/vsimem/out.tif'
135    if version_info >= (3,0,0):
136        filename = bytes(filename, 'utf-8')
137
138    native_out_ds = gdal_handle_stdcall.GDALOpen(filename, gdal.GA_Update)
139    if native_out_ds is None:
140        gdaltest.post_reason('fail')
141        return 'fail'
142
143    pTransformerArg = gdal_handle.GDALCreateGenImgProjTransformer2( native_in_ds, native_out_ds, None )
144    if pTransformerArg is None:
145        gdaltest.post_reason('fail')
146        return 'fail'
147
148    ret = gdal_handle_stdcall.GDALSimpleImageWarp(native_in_ds, native_out_ds, 0, None, gdal_handle_stdcall.GDALGenImgProjTransform, pTransformerArg, None, None, None)
149    if ret != 1:
150        gdaltest.post_reason('fail')
151        print(ret)
152        return 'fail'
153
154    gdal_handle.GDALDestroyGenImgProjTransformer(pTransformerArg)
155
156    gdal_handle_stdcall.GDALClose(native_in_ds)
157    gdal_handle_stdcall.GDALClose(native_out_ds)
158
159    ds = gdal.Open('/vsimem/out.tif')
160    cs = ds.GetRasterBand(1).Checksum()
161    ds = None
162
163    gdal.Unlink('/vsimem/out.tif')
164
165    if cs != 4672:
166        gdaltest.post_reason('fail')
167        print(cs)
168        return 'fail'
169
170    return 'success'
171
172###############################################################################
173# Test VRT derived bands with callback functions implemented in Python!
174
175def GDALTypeToCTypes(gdaltype):
176
177    if gdaltype == gdal.GDT_Byte:
178        return ctypes.c_ubyte
179    elif gdaltype == gdal.GDT_Int16:
180        return ctypes.c_short
181    elif gdaltype == gdal.GDT_UInt16:
182        return ctypes.c_ushort
183    elif gdaltype == gdal.GDT_Int32:
184        return ctypes.c_int
185    elif gdaltype == gdal.GDT_UInt32:
186        return ctypes.c_uint
187    elif gdaltype == gdal.GDT_Float32:
188        return ctypes.c_float
189    elif gdaltype == gdal.GDT_Float64:
190        return ctypes.c_double
191    else:
192        return None
193
194def my_pyDerivedPixelFunc(papoSources, nSources, pData, nBufXSize, nBufYSize, eSrcType, eBufType, nPixelSpace, nLineSpace):
195    if nSources != 1:
196        print(nSources)
197        gdaltest.post_reason('did not get expected nSources')
198        return 1
199
200    srcctype = GDALTypeToCTypes(eSrcType)
201    if srcctype is None:
202        print(eSrcType)
203        gdaltest.post_reason('did not get expected eSrcType')
204        return 1
205
206    dstctype = GDALTypeToCTypes(eBufType)
207    if dstctype is None:
208        print(eBufType)
209        gdaltest.post_reason('did not get expected eBufType')
210        return 1
211
212    if nPixelSpace != gdal.GetDataTypeSize(eBufType) / 8:
213        print(nPixelSpace)
214        gdaltest.post_reason('did not get expected nPixelSpace')
215        return 1
216
217    if (nLineSpace % nPixelSpace) != 0:
218        print(nLineSpace)
219        gdaltest.post_reason('did not get expected nLineSpace')
220        return 1
221
222    nLineStride = (int)(nLineSpace/nPixelSpace)
223
224    srcValues = ctypes.cast(papoSources[0], ctypes.POINTER(srcctype))
225    dstValues = ctypes.cast(pData, ctypes.POINTER(dstctype))
226    for j in range(nBufYSize):
227        for i in range(nBufXSize):
228            dstValues[j * nLineStride + i] = srcValues[j * nBufXSize + i]
229
230    return 0
231
232def testnonboundtoswig_VRTDerivedBands():
233
234    if gdal_handle is None:
235        return 'skip'
236
237    DerivedPixelFuncType = ctypes.CFUNCTYPE(ctypes.c_int, # ret CPLErr
238                                            ctypes.POINTER(ctypes.c_void_p), # void **papoSources
239                                            ctypes.c_int, # int nSources
240                                            ctypes.c_void_p, #void *pData
241                                            ctypes.c_int, #int nBufXSize
242                                            ctypes.c_int, #int nBufYSize
243                                            ctypes.c_int, # GDALDataType eSrcType
244                                            ctypes.c_int, # GDALDataType eBufType
245                                            ctypes.c_int, #int nPixelSpace
246                                            ctypes.c_int ) #int nLineSpace
247
248    my_cDerivedPixelFunc = DerivedPixelFuncType(my_pyDerivedPixelFunc)
249
250    #CPLErr CPL_DLL CPL_STDCALL GDALAddDerivedBandPixelFunc( const char *pszName,
251    #                                GDALDerivedPixelFunc pfnPixelFunc );
252
253    gdal_handle_stdcall.GDALAddDerivedBandPixelFunc.argtypes = [ ctypes.c_char_p, DerivedPixelFuncType]
254    gdal_handle_stdcall.GDALAddDerivedBandPixelFunc.restype = ctypes.c_int
255
256    funcName = "pyDerivedPixelFunc"
257    if version_info >= (3,0,0):
258        funcName = bytes(funcName, 'utf-8')
259    ret = gdal_handle_stdcall.GDALAddDerivedBandPixelFunc(funcName, my_cDerivedPixelFunc)
260    if ret != 0:
261        gdaltest.post_reason('fail')
262        return 'fail'
263
264    vrt_xml = """<VRTDataset rasterXSize="20" rasterYSize="20">
265  <VRTRasterBand dataType="Byte" band="1" subClass="VRTDerivedRasterBand">
266    <PixelFunctionType>pyDerivedPixelFunc</PixelFunctionType>
267    <SourceTransferType>Byte</SourceTransferType>
268    <SimpleSource>
269      <SourceFilename relativeToVRT="0">data/byte.tif</SourceFilename>
270      <SourceBand>1</SourceBand>
271      <SrcRect xOff="0" yOff="0" xSize="20" ySize="20" />
272      <DstRect xOff="0" yOff="0" xSize="20" ySize="20" />
273    </SimpleSource>
274  </VRTRasterBand>
275</VRTDataset>"""
276
277    src_ds = gdal.Open('data/byte.tif')
278    ref_cs = src_ds.GetRasterBand(1).Checksum()
279    ref_data = src_ds.GetRasterBand(1).ReadRaster(0,0,20,20)
280    src_ds = None
281
282    ds = gdal.Open(vrt_xml)
283    got_cs = ds.GetRasterBand(1).Checksum()
284    got_data = ds.GetRasterBand(1).ReadRaster(0,0,20,20)
285    ds = None
286
287    if ref_cs != got_cs:
288        gdaltest.post_reason('wrong checksum')
289        print(got_cs)
290        return 'fail'
291
292    if ref_data != got_data:
293        gdaltest.post_reason('wrong data')
294        print(ref_data)
295        print(got_data)
296        return 'fail'
297
298    return 'success'
299
300gdaltest_list = [ testnonboundtoswig_init,
301                  testnonboundtoswig_GDALSimpleImageWarp,
302                  testnonboundtoswig_VRTDerivedBands ]
303
304if __name__ == '__main__':
305
306    gdaltest.setup_run( 'testnonboundtoswig' )
307
308    gdaltest.run_tests( gdaltest_list )
309
310    gdaltest.summarize()
311
Note: See TracBrowser for help on using the repository browser.