|
| 1 | +from __future__ import print_function, division |
| 2 | +import subprocess |
| 3 | +import os |
| 4 | + |
| 5 | +width = 1500 |
| 6 | +height = 1000 |
| 7 | +#ctypes |
| 8 | +# First all the declarations. Each function and struct must be redefined ... |
| 9 | +import ctypes |
| 10 | + |
| 11 | +class CtypesImg(ctypes.Structure): |
| 12 | + _fields_ = [('width', ctypes.c_int), |
| 13 | + ('height', ctypes.c_int), |
| 14 | + ('data', ctypes.POINTER(ctypes.c_uint8)), # HUH? |
| 15 | + ] |
| 16 | + array_cache = {} |
| 17 | + def __init__(self, width, height): |
| 18 | + self.width = width |
| 19 | + self.height = height |
| 20 | + # Create a class type to hold the data. |
| 21 | + # Since this creates a type, cache it for reuse rather |
| 22 | + # than create a new one each time |
| 23 | + if width*height not in self.array_cache: |
| 24 | + self.array_cache[width*height] = ctypes.c_uint8 * (width * height) |
| 25 | + # Note this keeps the img.data alive in the interpreter |
| 26 | + self.data = self.array_cache[width*height]() # !!!!!! |
| 27 | + |
| 28 | + def asmemoryview(self): |
| 29 | + # There must be a better way, but this code will not |
| 30 | + # be timed, so explicit trumps implicit |
| 31 | + ret = self.array_cache[width*height]() |
| 32 | + for i in range(width*height): |
| 33 | + ret[i] = self.data[i] |
| 34 | + return ret |
| 35 | + |
| 36 | +ctypesimg = CtypesImg(width, height) |
| 37 | + |
| 38 | + |
| 39 | +# Load the DLL |
| 40 | +cdll = ctypes.cdll.LoadLibrary('./libcreate_fractal.so') |
| 41 | + |
| 42 | +#Fish the function pointers from the DLL and define the interfaces |
| 43 | +create_fractal_ctypes = cdll.create_fractal |
| 44 | +create_fractal_ctypes.argtypes = [CtypesImg, ctypes.c_int] |
| 45 | + |
| 46 | +mandel_ctypes = cdll.mandel |
| 47 | +mandel_ctypes.argtypes = [ctypes.c_float, ctypes.c_float, ctypes.c_int, |
| 48 | + ctypes.POINTER(ctypes.c_uint8)] |
| 49 | + |
| 50 | + |
| 51 | +if __name__ == "__main__": |
| 52 | + from timeit import default_timer as timer |
| 53 | + from PIL import Image |
| 54 | + from create_fractal import create_fractal |
| 55 | + s = timer() |
| 56 | + create_fractal_ctypes(ctypesimg, 20) |
| 57 | + e = timer() |
| 58 | + ctypes_onecall = e - s |
| 59 | + print('ctypes calling create_fractal required {:.2f} millisecs'.format(1000*ctypes_onecall)) |
| 60 | + data = ctypesimg.asmemoryview() |
| 61 | + print(max(data)) |
| 62 | + im = Image.frombuffer("L", (width, height), data, 'raw', 'L', 0, 1) |
| 63 | + im.save('ctypes_fractal.png') |
| 64 | + |
| 65 | + value = (ctypes.c_uint8*1)() |
| 66 | + s = timer() |
| 67 | + create_fractal(ctypesimg, 20, mandel_ctypes, value) |
| 68 | + e = timer() |
| 69 | + ctypes_createfractal = e - s |
| 70 | + data = ctypesimg.asmemoryview() |
| 71 | + print(max(data)) |
| 72 | + print('ctypes calling mandel required {:.2f} millisecs'.format(1000*ctypes_createfractal)) |
| 73 | + im = Image.frombuffer("L", (width, height), data, 'raw', 'L', 0, 1) |
| 74 | + im.save('ctypes_mandel.png') |
0 commit comments