3.0.0#

The major breaking changes with the version 3.0 release are:

  • The value for JPEGLossless has changed to 1.2.840.10008.1.2.4.57.

  • The encoding used when saving datasets defaults to the set Transfer Syntax UID.

  • Dataset.pixel_array will convert YCbCr Pixel Data to RGB by default when possible.

  • read_file and write_file have been removed.

Changes#

  • Removed support for Python <= 3.9.

  • All tag formats changed to upper case, no space e.g. “(7FE0,0010)” rather than “(7fe0, 0010)”.

  • Values with VR AE with an incorrect value length are now handled gracefully (extra bytes are ignored with a warning).

  • A value of 0 for Number of Frames is now handled as 1 frame, with a user warning issued on reading the pixel data (#1844).

  • The value for JPEGLossless has changed from 1.2.840.10008.1.2.4.70 to 1.2.840.10008.1.2.4.57 to match its UID keyword. Use JPEGLosslessSV1 instead for 1.2.840.10008.1.2.4.70.

  • The theoretical maximum number of instances supported by FileSet has been reduced to 1838265625 to ensure support for 32-bit systems (#1743).

  • The characters used by generate_filename() when alphanumeric is True has been reduced to [0-9][A-I,K-Z].

  • get_testdata_file() and get_testdata_files() now raise ValueError if called with an absolute path or pattern.

  • generate_uid() has been changed to use a random suffix generated using randbelow() when entropy_srcs isn’t used, and the maximum allowed length of the prefix has been changed to 54 characters (#1773).

  • DataElement.VM always returns 1 for SQ elements (#1481).

  • DICOM dictionary updated to 2024c.

  • Concepts dictionaries updated to 2024c.

  • validate_file_meta() now checks to ensure required Type 1 elements aren’t empty.

  • implicit_vr and little_endian optional arguments added to Dataset.save_as(). In addition, this method will now raise an exception if the user tries to convert between little and big endian datasets. If this is something you need, use dcmwrite() instead.

  • Added the overwrite argument to Dataset.save_as() and dcmwrite() to allow raising a FileExistsError if trying to write to a file that already exists (#2104).

  • implicit_vr, little_endian and force_encoding optional arguments added to dcmwrite().

  • The priority used to decide which encoding to use with Dataset.save_as() and dcmwrite() has been changed to:

    1. The set Transfer Syntax UID,

    2. The implicit_vr and little_endian arguments,

    3. Dataset.is_implicit_VR and Dataset.is_little_endian,

    4. Dataset.original_encoding.

  • Datasets containing Command Set (0000,eeee) elements can no longer be written using Dataset.save_as() or dcmwrite(), use write_dataset() instead.

  • A dataset’s file_meta elements are no longer modified when writing.

  • DicomIO now requires a readable or writeable buffer during initialisation and DicomBytesIO directly inherits from it.

  • The pydicom.encoders module has been moved to pydicom.pixels.encoders, the original import path will be removed in v4.0.

  • Using GDCM v3.0.23 or lower to decode JPEG-LS datasets with a Bits Stored of 6 or 7 produces incorrect results, so attempting to do so now raises an exception. pyjpegls or pylibjpeg with pylibjpeg-libjpeg can be used instead (#2008).

  • Using Pillow with JPEG 2000 encoded > 8-bit multi-sample data (such as RGB) now raises an exception as Pillow cannot decode such data correctly (#2006).

  • An exception will now be raised if an ndarray is used to set Pixel Data (#50).

  • Logging of errors when converting elements using Dataset.to_json_dict() have been made more verbose and now use logging.WARNING (#1909).

  • Added FileDataset.buffer and changed FileDataset.filename to only be the filename the dataset was read from (if any) (#1937).

Removals#

  • The compat module has been removed.

  • The dicomdir module and DicomDir class have been removed and reading a DICOMDIR dataset now returns a normal FileDataset instance. For handling DICOM File-sets and DICOMDIR datasets use the FileSet class instead.

  • The read_file and write_file functions have been removed, use dcmread() and dcmwrite() instead.

  • The following UID constants have been removed:

  • The following UID lists have been removed:

  • The PersonNameUnicode class has been removed, use PersonName instead.

  • The DataElement.description attribute has been removed, use DataElement.name instead.

  • The pixel_data_handlers.rle_handler.rle_encode_frame function has been removed, use Dataset.compress() or RLELosslessEncoder instead.

  • The _storage_sopclass_uids module has been removed, import UIDs from the uid module instead.

  • The following properties have been removed:

    • Dataset.parent and Dataset.parent_seq

    • Sequence.parent and Sequence.parent_dataset

    • DataElement.parent

  • The overlay_data_handlers module has been removed, use the overlays module instead.

  • config.overlay_data_handlers has been removed.

  • Dataset.fix_meta_info() has been removed as encoding state now follows the transfer syntax instead of the other way around.

Enhancements#

Fixes#

  • Fixed the GDCM and pylibjpeg handlers changing the Pixel Representation value to 0 when the J2K stream disagrees with the dataset and APPLY_J2K_CORRECTIONS is True (#1689).

  • Fixed pydicom codify error when relative path did not exist.

  • Fixed the VR enum sometimes returning invalid values for Python 3.11+ (#1874).

  • Fixed pixel data handler for Pillow 10.1 raising an AttributeError (#1907).

  • Fixed a possible security issue with FileInstance instances being able to escape the temporary directory when being added to a FileSet (#1922).

  • Fixed an AttributeError when running deepcopy() after Dataset.update (#1816).

  • Fixed encapsulate_extended() not returning the correct values for odd-length frames (#1968).

  • Fixed using the incorrect encoding when writing datasets converted between explicit and implicit VR when only the Transfer Syntax UID was changed (#1943).

  • Fixed the jpeg_ls, pillow and rle pixel data handlers not working correctly when a frame is spread across multiple fragments (#1774).

  • Added mitigation for a rare case where clearing the pixel data value prior to updating it may sometimes result in pixel_array returning the previous array instead of creating a new one (#1983).

  • Fixed a KeyError when comparing codes with one of the codes having scheme_designator set to SRT but not being included in the SRT to SCT code mapping (#1994).

  • Fixed JPEG-LS datasets with a Pixel Representation of 1 returning incorrect image data when Bits Stored is less than Bits Allocated (#2009).

  • Fixed decoding failures for JPEG-LS datasets with Bits Allocated of 16 and Bits Stored <= 8 (#2010).

  • Fixed the Pixel Data VR not being set correctly with Dataset.compress() (#2013).

  • Fixed Dataset.decompress() not updating the Pixel Data element value until after saving (#2024).

  • Fixed a rare issue with converting pixel data to an ndarray when Bits Stored is less than Bits Allocated and the unused bits haven’t been set to an appropriate value for correct interpretation of the data.

  • Fixed a RecursionError when using copy.deepcopy() with a dataset containing a private block (#2025).

  • Fixed non-unique keywords for the concept codes in pydicom.sr (#1388).

  • Fixed keywords using Python identifiers in pydicom.sr (#1273).

  • Fixed being unable to write LUT Descriptor when the VR is SS and the first value is greater than 32767 (#2081).

  • Fixed Deflated Explicit VR Little Endian datasets not working correctly with codify (#1937).

Deprecations#

Pydicom Internals#

  • Repository folder structure refactored.

  • Renamed top level source folder to util.

  • New CI tools - dependabot, and pre-commit using black and ruff.