3.0.0#
The major breaking changes with the version 3.0 release are:
The value for
JPEGLossless
has changed to1.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
andwrite_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. UseJPEGLosslessSV1
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 isTrue
has been reduced to [0-9][A-I,K-Z].get_testdata_file()
andget_testdata_files()
now raiseValueError
if called with an absolute path or pattern.generate_uid()
has been changed to use a random suffix generated usingrandbelow()
when entropy_srcs isn’t used, and the maximum allowed length of the prefix has been changed to 54 characters (#1773).DataElement.VM
always returns1
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, usedcmwrite()
instead.Added the overwrite argument to
Dataset.save_as()
anddcmwrite()
to allow raising aFileExistsError
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()
anddcmwrite()
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()
ordcmwrite()
, usewrite_dataset()
instead.A dataset’s
file_meta
elements are no longer modified when writing.DicomIO
now requires a readable or writeable buffer during initialisation andDicomBytesIO
directly inherits from it.The
pydicom.encoders
module has been moved topydicom.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
orpylibjpeg
withpylibjpeg-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 uselogging.WARNING
(#1909).Added
FileDataset.buffer
and changedFileDataset.filename
to only be the filename the dataset was read from (if any) (#1937).
Removals#
The
compat
module has been removed.The
dicomdir
module andDicomDir
class have been removed and reading a DICOMDIR dataset now returns a normalFileDataset
instance. For handling DICOM File-sets and DICOMDIR datasets use theFileSet
class instead.The
read_file
andwrite_file
functions have been removed, usedcmread()
anddcmwrite()
instead.The following UID constants have been removed:
JPEGBaseline
(useJPEGBaseline8Bit
instead)JPEGExtended
(useJPEGExtended12Bit
instead)JPEGLSLossy
(useJPEGLSNearLossless
instead)JPEG2000MultiComponentLossless
(useJPEG2000MCLossless
instead)JPEG2000MultiComponent
(useJPEG2000MC
instead)
The following UID lists have been removed:
JPEGLossyCompressedPixelTransferSyntaxes
: useJPEGTransferSyntaxes
JPEGLSSupportedCompressedPixelTransferSyntaxes
: useJPEGLSTransferSyntaxes
JPEG2000CompressedPixelTransferSyntaxes
: useJPEG2000TransferSyntaxes
RLECompressedLosslessSyntaxes
: useRLETransferSyntaxes
UncompressedPixelTransferSyntaxes
: useUncompressedTransferSyntaxes
PILSupportedCompressedPixelTransferSyntaxes
The
PersonNameUnicode
class has been removed, usePersonName
instead.The
DataElement.description
attribute has been removed, useDataElement.name
instead.The
pixel_data_handlers.rle_handler.rle_encode_frame
function has been removed, useDataset.compress()
orRLELosslessEncoder
instead.The
_storage_sopclass_uids
module has been removed, import UIDs from theuid
module instead.The following properties have been removed:
Dataset.parent
andDataset.parent_seq
Sequence.parent
andSequence.parent_dataset
DataElement.parent
The
overlay_data_handlers
module has been removed, use theoverlays
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#
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
UID
via theset_private_encoding()
method.Added the ability to register private transfer syntaxes with
register_transfer_syntax()
so they can be used when reading datasets withdcmread()
.Warning messages are also sent to the pydicom logger (#1529).
Added the following to the
encaps
module: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
bytes
or any Python object withread()
,seek()
andtell()
methods such asio.BytesIO
,BinaryIO
ormmap.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
pixels
module and a new more flexible backend for decoding pixel data viaDecoder
factory 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
ndarray
or 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
ndarray
from a path to a dataset while minimizing memory-usage:pixel_array()
anditer_pixels()
.Added two functions for compressing and decompressing datasets using the new decoding backend:
compress()
anddecompress()
.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 usingDataset.pixel_array
with the newpixels
backend.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 inpydicom.sr
(#1021).Refactored the interface for the concepts in
pydicom.sr
to simplify the access types (#1454).Added the
Dataset.set_pixel_data()
method andset_pixel_data()
function for automatically setting a dataset’s Pixel Data and related Image Pixel module elements using anndarray
(#50).Added typing support for
Dataset
element access using the types-pydicom package. (#1485).Added
apply_presentation_lut()
for applying a Presentation LUT to anndarray
(#1265).Added
apply_icc_profile()
andcreate_icc_transform()
for applying ICC profiles to anndarray
(#1244).Added
Dataset.update_raw_element()
to make it easier to modify aRawDataElement
’s VR or value prior to conversion to aDataElement
(#1739).Added support for using
io.BufferedIOBase
subclasses to set the value for elements with O* VRs such as OB and OW (#1913).Added
encapsulate_buffer()
andencapsulate_extended_buffer()
for encapsulating buffered compressed Pixel Data viaEncapsulatedBuffer
instances.Added elements with OB, OD, OF, OL, OW, OV VRs to the type validation checking when setting
DataElement
values (#1414).Added
convert_raw_data_element()
for converting raw element data toDataElement
instances.Added the
hooks
module which contains an interface for adding callback functions via theHooks
singleton, as well as default and alternative convenience callbacks forconvert_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_CORRECTIONS
isTrue
(#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 aFileSet
(#1922).Fixed an
AttributeError
when runningdeepcopy()
afterDataset.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
andrle
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 havingscheme_designator
set toSRT
but not being included in theSRT
toSCT
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 usingcopy.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_endian
andDataset.is_implicit_VR
will be removed in v4.0.Dataset.read_little_endian
andDataset.read_implicit_vr
will be removed in v4.0, useDataset.original_encoding
instead.Dataset.read_encoding
will be removed in v4.0, useDataset.original_character_set
instead.The write_like_original optional argument to
Dataset.save_as
anddcmwrite()
will be removed in v4.0, use enforce_file_format instead.The following
encaps
module functions will be removed in v4.0:get_frame_offsets()
, useparse_basic_offsets()
instead.generate_pixel_data_fragment()
, usegenerate_fragments()
instead.generate_pixel_data_frame()
, usegenerate_fragmented_frames()
instead.generate_pixel_data()
, usegenerate_frames()
instead.decode_data_sequence()
, usegenerate_fragments()
instead.defragment_data()
, usegenerate_frames()
instead.read_item()
, usegenerate_fragments()
instead.
The
pydicom.pixel_data_handlers
module will be removed in v4.0. All pixel data processing will use thepydicom.pixels
module instead starting with v3.0.The following functions from
pydicom.pixel_data_handlers.util
have been moved topydicom.pixels.processing
:The following functions from
pydicom.pixel_data_handlers.util
have been moved topydicom.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, useDataset.pixel_array_options()
instead.DataElement_from_raw()
will be removed in v4.0, please useconvert_raw_data_element()
instead.config.data_element_callback
andconfig.data_element_callback_kwargs
will be removed in v4.0, please use the hooks forconvert_raw_data_element()
instead.The
pydicom.utils.fixers
submodule will be removed in v4.0, please use the alternative callbacks forconvert_raw_data_element()
in thehooks
module instead.
Pydicom Internals#
Repository folder structure refactored.
Renamed top level
source
folder toutil
.New CI tools - dependabot, and pre-commit using black and ruff.