Skip to content

Commit

Permalink
Fix missing _lock and _unlock method on the _Image class
Browse files Browse the repository at this point in the history
  • Loading branch information
denisenkom committed Dec 20, 2023
1 parent 5a0c642 commit 6eb7c58
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
25 changes: 22 additions & 3 deletions src/twain/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,17 @@ def _twain1_alloc(size: int) -> ct.c_void_p:
_twain1_unlock = windows.GlobalUnlock

class _Image(_IImage):
def __init__(self, handle, free: collections.abc.Callable[[typing.Any], None]):
def __init__(
self,
handle,
free: collections.abc.Callable[[typing.Any], None],
lock: collections.abc.Callable[[typing.Any], ct.c_void_p],
unlock: collections.abc.Callable[[typing.Any], None]
):
self._handle = handle
self._free = free
self._lock = lock
self._unlock = unlock

def __del__(self):
self.close()
Expand All @@ -139,7 +147,18 @@ def close(self):

def save(self, filepath: str):
"""Saves in-memory image to BMP file"""
windows.dib_write(self._handle, filepath, self._lock, self._unlock) # type: ignore # needs fixing
# calling GlobalSize may not work on TWAIN2 sources as they may use memory allocator that is not compatible
# with GlobalSize
# in this case would need to change code to determine image size from image contents
size = windows.GlobalSize(self._handle)
ptr = self._lock(self._handle)
try:
dib_bytes = (ct.c_char * size).from_address(ptr)
bmp = windows.convert_dib_to_bmp(dib_bytes)
with open(filepath, "wb") as f:
f.write(bmp)
finally:
self._unlock(self._handle)
else:
# Mac
def _twain1_alloc(size: int) -> ct.c_void_p:
Expand Down Expand Up @@ -905,7 +924,7 @@ def acquire_natively(
def xfer_ready_callback() -> int:
before(self.image_info)
handle, more = self.xfer_image_natively()
after(_Image(handle=handle, free=self._free), more) # type: ignore # needs fixing
after(_Image(handle=handle, free=self._free, lock=self._lock, unlock=self._unlock), more)
return more

self.set_capability(
Expand Down
7 changes: 6 additions & 1 deletion tests/test_integ.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,15 @@ def test_acquire_natively(root_window):
Testing acquire_natively method
"""
logger.info("creating source manager")

def save_and_close(img):
img.save("test.bmp")
img.close()

with twain.SourceManager(root_window) as sm:
logger.info("opening source")
with sm.open_source() as ss: # this posts a modeless dialog...
logger.info("calling acquire_natively")
ss.acquire_natively(
after=lambda img, no: img.close()
after=lambda img, no: save_and_close(img)
)

0 comments on commit 6eb7c58

Please sign in to comment.