Skip to content

Commit 23d8cd0

Browse files
authored
(cont'd) Remove gil from C implementations to enable reading raw files in parallel threads (#220)
1 parent 3bf7e77 commit 23d8cd0

File tree

2 files changed

+47
-33
lines changed

2 files changed

+47
-33
lines changed

rawpy/_rawpy.pyx

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -196,35 +196,35 @@ IF UNAME_SYSNAME == "Windows":
196196
cdef cppclass LibRaw:
197197
libraw_data_t imgdata
198198
LibRaw()
199-
int open_buffer(void *buffer, size_t bufsize)
200-
int open_file(const wchar_t *fname)
201-
int unpack()
202-
int unpack_thumb()
203-
int COLOR(int row, int col)
204-
int dcraw_process()
205-
libraw_processed_image_t* dcraw_make_mem_image(int *errcode)
206-
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode)
207-
void dcraw_clear_mem(libraw_processed_image_t* img)
208-
void free_image()
209-
const char* strerror(int p)
210-
void recycle()
199+
int open_buffer(void *buffer, size_t bufsize) nogil
200+
int open_file(const wchar_t *fname) nogil
201+
int unpack() nogil
202+
int unpack_thumb() nogil
203+
int COLOR(int row, int col) nogil
204+
int dcraw_process() nogil
205+
libraw_processed_image_t* dcraw_make_mem_image(int *errcode) nogil
206+
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode) nogil
207+
void dcraw_clear_mem(libraw_processed_image_t* img) nogil
208+
void free_image() nogil
209+
const char* strerror(int p) nogil
210+
void recycle() nogil
211211
ELSE:
212212
cdef extern from "libraw.h":
213213
cdef cppclass LibRaw:
214214
libraw_data_t imgdata
215215
LibRaw()
216-
int open_buffer(void *buffer, size_t bufsize)
217-
int open_file(const char *fname)
218-
int unpack()
219-
int unpack_thumb()
216+
int open_buffer(void *buffer, size_t bufsize) nogil
217+
int open_file(const char *fname) nogil
218+
int unpack() nogil
219+
int unpack_thumb() nogil
220220
int COLOR(int row, int col)
221-
int dcraw_process()
222-
libraw_processed_image_t* dcraw_make_mem_image(int *errcode)
223-
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode)
224-
void dcraw_clear_mem(libraw_processed_image_t* img)
225-
void free_image()
226-
const char* strerror(int p)
227-
void recycle()
221+
int dcraw_process() nogil
222+
libraw_processed_image_t* dcraw_make_mem_image(int *errcode) nogil
223+
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode) nogil
224+
void dcraw_clear_mem(libraw_processed_image_t* img) nogil
225+
void free_image() nogil
226+
const char* strerror(int p) nogil
227+
void recycle() nogil
228228

229229
libraw_version = (LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, LIBRAW_PATCH_VERSION)
230230

@@ -384,7 +384,8 @@ cdef class RawPy:
384384
# work with raw object
385385
386386
"""
387-
self.p.recycle()
387+
with nogil:
388+
self.p.recycle()
388389

389390
def open_file(self, path):
390391
"""
@@ -402,7 +403,8 @@ cdef class RawPy:
402403
wchars = PyUnicode_AsWideCharString(path, &wchars_len)
403404
if wchars == NULL:
404405
raise RuntimeError('cannot convert unicode path to wide chars')
405-
res = self.p.open_file(wchars)
406+
with nogil:
407+
res = self.p.open_file(wchars)
406408
PyMem_Free(wchars)
407409
ELSE:
408410
res = self.p.open_file(path.encode('UTF-8'))
@@ -421,15 +423,20 @@ cdef class RawPy:
421423
# we keep a reference to the byte buffer to avoid garbage collection
422424
self.bytes = fileobj.read()
423425
cdef char *buf = self.bytes
424-
self.handle_error(self.p.open_buffer(buf, len(self.bytes)))
426+
buf_len = len(self.bytes)
427+
with nogil:
428+
e = self.p.open_buffer(buf, buf_len)
429+
self.handle_error(e)
425430

426431
def unpack(self):
427432
"""
428433
Unpacks/decodes the opened RAW image.
429434
430435
.. NOTE:: This is a low-level method, consider using :func:`rawpy.imread` instead.
431436
"""
432-
self.handle_error(self.p.unpack())
437+
with nogil:
438+
e = self.p.unpack()
439+
self.handle_error(e)
433440
self.bytes = None
434441
self.unpack_called = True
435442

@@ -443,7 +450,9 @@ cdef class RawPy:
443450
444451
.. NOTE:: This is a low-level method, consider using :meth:`~rawpy.RawPy.extract_thumb` instead.
445452
"""
446-
self.handle_error(self.p.unpack_thumb())
453+
with nogil:
454+
e = self.p.unpack_thumb()
455+
self.handle_error(e)
447456
self.unpack_thumb_called = True
448457

449458
cdef ensure_unpack_thumb(self):
@@ -793,7 +802,9 @@ cdef class RawPy:
793802
if params is None:
794803
params = Params(**kw)
795804
self.apply_params(params)
796-
self.handle_error(self.p.dcraw_process())
805+
with nogil:
806+
e = self.p.dcraw_process()
807+
self.handle_error(e)
797808

798809
def dcraw_make_mem_image(self):
799810
"""
@@ -804,7 +815,9 @@ cdef class RawPy:
804815
:rtype: ndarray of shape (h,w,c)
805816
"""
806817
cdef int errcode = 0
807-
cdef libraw_processed_image_t* img = self.p.dcraw_make_mem_image(&errcode)
818+
cdef libraw_processed_image_t* img
819+
with nogil:
820+
img = self.p.dcraw_make_mem_image(&errcode)
808821
self.handle_error(errcode)
809822
assert img.type == LIBRAW_IMAGE_BITMAP
810823
wrapped = processed_image_wrapper()
@@ -826,7 +839,8 @@ cdef class RawPy:
826839
"""
827840
cdef int errcode = 0
828841
cdef libraw_processed_image_t* img
829-
img = self.p.dcraw_make_mem_thumb(&errcode)
842+
with nogil:
843+
img = self.p.dcraw_make_mem_thumb(&errcode)
830844
self.handle_error(errcode)
831845
if img.type == LIBRAW_IMAGE_BITMAP:
832846
wrapped = processed_image_wrapper()

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
# adapted from cffi's setup.py
3131
# the following may be overridden if pkg-config exists
32-
libraries = ['libraw']
32+
libraries = ['libraw_r']
3333
include_dirs = []
3434
library_dirs = []
3535
extra_compile_args = []
@@ -38,7 +38,7 @@
3838
def _ask_pkg_config(resultlist, option, result_prefix='', sysroot=False):
3939
pkg_config = os.environ.get('PKG_CONFIG','pkg-config')
4040
try:
41-
p = subprocess.Popen([pkg_config, option, 'libraw'],
41+
p = subprocess.Popen([pkg_config, option, 'libraw_r'],
4242
stdout=subprocess.PIPE)
4343
except OSError as e:
4444
if e.errno != errno.ENOENT:

0 commit comments

Comments
 (0)