@@ -1997,16 +1997,27 @@ def insert_instances(
19971997 transfer_syntax_uid = transfer_syntax_uid
19981998 )
19991999 dcmwrite (b , ds , write_like_original = False )
2000+ # The data set needs to be read back (at least partially)
2001+ # to determine the offset of the Pixel Data element. This
2002+ # is required to either read or build the Basic Offset Table
2003+ # for image instances to allow for fast retrieval of frames.
2004+ fp .seek (0 )
2005+ # One needs to specify at least one tag to satisfy mypy.
2006+ tag = tag_for_keyword ('PatientID' )
2007+ dcmread (
2008+ fp ,
2009+ specific_tags = [tag ], # type: ignore
2010+ stop_before_pixels = True
2011+ )
2012+ pixel_data_offset = fp .tell ()
2013+
20002014 pixel_data_element : Union [DataElement , None ] = None
20012015 for pixel_data_tag in _PIXEL_DATA_TAGS :
20022016 try :
20032017 pixel_data_element = ds [pixel_data_tag ]
20042018 except KeyError :
20052019 continue
20062020 if pixel_data_element is not None :
2007- pixel_data_offset = pixel_data_element .file_tell
2008- if pixel_data_offset is None :
2009- continue
20102021 fp .seek (pixel_data_offset , 0 )
20112022 first_frame_offset , bot = _get_frame_offsets (
20122023 fp ,
@@ -2017,7 +2028,8 @@ def insert_instances(
20172028 np .product ([
20182029 ds .Rows ,
20192030 ds .Columns ,
2020- ds .SamplesPerPixel ])
2031+ ds .SamplesPerPixel
2032+ ])
20212033 ),
20222034 transfer_syntax_uid = ds .file_meta .TransferSyntaxUID ,
20232035 bits_allocated = ds .BitsAllocated
@@ -2028,14 +2040,14 @@ def insert_instances(
20282040
20292041 fp .seek (0 )
20302042 file_content = fp .read ()
2043+
20312044 instances [sop_instance_uid ] = (
20322045 * instance_metadata ,
20332046 str (ds .file_meta .TransferSyntaxUID ),
20342047 str (rel_file_path ),
20352048 first_frame_offset ,
20362049 bot ,
20372050 )
2038-
20392051 file_path = self .base_dir .joinpath (rel_file_path )
20402052 successes .append ((ds , file_path , file_content ))
20412053 except Exception as error :
@@ -2899,6 +2911,7 @@ def retrieve_instance_rendered(
28992911 frame_index = frame_index ,
29002912 transfer_syntax_uid = transfer_syntax_uid
29012913 )
2914+ image_file_pointer .close ()
29022915
29032916 # TODO: ICC Profile
29042917 codec_name , codec_kwargs = self ._get_image_codec_parameters (
@@ -3187,6 +3200,8 @@ def iter_instance_frames(
31873200 else :
31883201 yield frame
31893202
3203+ image_file_pointer .close ()
3204+
31903205 def retrieve_instance_frames (
31913206 self ,
31923207 study_instance_uid : str ,
@@ -3313,6 +3328,7 @@ def retrieve_instance_frames(
33133328 else :
33143329 retrieved_frames .append (frame )
33153330
3331+ image_file_pointer .close ()
33163332 return retrieved_frames
33173333
33183334 def retrieve_instance_frames_rendered (
@@ -3383,6 +3399,7 @@ def retrieve_instance_frames_rendered(
33833399 frame_index = frame_index ,
33843400 transfer_syntax_uid = transfer_syntax_uid
33853401 )
3402+ image_file_pointer .close ()
33863403
33873404 # TODO: ICC Profile
33883405 codec_name , codec_kwargs = self ._get_image_codec_parameters (
@@ -3573,6 +3590,9 @@ def store_instances(
35733590 response = Dataset ()
35743591 response .RetrieveURL = None
35753592
3593+ if len (successes ) == 0 and len (failures ) == 0 :
3594+ raise RuntimeError ('Failed to store instances.' )
3595+
35763596 if len (successes ) > 0 :
35773597 response .ReferencedSOPSequence = []
35783598 for ds , file_path , file_content in successes :
0 commit comments