@@ -128,6 +128,14 @@ def _decode_frame(src: bytes, runner: DecodeRunner) -> bytearray | bytes
128128
129129_logger = logging .getLogger (__name__ )
130130
131+ # Lazy singletons for nvimgcodec resources; initialized on first use
132+ if nvimgcodec :
133+ _NVIMGCODEC_DECODER : Any = None
134+ _NVIMGCODEC_DECODE_PARAMS : Any = None
135+ else : # pragma: no cover - nvimgcodec not installed
136+ _NVIMGCODEC_DECODER = None
137+ _NVIMGCODEC_DECODE_PARAMS = None
138+
131139# Required for decoder plugin
132140DECODER_DEPENDENCIES = {
133141 x : ("numpy" , "cupy" , f"{ NVIMGCODEC_MODULE_NAME } >={ NVIMGCODEC_MIN_VERSION } " ) for x in SUPPORTED_TRANSFER_SYNTAXES
@@ -158,6 +166,25 @@ def is_available(uid: UID) -> bool:
158166 return True
159167
160168
169+ def _get_decoder_resources () -> tuple [Any , Any ]:
170+ """Return cached nvimgcodec decoder and decode parameters."""
171+
172+ if nvimgcodec is None :
173+ raise ImportError ("nvimgcodec package is not available." )
174+
175+ global _NVIMGCODEC_DECODER , _NVIMGCODEC_DECODE_PARAMS
176+
177+ if _NVIMGCODEC_DECODER is None :
178+ _NVIMGCODEC_DECODER = nvimgcodec .Decoder ()
179+ if _NVIMGCODEC_DECODE_PARAMS is None :
180+ _NVIMGCODEC_DECODE_PARAMS = nvimgcodec .DecodeParams (
181+ allow_any_depth = True ,
182+ color_spec = nvimgcodec .ColorSpec .UNCHANGED ,
183+ )
184+
185+ return _NVIMGCODEC_DECODER , _NVIMGCODEC_DECODE_PARAMS
186+
187+
161188# Required function for decoder plugin (specific signature but flexible name to be registered to a decoder)
162189# see also https://github.com/pydicom/pydicom/blob/v3.0.1/src/pydicom/pixels/decoders/base.py#L334
163190def _decode_frame (src : bytes , runner : DecodeRunner ) -> bytearray | bytes :
@@ -190,14 +217,10 @@ def _decode_frame(src: bytes, runner: DecodeRunner) -> bytearray | bytes:
190217 if not is_available (tsyntax ):
191218 raise ValueError (f"Transfer syntax { tsyntax } not supported; see details in the debug log." )
192219
193- nvimgcodec_decoder = nvimgcodec .Decoder ()
194- decode_params = nvimgcodec .DecodeParams (allow_any_depth = True , color_spec = nvimgcodec .ColorSpec .UNCHANGED )
195- decoded_data = nvimgcodec_decoder .decode (
196- src , params = decode_params
197- ) # HWC layout, interleaved format, and contiguous array in C-style
198- superface = np .asarray (decoded_data .cpu ())
199- np .ascontiguousarray (superface )
200- return superface .tobytes ()
220+ decoder , params = _get_decoder_resources ()
221+ decoded_surface = decoder .decode (src , params = params ).cpu ()
222+ np_surface = np .ascontiguousarray (np .asarray (decoded_surface ))
223+ return np_surface .tobytes ()
201224
202225
203226def _is_nvimgcodec_available () -> bool :
0 commit comments