1""":mod:`libraw.bindings` --- Low-level LibRaw bindings 2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 4The :class:`libraw.bindings` module handles linking against the LibRaw binary. 5""" 6 7from ctypes import * # noqa 8from ctypes import util 9 10from libraw import errors 11from libraw.callbacks import data_callback 12from libraw.callbacks import memory_callback 13from libraw.callbacks import progress_callback 14from libraw.errors import c_error 15from libraw import structs_16 16from libraw import structs_17 17from libraw import structs_18 18 19 20class LibRaw(CDLL): 21 22 """ 23 A :class:`ctypes.CDLL` that links against `libraw.so` (or the equivalent on 24 your platform). 25 26 Raises: 27 ImportError: If LibRaw cannot be found on your system, or linking 28 fails. 29 """ 30 31 def __init__(self): # pragma: no cover 32 libraw = util.find_library('raw') 33 try: 34 if libraw is not None: 35 super(LibRaw, self).__init__(libraw) 36 else: 37 raise ImportError 38 except (ImportError, AttributeError, OSError, IOError): 39 raise ImportError('Cannot find LibRaw on your system!') 40 41 try: 42 structs = { 43 16: structs_16, 44 17: structs_17, 45 18: structs_18, 46 }[self.version_number[1]] 47 except KeyError: 48 raise ImportError( 49 'Unsupported Libraw version: %s.%s.%s.' % self.version_number 50 ) 51 52 libraw_data_t = structs.libraw_data_t 53 libraw_decoder_info_t = structs.libraw_decoder_info_t 54 libraw_processed_image_t = structs.libraw_processed_image_t 55 56 # Define arg types 57 58 self.libraw_init.argtypes = [c_int] 59 # enum LibRaw_progress 60 self.libraw_strprogress.argtypes = [c_int] 61 self.libraw_unpack_function_name.argtypes = [POINTER(libraw_data_t)] 62 63 self.libraw_subtract_black.argtypes = [POINTER(libraw_data_t)] 64 self.libraw_open_file.argtypes = [POINTER(libraw_data_t), c_char_p] 65 self.libraw_open_file_ex.argtypes = [ 66 POINTER(libraw_data_t), 67 c_char_p, 68 c_int64 69 ] 70 self.libraw_open_buffer.argtypes = [ 71 POINTER(libraw_data_t), 72 c_void_p, 73 c_int64 74 ] 75 self.libraw_unpack.argtypes = [POINTER(libraw_data_t)] 76 self.libraw_unpack_thumb.argtypes = [POINTER(libraw_data_t)] 77 self.libraw_recycle_datastream.argtypes = [POINTER(libraw_data_t)] 78 self.libraw_recycle.argtypes = [POINTER(libraw_data_t)] 79 self.libraw_close.argtypes = [POINTER(libraw_data_t)] 80 self.libraw_set_memerror_handler.argtypes = [ 81 POINTER(libraw_data_t), 82 memory_callback, 83 c_void_p, 84 ] 85 self.libraw_set_dataerror_handler.argtypes = [ 86 POINTER(libraw_data_t), 87 data_callback, 88 c_void_p, 89 ] 90 self.libraw_set_progress_handler.argtypes = [ 91 POINTER(libraw_data_t), 92 progress_callback, 93 c_void_p, 94 ] 95 self.libraw_adjust_sizes_info_only.argtypes = [ 96 POINTER(libraw_data_t) 97 ] 98 self.libraw_dcraw_ppm_tiff_writer.argtypes = [ 99 POINTER(libraw_data_t), 100 c_char_p 101 ] 102 self.libraw_dcraw_thumb_writer.argtypes = [ 103 POINTER(libraw_data_t), 104 c_char_p 105 ] 106 self.libraw_dcraw_process.argtypes = [POINTER(libraw_data_t)] 107 self.libraw_dcraw_make_mem_image.argtypes = [ 108 POINTER(libraw_data_t), 109 POINTER(c_int) 110 ] 111 self.libraw_dcraw_make_mem_thumb.argtypes = [ 112 POINTER(libraw_data_t), 113 POINTER(c_int) 114 ] 115 self.libraw_dcraw_clear_mem.argtypes = [ 116 POINTER(libraw_processed_image_t) 117 ] 118 self.libraw_raw2image.argtypes = [POINTER(libraw_data_t)] 119 self.libraw_free_image.argtypes = [POINTER(libraw_data_t)] 120 self.libraw_get_decoder_info.argtypes = [ 121 POINTER(libraw_data_t), 122 POINTER(libraw_decoder_info_t) 123 ] 124 self.libraw_COLOR.argtypes = [ 125 POINTER(libraw_data_t), 126 c_int, 127 c_int 128 ] 129 130 # Define return types 131 132 self.libraw_init.restype = POINTER(libraw_data_t) 133 self.libraw_version.restype = c_char_p 134 self.libraw_strprogress.restype = c_char_p 135 self.libraw_versionNumber.restype = c_int 136 self.libraw_cameraCount.restype = c_int 137 self.libraw_cameraList.restype = POINTER( 138 c_char_p * self.libraw_cameraCount() 139 ) 140 self.libraw_unpack_function_name.restype = c_char_p 141 self.libraw_subtract_black.restype = POINTER(libraw_data_t) 142 self.libraw_open_file.restype = c_error 143 self.libraw_open_file_ex.restype = c_error 144 self.libraw_open_buffer.restype = c_error 145 self.libraw_unpack.restype = c_error 146 self.libraw_unpack_thumb.restype = c_error 147 self.libraw_adjust_sizes_info_only.restype = c_error 148 self.libraw_dcraw_ppm_tiff_writer.restype = c_error 149 self.libraw_dcraw_thumb_writer.restype = c_error 150 self.libraw_dcraw_process.restype = c_error 151 self.libraw_dcraw_make_mem_image.restype = POINTER( 152 libraw_processed_image_t) 153 self.libraw_dcraw_make_mem_thumb.restype = POINTER( 154 libraw_processed_image_t) 155 self.libraw_raw2image.restype = c_error 156 self.libraw_get_decoder_info.restype = c_error 157 self.libraw_COLOR.restype = c_int 158 159 # Some special Windows-only garbage: 160 161 try: 162 self.libraw_open_wfile.argtypes = [ 163 POINTER(libraw_data_t), 164 c_wchar_p 165 ] 166 self.libraw_open_wfile_ex.argtypes = [ 167 POINTER(libraw_data_t), 168 c_wchar_p, 169 c_int64 170 ] 171 self.libraw_open_wfile.restype = c_error 172 self.libraw_open_wfile_ex.restype = c_error 173 except AttributeError: 174 pass 175 176 @property 177 def version_number(self): 178 """ 179 A numeric representation of the version of LibRaw which we have linked 180 against in ``(Major, Minor, Patch)`` form. eg. :: 181 182 (0, 16, 1) 183 184 Returns: 185 3 tuple: The version number 186 """ 187 v = self.libraw_versionNumber() 188 return ((v >> 16) & 0x0000ff, (v >> 8) & 0x0000ff, v & 0x0000ff) 189 190 @property 191 def version(self): 192 """ 193 A string representation of the version of LibRaw which we have linked 194 against. eg. :: 195 196 "0.16.1-Release" 197 198 Returns: 199 str: The version 200 """ 201 return self.libraw_version().decode('utf-8') 202 203 def __getitem__(self, name): 204 func = super(LibRaw, self).__getitem__(name) 205 206 func.errcheck = errors.check_call 207 208 return func 209