@@ -630,6 +630,19 @@ def convert(
630630 item_dicoms , prefix , with_prov , bids_options , tmpdir , dcmconfig
631631 )
632632
633+ # try to handle compression failures from dcm2niix
634+ if outtype == 'nii.gz' :
635+ converted_files = res .outputs .converted_files
636+ if not isinstance (converted_files , list ):
637+ converted_files = [converted_files ]
638+ uncompressed = [x for x in converted_files if x .endswith ('.nii' )]
639+ if len (uncompressed ) > 0 :
640+ lgr .warning ("Conversion returned uncompressed nifti (>4GB?) - "
641+ "trying to salvage by recompressing ourselves. "
642+ "This might take a while " )
643+ if not recompress_failed (uncompressed ):
644+ raise RuntimeError ("Error compressing nifti" )
645+
633646 bids_outfiles = save_converted_files (
634647 res ,
635648 item_dicoms ,
@@ -1099,3 +1112,38 @@ def bvals_are_zero(bval_file: str | list) -> bool:
10991112
11001113 bvals_unique = set (float (b ) for b in bvals )
11011114 return bvals_unique == {0.0 } or bvals_unique == {5.0 }
1115+
1116+
1117+ def recompress_failed (niftis : list ) -> bool :
1118+ """Tries to recompress nifti files with built-in gzip module
1119+
1120+ Parameters
1121+ ----------
1122+ niftis : list
1123+ list of nifti file paths
1124+
1125+ Returns
1126+ -------
1127+ True if all nifits were successfully compressed. False otherwise.
1128+ """
1129+
1130+ import zlib
1131+ import gzip
1132+ from nibabel import load as nb_load
1133+ from nibabel .filebasedimages import ImageFileError
1134+
1135+ for nifti in niftis :
1136+ try :
1137+ img = nb_load (nifti )
1138+ # read everything to catch truncated/corrupted files
1139+ _ = img .get_fdata () # type:ignore[attr-defined]
1140+ with open (nifti , 'rb' ) as f_in :
1141+ with gzip .open (nifti + '.gz' , 'wb' , compresslevel = 6 ) as f_out :
1142+ shutil .copyfileobj (f_in , f_out )
1143+ # nipype results still carry uncompressed file names and they will
1144+ # be renamed to '.nii.gz' later
1145+ os .rename (nifti + '.gz' , nifti )
1146+ except (OSError , ImageFileError , zlib .error ):
1147+ return False
1148+
1149+ return True
0 commit comments