3.0.0#
The major breaking changes with the version 3.0 release are:
The value for
JPEGLosslesshas changed to1.2.840.10008.1.2.4.57.
The encoding used when saving datasets defaults to the set Transfer Syntax UID.
Dataset.pixel_arraywill convert YCbCr Pixel Data to RGB by default when possible.
read_fileandwrite_filehave 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 - JPEGLosslesshas 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- JPEGLosslessSV1instead for 1.2.840.10008.1.2.4.70.
- The theoretical maximum number of instances supported by - FileSethas been reduced to 1838265625 to ensure support for 32-bit systems (#1743).
- The characters used by - generate_filename()when alphanumeric is- Truehas been reduced to [0-9][A-I,K-Z].
- get_testdata_file()and- get_testdata_files()now raise- ValueErrorif 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.VMalways returns- 1for 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- FileExistsErrorif 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:- The set Transfer Syntax UID, 
- The implicit_vr and little_endian arguments, 
 
- 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_metaelements are no longer modified when writing.
- DicomIOnow requires a readable or writeable buffer during initialisation and- DicomBytesIOdirectly inherits from it.
- The - pydicom.encodersmodule 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. - pyjpeglsor- pylibjpegwith- pylibjpeg-libjpegcan 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 - ndarrayis 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.bufferand changed- FileDataset.filenameto only be the filename the dataset was read from (if any) (#1937).
Removals#
- The - compatmodule has been removed.
- The - dicomdirmodule and- DicomDirclass have been removed and reading a DICOMDIR dataset now returns a normal- FileDatasetinstance. For handling DICOM File-sets and DICOMDIR datasets use the- FileSetclass instead.
- The - read_fileand- write_filefunctions have been removed, use- dcmread()and- dcmwrite()instead.
- The following UID constants have been removed: - JPEGBaseline(use- JPEGBaseline8Bitinstead)
- JPEGExtended(use- JPEGExtended12Bitinstead)
- JPEGLSLossy(use- JPEGLSNearLosslessinstead)
- JPEG2000MultiComponentLossless(use- JPEG2000MCLosslessinstead)
- JPEG2000MultiComponent(use- JPEG2000MCinstead)
 
- The following UID lists have been removed: - JPEGLossyCompressedPixelTransferSyntaxes: use- JPEGTransferSyntaxes
- JPEGLSSupportedCompressedPixelTransferSyntaxes: use- JPEGLSTransferSyntaxes
- JPEG2000CompressedPixelTransferSyntaxes: use- JPEG2000TransferSyntaxes
- RLECompressedLosslessSyntaxes: use- RLETransferSyntaxes
- UncompressedPixelTransferSyntaxes: use- UncompressedTransferSyntaxes
- PILSupportedCompressedPixelTransferSyntaxes
 
- The - PersonNameUnicodeclass has been removed, use- PersonNameinstead.
- The - DataElement.descriptionattribute has been removed, use- DataElement.nameinstead.
- The - pixel_data_handlers.rle_handler.rle_encode_framefunction has been removed, use- Dataset.compress()or- RLELosslessEncoderinstead.
- The - _storage_sopclass_uidsmodule has been removed, import UIDs from the- uidmodule instead.
- The following properties have been removed: - Dataset.parentand- Dataset.parent_seq
- Sequence.parentand- Sequence.parent_dataset
- DataElement.parent
 
- The - overlay_data_handlersmodule has been removed, use the- overlaysmodule instead.
- config.overlay_data_handlershas been removed.
- Dataset.fix_meta_info()has been removed as encoding state now follows the transfer syntax instead of the other way around.
Enhancements#
- Added details of missing required tag information when adding a dataset to a File-set (#1752). 
- The following UID constants have been added: 
- Added convenience method - add_new_private()to add a private tag.
- Added the examples module to make it easier and less confusing for users to work with the example datasets used by the documentation. 
- Added the ability to set the corresponding dataset encoding for private transfer syntaxes to - UIDvia the- set_private_encoding()method.
- Added the ability to register private transfer syntaxes with - register_transfer_syntax()so they can be used when reading datasets with- dcmread().
- Warning messages are also sent to the pydicom logger (#1529). 
- Added the following to the - encapsmodule:- parse_basic_offsets()for parsing the Basic Offset Table.
- parse_fragments()for determining the number of encapsulated fragments and their byte offsets.
- generate_fragments()for yielding encapsulated fragments.
- generate_fragmented_frames()for yielding encapsulated frame fragments.
- generate_frames()for yielding whole encapsulated frames.
- get_frame()for returning the specific encapsulated frame at index without necessarily having to read the preceding frames into memory.
 - These new functions support reading encapsulated data from both - bytesor any Python object with- read(),- seek()and- tell()methods such as- io.BytesIO,- BinaryIOor- mmap.mmap. They also support using the Extended Offset Table for determining frame boundaries.
- Added the keep_deferred keyword argument to - Dataset.get_item()to allow accessing the file offset and element length without having to read the element value. (#1873).
- Added the - pixelsmodule and a new more flexible backend for decoding pixel data via- Decoderfactory class instances. The new decoding backend adds support for the following:- Returning a view over the original pixel data buffer (#746). 
- Returning RGB pixel data by default for JPEG (#1781, #1133 and many others). 
- Returning excess frames for JPEG when there is no Basic or Extended Offset Table and the Number of Frames is incorrect (#1666). 
- Returning excess frames for native encoding when the Number of Frames is incorrect (#2035) 
- Returning the decoded pixel data as either a NumPy - ndarrayor buffer-like object.
- Iterating through either all or specific frames. 
 
- Added support for decoding HTJ2K transfer syntaxes (#1848). 
- Added two functions for returning pixel data as a NumPy - ndarrayfrom a path to a dataset while minimizing memory-usage:- pixel_array()and- iter_pixels().
- Added two functions for compressing and decompressing datasets using the new decoding backend: - compress()and- decompress().
- Added support for the following transfer syntaxes to - Dataset.compress()(#1997):- JPEG-LS Lossless with - JPEGLSLosslessEncoder
- JPEG-LS Near Lossless with - JPEGLSNearLosslessEncoder
- JPEG 2000 Lossless with - JPEG2000LosslessEncoder
- JPEG 2000 with - JPEG2000Encoder
 - See the JPEG-LS and JPEG 2000 encoding guides for more information. 
- Added - Dataset.pixel_array_options()for controlling pixel data decoding when using- Dataset.pixel_arraywith the new- pixelsbackend.
- Improve support for reading and resolving inline binary data with VR=UN from Json (#2062). 
- get_j2k_parameters()now takes into account the JP2 header (if present, although it’s non-conformant for it to be) (#2073).
- Added support for NumPy v2.0 (#2075). 
- Added - pydicom.__concepts_version__attribute with the DICOM Standard version used to create the concepts dictionaries in- pydicom.sr(#1021).
- Refactored the interface for the concepts in - pydicom.srto simplify the access types (#1454).
- Added the - Dataset.set_pixel_data()method and- set_pixel_data()function for automatically setting a dataset’s Pixel Data and related Image Pixel module elements using an- ndarray(#50).
- Added typing support for - Datasetelement access using the types-pydicom package. (#1485).
- Added - apply_presentation_lut()for applying a Presentation LUT to an- ndarray(#1265).
- Added - apply_icc_profile()and- create_icc_transform()for applying ICC profiles to an- ndarray(#1244).
- Added - Dataset.update_raw_element()to make it easier to modify a- RawDataElement’s VR or value prior to conversion to a- DataElement(#1739).
- Added support for using - io.BufferedIOBasesubclasses to set the value for elements with O* VRs such as OB and OW (#1913).
- Added - encapsulate_buffer()and- encapsulate_extended_buffer()for encapsulating buffered compressed Pixel Data via- EncapsulatedBufferinstances.
- Added elements with OB, OD, OF, OL, OW, OV VRs to the type validation checking when setting - DataElementvalues (#1414).
- Added - convert_raw_data_element()for converting raw element data to- DataElementinstances.
- Added the - hooksmodule which contains an interface for adding callback functions via the- Hookssingleton, as well as default and alternative convenience callbacks for- convert_raw_data_element()(#1556).
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_CORRECTIONSis- 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 - FileInstanceinstances being able to escape the temporary directory when being added to a- FileSet(#1922).
- Fixed an - AttributeErrorwhen 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,- pillowand- rlepixel 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_arrayreturning the previous array instead of creating a new one (#1983).
- Fixed a - KeyErrorwhen comparing codes with one of the codes having- scheme_designatorset to- SRTbut not being included in the- SRTto- SCTcode 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 - ndarraywhen 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 - RecursionErrorwhen 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#
- Dataset.is_little_endianand- Dataset.is_implicit_VRwill be removed in v4.0.
- Dataset.read_little_endianand- Dataset.read_implicit_vrwill be removed in v4.0, use- Dataset.original_encodinginstead.
- Dataset.read_encodingwill be removed in v4.0, use- Dataset.original_character_setinstead.
- The write_like_original optional argument to - Dataset.save_asand- dcmwrite()will be removed in v4.0, use enforce_file_format instead.
- The following - encapsmodule functions will be removed in v4.0:- get_frame_offsets(), use- parse_basic_offsets()instead.
- generate_pixel_data_fragment(), use- generate_fragments()instead.
- generate_pixel_data_frame(), use- generate_fragmented_frames()instead.
- generate_pixel_data(), use- generate_frames()instead.
- decode_data_sequence(), use- generate_fragments()instead.
- defragment_data(), use- generate_frames()instead.
- read_item(), use- generate_fragments()instead.
 
- The - pydicom.pixel_data_handlersmodule will be removed in v4.0. All pixel data processing will use the- pydicom.pixelsmodule instead starting with v3.0.- The following functions from - pydicom.pixel_data_handlers.utilhave been moved to- pydicom.pixels.processing:
- The following functions from - pydicom.pixel_data_handlers.utilhave been moved to- pydicom.pixels.utils:
- pydicom.pixel_data_handlers.util.dtype_corrected_for_endianness()will be removed in v4.0.
 
- Dataset.convert_pixel_data()will be removed in v4.0, use- Dataset.pixel_array_options()instead.
- DataElement_from_raw()will be removed in v4.0, please use- convert_raw_data_element()instead.
- config.data_element_callbackand- config.data_element_callback_kwargswill be removed in v4.0, please use the hooks for- convert_raw_data_element()instead.
- The - pydicom.utils.fixerssubmodule will be removed in v4.0, please use the alternative callbacks for- convert_raw_data_element()in the- hooksmodule instead.
Pydicom Internals#
- Repository folder structure refactored. 
- Renamed top level - sourcefolder to- util.
- New CI tools - dependabot, and pre-commit using black and ruff. 
