From 6357f7053519030a6968b0fe9c5cc9fcfae5fe39 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Tue, 8 Oct 2019 09:04:16 -0400 Subject: [PATCH] Open a jp2 file multiple tiles to allow multithreaded reads. --- server/tilesource/openjpeg.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/server/tilesource/openjpeg.py b/server/tilesource/openjpeg.py index 6ed6e6eb2..1124c203b 100644 --- a/server/tilesource/openjpeg.py +++ b/server/tilesource/openjpeg.py @@ -93,6 +93,7 @@ def __init__(self, path, **kwargs): self._openjpeg = glymur.Jp2k(largeImagePath) except glymur.jp2box.InvalidJp2kError: raise TileSourceException('File cannot be opened via Glymur and OpenJPEG.') + self._openjpegHandles = [self._openjpeg] try: self.sizeY, self.sizeX = self._openjpeg.shape[:2] except IndexError: @@ -202,8 +203,17 @@ def getTile(self, x, y, z, pilImageAllowed=False, **kwargs): raise TileSourceException('x is outside layer') if y < 0 or y0 >= self.sizeY: raise TileSourceException('y is outside layer') + # possible open the file multiple times so multiple threads can access + # it concurrently. with self._openjpegLock: - tile = self._openjpeg[y0:y1:step, x0:x1:step] + if not len(self._openjpegHandles): + self._openjpegHandles.append(glymur.Jp2k(self._largeImagePath)) + openjpegHandle = self._openjpegHandles.pop() + try: + tile = openjpegHandle[y0:y1:step, x0:x1:step] + finally: + with self._openjpegLock: + self._openjpegHandles.append(openjpegHandle) mode = 'L' if len(tile.shape) == 3: mode = ['L', 'LA', 'RGB', 'RGBA'][tile.shape[2] - 1]