o
    i&                    @   sV  U d Z ddlmZmZmZ ddlZddlZddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZmZmZ zddlZdZW n eyH   d	ZY nw dd
lmZ ddlmZ ddlmZmZ ddlmZ ddl m!Z! ddl"m#Z#m$Z$m%Z%m&Z&m'Z' ddl(m)Z) erddl*m+Z+ ddl,m-Z- e.e/Z0dd e1 D Z2dddddddddd	Z3dd e34 D d d!hB Z5d"d#d$d%Z6d&d' e7d(D Z8e9e:e;f e<d)< h d*Z=d+d e7d,d-D Z>ed.j
Z?d/ed0e@e!e:B  d1ed2eAd3e9eBef f fd4d5ZCd6d3d1ed2e9eBef fd7d8ZD	d~d9d	ddddd:d6d3d;eBd<d=d>eBd?eEd@eEdAe:dB dBe@eF dB dCe@eF dB d1ed2d3fdDdEZGddd9dFd6d3dGeEd@eEdHeBd1ed2d3fdIdJZHdKede:d2e;fdLdMZIdd6d3dOeBd2e:fdPdQZJd6d3d2e9eBe:f fdRdSZKdTe;d2e9eBef fdUdVZLdKe;d2e9eBef fdWdXZMdd6d3dYeEd2e:fdZd[ZNdddd	d9d\dKd]d^d_d0e@e!e:B  dB d`ee: dB daeEdHeBd1ed2edb fdcddZOdd<dbdeeEd2e;fdfdgZPdheBdieAe:djf d2eEfdkdlZQdddd	d9dmdKd]d^d_d0e@e: dB dne:dB daeEdHeBd1ed2dbfdodpZRdd6d3dqeEd2drfdsdtZSddudvZTddwd6d3d<dbdeBde:d@eEd2dfdxdyZUddKe;dzeEd2d{fd|d}ZVdS )z"Utilities for pixel data handling.    )IterableIterator
ByteStringN)Path)unpackStruct	byteorder)BinaryIOAnycastTYPE_CHECKINGTF)default_encoding)DicomDictionary)encapsulateencapsulate_extended)warn_and_log)BaseTag)UIDJPEGLSNearLosslessJPEG2000ExplicitVRLittleEndiangenerate_uid)VR)PathLikeDatasetc                 C   s,   h | ]\}}|d ? dkr|d dkr|qS )   (        ).0kvr!   r!   J/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/pydicom/pixels/utils.py	<setcomp>)   s    &r&   samples_per_pixelphotometric_interpretationplanar_configurationnumber_of_framesrowscolumnsbits_allocatedbits_storedpixel_representation)	i ( i ( i (  ( i ( i ( i ( i( i( c                 C   s   h | ]}|qS r!   r!   r"   r#   r!   r!   r%   r&   9         FloatPixelDataDoubleFloatPixelData	PixelData))     )r8   	   )r8   r   c                 C   s(   i | ]}|t d d t|dD qS )c                 s       | ]}t |V  qd S Nintr"   sr!   r!   r%   	<genexpr>A       z<dictcomp>.<genexpr>08b)bytesreversedr1   r!   r!   r%   
<dictcomp>@   s    rF      _UNPACK_LUT>                                             c                 C   s   h | ]	}|j d ddqS )   big)lengthr	   )to_bytesr"   xr!   r!   r%   r&   V   s    i  i  z>Hfspecific_tagskwargsreturnr   c                 K   s>  ddl m}m}m}m} || dd || }|d|dd}|s&tdt|}|| |j	|j
||d	}	||	_t|	fi |}
||
d< z| d
}t|d
ksRJ W n ty^   tdw d|j
 }|j	rud}t| d|\}}}nt| d|\}}}}|t|
d< t| d| d t||f |
d< |	|
fS )a  Return a dataset from `f` and a corresponding decoding options dict.

    Parameters
    ----------
    f : BinaryIO
        The opened file-like containing the DICOM dataset, positioned at the
        start of the file.
    specific_tags : list[BaseTag | int]
        A list of additional tags to be read from the dataset and possibly
        returned via the `ds_out` dataset.
    kwargs : dict[str, Any]
        Required and optional arguments for the pixel data decoding functions.

    Returns
    -------
    tuple[Dataset, dict[str, Any]]

        * A dataset containing the group 0x0028 elements, the extended offset
          elements (if any) and elements from `specific_tags`.
        * The required and optional arguments for the pixel data decoding
          functions.
    r   )read_preamble_read_file_meta_inforead_dataset_at_pixel_dataT)forcetransfer_syntax_uidTransferSyntaxUIDNzY'transfer_syntax_uid' is required if the dataset in 'src' is not in the DICOM File Format)is_implicit_VRis_little_endian	stop_whenr^   r9   zzThe dataset in 'src' has no 'Pixel Data', 'Float Pixel Data' or 'Double Float Pixel Data' element, no pixel data to decodez><HHLHH2sHpixel_vrL   pixel_keyword)pydicom.filereaderra   rb   rc   rd   
setdefaultgetAttributeErrorr   rh   ri   	file_metaas_pixel_optionsreadlen	Exceptionr   decoder   _PIXEL_KEYWORDS)r]   r^   r_   ra   rb   rc   rd   ru   tsyntaxdsoptsdata
endiannessvrgroupelemrY   r!   r!   r%   _array_commonZ   sN   


r   r}   c                    s    fddt  D }d jvrd|d< |d }t|tr!t|n|}|dv r1td| d d}||d< d	 jv rGd	 jv rG j jf|d
< |	| |S )a  Return a dict containing the image pixel element values from `ds`.

    .. versionadded:: 3.0

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        A dataset containing Image Pixel module elements.
    **kwargs
        A :class:`dict` containing (key, value) pairs to be used to override the
        values taken from `ds`. For example, if ``kwargs = {'rows': 64}`` then
        the returned :class:`dict` will have a 'rows' value of 64 rather than
        whatever ``ds.Rows`` may be.

    Returns
    -------
    dict[str, Any]
        A dictionary which may contain the following keys, depending on which
        elements are present in `ds` and the contents of `kwargs`:

        * `samples_per_pixel`
        * `photometric_interpretation`
        * `planar_configuration`
        * `number_of_frames` (always present)
        * `rows`
        * `columns`
        * `bits_allocated`
        * `bits_stored`
        * `pixel_representation`
    c                    s&   i | ]\}}| j v r| | jqS r!   )_dictvalue)r"   tagattrr}   r!   r%   rF      s     z$as_pixel_options.<locals>.<dictcomp>r0      r*   )Nr   zA value of 'zA' for (0028,0008) 'Number of Frames' is invalid, assuming 1 framer3   extended_offsets)
_IMAGE_PIXELitemsr   
isinstancestrr>   r   ExtendedOffsetTableExtendedOffsetTableLengthsupdate)r}   r_   r~   	nr_framesr!   r   r%   rv      s&   



rv   r    )encoding_pluginencapsulate_extgenerate_instance_uid	jls_errorj2k_crj2k_psnrrf   arrznp.ndarray | Noner   r   r   r   r   r   c                K   s  ddl m}
 ddlm} t D ]}|	|d qt|}||}|js:d	dd |j
D }td|j d	| |tkrF|durF||	d
< |tkrZ|durR||	d< |durZ||	d< |du r| di }|dd}|sptd|jrwtd|j| fd|i|	}nt| fi |	}|j|fd|i|}dd |D }t|}|d d tdd |dd D  }|s|dkrt|\| _| _| _nt|| _| d }d|_tj|_d| _i | _ t!| ds|
 | _"|| j"_#|rt$ }|| _%|| j"_&| S )a  Compress uncompressed pixel data and update `ds` in-place with the
    resulting :dcm:`encapsulated<part05/sect_A.4.html>` codestream.

    .. versionadded:: 3.0

    The dataset `ds` must already have the following
    :dcm:`Image Pixel<part03/sect_C.7.6.3.html>` module elements present
    with correct values that correspond to the resulting compressed
    pixel data:

    * (0028,0002) *Samples per Pixel*
    * (0028,0004) *Photometric Interpretation*
    * (0028,0008) *Number of Frames* (if more than 1 frame will be present)
    * (0028,0010) *Rows*
    * (0028,0011) *Columns*
    * (0028,0100) *Bits Allocated*
    * (0028,0101) *Bits Stored*
    * (0028,0103) *Pixel Representation*

    If *Samples per Pixel* is greater than 1 then the following element
    is also required:

    * (0028,0006) *Planar Configuration*

    This method will add the file meta dataset if none is present and add
    or modify the following elements:

    * (0002,0010) *Transfer Syntax UID*
    * (7FE0,0010) *Pixel Data*

    If the compressed pixel data is too large for encapsulation using a
    basic offset table then an :dcm:`extended offset table
    <part03/sect_C.7.6.3.html>` will also be used, in which case the
    following elements will also be added:

    * (7FE0,0001) *Extended Offset Table*
    * (7FE0,0002) *Extended Offset Table Lengths*

    If `generate_instance_uid` is ``True`` (default) then a new (0008,0018) *SOP
    Instance UID* value will be generated.

    **Supported Transfer Syntax UIDs**

    +-----------------------------------------------+-----------+----------------------------------+
    | UID                                           |  Plugins  | Encoding Guide                   |
    +------------------------+----------------------+           |                                  |
    | Name                   | Value                |           |                                  |
    +========================+======================+===========+==================================+
    | *JPEG-LS Lossless*     |1.2.840.10008.1.2.4.80| pyjpegls  | :doc:`JPEG-LS                    |
    +------------------------+----------------------+           | </guides/encoding/jpeg_ls>`      |
    | *JPEG-LS Near Lossless*|1.2.840.10008.1.2.4.81|           |                                  |
    +------------------------+----------------------+-----------+----------------------------------+
    | *JPEG 2000 Lossless*   |1.2.840.10008.1.2.4.90| pylibjpeg | :doc:`JPEG 2000                  |
    +------------------------+----------------------+           | </guides/encoding/jpeg_2k>`      |
    | *JPEG 2000*            |1.2.840.10008.1.2.4.91|           |                                  |
    +------------------------+----------------------+-----------+----------------------------------+
    | *RLE Lossless*         | 1.2.840.10008.1.2.5  | pydicom,  | :doc:`RLE Lossless               |
    |                        |                      | pylibjpeg,| </guides/encoding/rle_lossless>` |
    |                        |                      | gdcm      |                                  |
    +------------------------+----------------------+-----------+----------------------------------+

    Examples
    --------

    Compress the existing uncompressed *Pixel Data* in place:

    >>> from pydicom import examples
    >>> from pydicom.pixels import compress
    >>> from pydicom.uid import RLELossless
    >>> ds = examples.ct
    >>> compress(ds, RLELossless)
    >>> ds.save_as("ct_rle_lossless.dcm")

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        The dataset to be compressed.
    transfer_syntax_uid : pydicom.uid.UID
        The UID of the :dcm:`transfer syntax<part05/chapter_10.html>` to
        use when compressing the pixel data.
    arr : numpy.ndarray, optional
        Compress the uncompressed pixel data in `arr` and use it
        to set the *Pixel Data*. If `arr` is not used then the existing
        uncompressed *Pixel Data* in the dataset will be compressed instead.
        The :attr:`~numpy.ndarray.shape`, :class:`~numpy.dtype` and
        contents of the array should match the dataset.
    encoding_plugin : str, optional
        Use `encoding_plugin` to compress the pixel data. See the
        :doc:`user guide </guides/user/image_data_compression>` for a list of
        plugins available for each UID and their dependencies. If not
        specified then all available plugins will be tried (default).
    encapsulate_ext : bool, optional
        If ``True`` then force the addition of an extended offset table.
        If ``False`` (default) then an extended offset table
        will be added if needed for large amounts of compressed *Pixel
        Data*, otherwise just the basic offset table will be used.
    generate_instance_uid : bool, optional
        If ``True`` (default) then generate a new (0008,0018) *SOP Instance UID*
        value for the dataset using :func:`~pydicom.uid.generate_uid`, otherwise
        keep the original value.
    jls_error : int, optional
        **JPEG-LS Near Lossless only**. The allowed absolute compression error
        in the pixel values.
    j2k_cr : list[float], optional
        **JPEG 2000 only**. A list of the compression ratios to use for each
        quality layer. There must be at least one quality layer and the
        minimum allowable compression ratio is ``1``. When using multiple
        quality layers they should be ordered in decreasing value from left
        to right. For example, to use 2 quality layers with 20x and 5x
        compression ratios then `j2k_cr` should be ``[20, 5]``. Cannot be
        used with `j2k_psnr`.
    j2k_psnr : list[float], optional
        **JPEG 2000 only**. A list of the peak signal-to-noise ratios (in dB)
        to use for each quality layer. There must be at least one quality
        layer and when using multiple quality layers they should be ordered
        in increasing value from left to right. For example, to use 2
        quality layers with PSNR of 80 and 300 then `j2k_psnr` should be
        ``[80, 300]``. Cannot be used with `j2k_cr`.
    **kwargs
        Optional keyword parameters for the encoding plugin may also be
        present. See the :doc:`encoding plugins options
        </guides/encoding/encoder_plugin_options>` for more information.
    r   FileMetaDataset)get_encoderN
c                 S      g | ]}d | qS z    r!   r?   r!   r!   r%   
<listcomp>      zcompress.<locals>.<listcomp>zThe pixel data encoder for 'zF' is unavailable because all of its plugins are missing dependencies:
r   r   r   ru   rg   r    zUnable to determine the initial compression state of the dataset as there's no (0002,0010) 'Transfer Syntax UID' element in the dataset's 'file_meta' attributez,Only uncompressed datasets may be compressedr   c                 S   s   g | ]}|qS r!   r!   r"   r]   r!   r!   r%   r     r2   r   r9   c                 S   s   g | ]}t |qS r!   rx   r   r!   r!   r%   r     s        r7   T)'pydicom.datasetr   pydicom.pixelsr   r   valuespopr   is_availablejoinmissing_dependenciesRuntimeErrornamer   r   rs   rt   is_compressed
ValueErroriter_encoderv   rx   sumr   r7   r   r   r   is_undefined_lengthr   OB_pixel_array	_pixel_idhasattrru   rg   r   SOPInstanceUIDMediaStorageSOPInstanceUID)r}   rf   r   r   r   r   r   r   r   r_   r   r   optionuidencodermissingru   r|   frame_iteratorr~   encodedr   totalr   instance_uidr!   r!   r%   compress   s    	
&

r   )as_rgbr   decoding_pluginr   r   c                K   s  ddl m} d| vrtd| di }|dd}|s tdt|}|js+td	|d
d}	|	r?| | | j	 g}
n?||}|j
s\ddd |jD }td|j d| |dd |j| f||d|}g }
|D ]\}}|
|	  qrtdd |
D }|dkrtdt|
}|d r|
d | d }ddd |
D |_d|_| jdkrtjntj|_t| j_|rt }|| _|| j_|	s|d | _ t!t"|d dkrt!t"|d  | _#d!| v s|dkr|| _$d| _%i | _&| S )"a
  Perform an in-place decompression of a dataset with a compressed *Transfer
    Syntax UID*.

    .. versionadded:: 3.0

    .. warning::

        This function requires `NumPy <https://numpy.org/>`_ and may require
        the installation of additional packages to perform the actual pixel
        data decoding. See the :doc:`pixel data decompression documentation
        </guides/user/image_data_handlers>` for more information.

    * The dataset's *Transfer Syntax UID* will be set to *Explicit
      VR Little Endian*.
    * The *Pixel Data* will be decompressed in its entirety and the
      *Pixel Data* element's value updated with the uncompressed data,
      padded to an even length.
    * The *Pixel Data* element's VR will be set to **OB** if *Bits
      Allocated* <= 8, otherwise it will be set to **OW**.
    * The :attr:`DataElement.is_undefined_length
      <pydicom.dataelem.DataElement.is_undefined_length>` attribute for the
      *Pixel Data* element will be set to ``False``.
    * Any :dcm:`image pixel<part03/sect_C.7.6.3.html>` module elements may be
      modified as required to match the uncompressed *Pixel Data*.
    * If `generate_instance_uid` is ``True`` (default) then a new (0008,0018) *SOP
      Instance UID* value will be generated.

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        A dataset containing compressed *Pixel Data* to be decoded and the
        corresponding *Image Pixel* module elements, along with a
        :attr:`~pydicom.dataset.FileDataset.file_meta` attribute containing a
        suitable (0002,0010) *Transfer Syntax UID*.
    as_rgb : bool, optional
        if ``True`` (default) then convert pixel data with a YCbCr
        :ref:`photometric interpretation<photometric_interpretation>` such as
        ``"YBR_FULL_422"`` to RGB.
    generate_instance_uid : bool, optional
        If ``True`` (default) then generate a new (0008,0018) *SOP Instance UID*
        value for the dataset using :func:`~pydicom.uid.generate_uid`, otherwise
        keep the original value.
    decoding_plugin : str, optional
        The name of the decoding plugin to use when decoding compressed
        pixel data. If no `decoding_plugin` is specified (default) then all
        available plugins will be tried and the result from the first successful
        one yielded. For information on the available plugins for each
        decoder see the :doc:`API documentation</reference/pixels.decoders>`.
    kwargs : dict[str, Any], optional
        Optional keyword parameters for the decoding plugin may also be
        present. See the :doc:`decoding plugins options
        </guides/decoding/decoder_options>` for more information.

    Returns
    -------
    pydicom.dataset.Dataset
        The dataset `ds` decompressed in-place.
    r   get_decoderr7   zKUnable to decompress as the dataset has no (7FE0,0010) 'Pixel Data' elementru   rg   r    zUnable to determine the initial compression state as there's no (0002,0010) 'Transfer Syntax UID' element in the dataset's 'file_meta' attributez#The dataset is already uncompresseduse_pdhFr   c                 S   r   r   r!   r?   r!   r!   r%   r   4  r   zdecompress.<locals>.<listcomp>z-Unable to decompress as the plugins for the 'z(' decoder are all missing dependencies:
indexN)r   r   c                 s   r;   r<   r   r"   framer!   r!   r%   rA   G  rB   zdecompress.<locals>.<genexpr>r   zUnable to decompress as the length of the uncompressed pixel data will be greater than the maximum allowed by the DICOM StandardrW           c                 s   s    | ]}|V  qd S r<   r!   r   r!   r!   r%   rA   T  s    r9   r(   r'   r   r)   NumberOfFrames)'r   r   rt   rs   r   r   r   convert_pixel_datapixel_arraytobytesr   r   r   r   r   r   
iter_arrayappendr   rx   r   r   BitsAllocatedr   r   OWr   ru   rg   r   r   r   PhotometricInterpretationr   r>   PlanarConfigurationr   r   r   )r}   r   r   r   r_   r   ru   r|   r   r   framesdecoderr   frame_generatorr   image_pixelvalue_lengthr   r   r   r!   r!   r%   
decompress  s   C



r   srcc           
      C   s  |d }t | d d }t|}|d }|d }t|D ]l}| d| | d| }| d| | d| }	| d| | d| |d| | d|< ||d| | d|< |	|d| | d|< | d| | d| |d| | d|< ||d| | d|< |	|d	| | d|< qt|S )
a  Return ``YBR_FULL_422`` data expanded to ``YBR_FULL``.

    Uncompressed datasets with a (0028,0004) *Photometric Interpretation* of
    ``"YBR_FULL_422"`` are subsampled in the horizontal direction by halving
    the number of Cb and Cr pixels (i.e. there are two Y pixels for every Cb
    and Cr pixel). This function expands the ``YBR_FULL_422`` data to remove
    the subsampling and the output is therefore ``YBR_FULL``.

    Parameters
    ----------
    src : bytes or bytearray
        The YBR_FULL_422 pixel data to be expanded.
    bits_allocated : int
        The number of bits used to store each pixel, as given by (0028,0100)
        *Bits Allocated*.

    Returns
    -------
    bytes
        The expanded data (as YBR_FULL).
    r9   rW   r   ro      Nr   r      )rx   	bytearrayrangerD   )
r   r-   n_bytesrY   dststep_srcstep_dstiic_bc_rr!   r!   r%   expand_ybr422o  s   ((r   rD   unitc                 C   s   t t| j}t t| j}t t| j}t t| j}|| | }|t| 9 }|dkr*|S |dkr9|d |d dk }n||d 9 }| jdkrJ|d d }|S )a  Return the expected length (in terms of bytes or pixels) of the *Pixel
    Data*.

    +------------------------------------------------+-------------+
    | Element                                        | Required or |
    +-------------+---------------------------+------+ optional    |
    | Tag         | Keyword                   | Type |             |
    +=============+===========================+======+=============+
    | (0028,0002) | SamplesPerPixel           | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (0028,0004) | PhotometricInterpretation | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (0028,0008) | NumberOfFrames            | 1C   | Optional    |
    +-------------+---------------------------+------+-------------+
    | (0028,0010) | Rows                      | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (0028,0011) | Columns                   | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (0028,0100) | BitsAllocated             | 1    | Required    |
    +-------------+---------------------------+------+-------------+

    Parameters
    ----------
    ds : Dataset
        The :class:`~pydicom.dataset.Dataset` containing the Image Pixel module
        and *Pixel Data*.
    unit : str, optional
        If ``'bytes'`` then returns the expected length of the *Pixel Data* in
        whole bytes and NOT including an odd length trailing NULL padding
        byte. If ``'pixels'`` then returns the expected length of the *Pixel
        Data* in terms of the total number of pixels (default ``'bytes'``).

    Returns
    -------
    int
        The expected length of the *Pixel Data* in either whole bytes or
        pixels, excluding the NULL trailing padding byte for odd length data.
    pixelsr   r9   r   YBR_FULL_422r   rW   )r   r>   RowsColumnsSamplesPerPixelr   get_nr_framesr   )r}   r   r+   r,   r'   r-   rY   r!   r!   r%   get_expected_length  s   '
r   c                    s   g d} fdd|D S )a  Return a dict of the pixel data affecting element's :func:`id` values.

    +------------------------------------------------+
    | Element                                        |
    +-------------+---------------------------+------+
    | Tag         | Keyword                   | Type |
    +=============+===========================+======+
    | (0028,0002) | SamplesPerPixel           | 1    |
    +-------------+---------------------------+------+
    | (0028,0004) | PhotometricInterpretation | 1    |
    +-------------+---------------------------+------+
    | (0028,0006) | PlanarConfiguration       | 1C   |
    +-------------+---------------------------+------+
    | (0028,0008) | NumberOfFrames            | 1C   |
    +-------------+---------------------------+------+
    | (0028,0010) | Rows                      | 1    |
    +-------------+---------------------------+------+
    | (0028,0011) | Columns                   | 1    |
    +-------------+---------------------------+------+
    | (0028,0100) | BitsAllocated             | 1    |
    +-------------+---------------------------+------+
    | (0028,0101) | BitsStored                | 1    |
    +-------------+---------------------------+------+
    | (0028,0103) | PixelRepresentation       | 1    |
    +-------------+---------------------------+------+
    | (7FE0,0008) | FloatPixelData            | 1C   |
    +-------------+---------------------------+------+
    | (7FE0,0009) | DoubleFloatPixelData      | 1C   |
    +-------------+---------------------------+------+
    | (7FE0,0010) | PixelData                 | 1C   |
    +-------------+---------------------------+------+

    Parameters
    ----------
    ds : Dataset
        The :class:`~pydicom.dataset.Dataset` containing the pixel data.

    Returns
    -------
    dict
        A dict containing the :func:`id` values for the elements that affect
        the pixel data.

    )r   r   r   r   r   r   r   
BitsStoredPixelRepresentationr5   r6   r7   c                    s   i | ]}|t t |d qS r<   )idgetattr)r"   kwr   r!   r%   rF     s    z'get_image_pixel_ids.<locals>.<dictcomp>r!   )r}   keywordsr!   r   r%   get_image_pixel_ids  s   -r   
codestreamc              	   C   s  d}ddi}|  dr?d|d< t| }d}||k r?tj| ||d  dd	}| |d |d
  dkr7|d
7 }n||7 }||k szB| ||d  dkrMi W S | |d |d  dkr\i W S | |d  }|d@ ru|d@ d |d< d|d< |W S |d |d< d|d< |W S  ttfy   Y i S w )a  Return a dict containing JPEG 2000 component parameters.

    .. versionadded:: 2.1

    Parameters
    ----------
    codestream : bytes
        The JPEG 2000 (ISO/IEC 15444-1) codestream to be parsed.

    Returns
    -------
    dict
        A dict containing parameters for the first component sample in the
        JPEG 2000 `codestream`, or an empty dict if unable to parse the data.
        Available parameters are ``{"precision": int, "is_signed": bool}``.
    r   jp2Fs      jP  T   ro   rX   r   r9   s   jp2crW   s   Os   Q*         r   	precision	is_signed)
startswithrx   r>   
from_bytes
IndexError	TypeError)r   offsetinfototal_lengthrY   ssizr!   r!   r%   get_j2k_parameters  s<   
	r
  c                 C   s  i }z| dd dkr|W S d}i }| ||d   }t vrPt| |d |d  d }|tv r>| |d |d |  ||< ||d 7 }| ||d   }t vs|rV||d< |d7 }| |d  |d< t| |d |d  d |d	< t| |d |d
  d |d< | |d
  |d< |d7 }g |d< t|d D ]}|d | |  |d7 }q|dkr|W S | ||d  dkr|t| |d |d  d d 7 }| ||d  dks|d| |d  d  7 }| | |d< | |d  |d< W |S  ty   i  Y S w )a  Return a dict containing JPEG or JPEG-LS encoding parameters.

    Parameters
    ----------
    src : bytes
        The JPEG (ISO/IEC 10918-1) or JPEG-LS (ISO/IEC 14495-1) codestream to
        be parsed.

    Returns
    -------
    dict[str, int | dict[bytes, bytes] | list[int]]
        A dict containing JPEG or JPEG-LS encoding parameters or an empty dict
        if unable to parse the data. Available parameters are:

        * ``precision``: int
        * ``height``: int
        * ``width``: int
        * ``components``: int
        * ``component_ids``: list[int]
        * ``app``: dict[bytes: bytes]
        * ``interleave_mode``: int, JPEG-LS only
        * ``lossy_error``: int, JPEG-LS only
    r   rW   s   ro   appr   r   r   height   width
componentsr9   component_idsrV   s   lossy_errorr   interleave_mode)_SOF_UNPACK_SHORT_APPr   r   ry   )r   r  r  app_markersmarkerrY   _r!   r!   r%   _get_jpg_parametersY  sH     
$r  warnc                 C   s,   t | dd}|s|rtd| d d}|S )a  Return NumberOfFrames or 1 if NumberOfFrames is None or 0.

    Parameters
    ----------
    ds : dataset.Dataset
        The :class:`~pydicom.dataset.Dataset` containing the Image Pixel module
        corresponding to the data in `arr`.
    warn : bool
        If ``True`` (the default), a warning is issued if NumberOfFrames
        has an invalid value.

    Returns
    -------
    int
        An integer for the NumberOfFrames or 1 if NumberOfFrames is None or 0
    r   r   zA value of zg for (0028,0008) 'Number of Frames' is non-conformant. It's recommended that this value be changed to 1)r   r   )r}   r  r   r!   r!   r%   r     s   
r   )ds_outr^   indicesrawr   z(str | PathLike[str] | BinaryIO | Datasetr  zDataset | Noner  r  
np.ndarrayc             	   k   s$   ddl m} ddlm} t| |r_| }	t|	di }
|
dd }s&tdz||}W n ty<   td|j	 d	w t
|	fi |}|j|	f|d
||d|}|D ]\}}|V  qUdS t| dsrt| jd
d}|d}ntt| }| }|d t}|dur|rt|nt }|tB ddhB }zit|t|fi |\}	}t||r|	j|_|j|	j  |j|	j |d }z||}W n ty   td|j	 d	w |j|f|d
||d|}|D ]\}}|V  qW t| ds|  dS || dS t| ds|  w || w )a  Yield decoded pixel data frames from `src` as :class:`~numpy.ndarray`.

    .. versionadded:: 3.0

    .. warning::

        This function requires `NumPy <https://numpy.org/>`_ and may require
        the installation of additional packages to perform the actual pixel
        data decompression. See the :doc:`pixel data decompression documentation
        </guides/user/image_data_handlers>` for more information.

    **Memory Usage**

    To minimize memory usage `src` should be the path to the dataset
    or a `file-like object <https://docs.python.org/3/glossary.html#term-file-object>`_
    containing the dataset.

    **Processing**

    The following processing operations on the raw pixel data are always
    performed:

    * Natively encoded bit-packed pixel data for a :ref:`bits allocated
      <bits_allocated>` of ``1`` will be unpacked.
    * Natively encoded pixel data with a :ref:`photometric interpretation
      <photometric_interpretation>` of ``"YBR_FULL_422"`` will
      have it's sub-sampling removed.
    * The output array will be reshaped to the specified dimensions.
    * JPEG-LS or JPEG 2000 encoded data whose signedness doesn't match the
      expected :ref:`pixel representation<pixel_representation>` will be
      converted to match.

    If ``raw = False`` (the default) then the following processing operation
    will also be performed:

    * Pixel data with a :ref:`photometric interpretation
      <photometric_interpretation>` of ``"YBR_FULL"`` or
      ``"YBR_FULL_422"`` will be converted to ``"RGB"``.

    Examples
    --------

    Read a DICOM dataset then iterate through all the pixel data frames::

        from pydicom import dcmread
        from pydicom.pixels import iter_pixels

        ds = dcmread("path/to/dataset.dcm")
        for arr in iter_pixels(ds):
            print(arr.shape)

    Iterate through all the pixel data frames in a dataset while minimizing
    memory usage::

        from pydicom.pixels import iter_pixels

        for arr in iter_pixels("path/to/dataset.dcm"):
            print(arr.shape)

    Iterate through the even frames for a dataset with 10 frames::

        from pydicom.pixels import iter_pixels

        with open("path/to/dataset.dcm", "rb") as f:
            for arr in iter_pixels(f, indices=range(0, 10, 2)):
                print(arr.shape)

    Parameters
    ----------
    src : str | PathLike[str] | file-like | pydicom.dataset.Dataset

        * :class:`str` | :class:`os.PathLike`: the path to a DICOM dataset
          containing pixel data, or
        * file-like: a `file-like object
          <https://docs.python.org/3/glossary.html#term-file-object>`_ in
          'rb' mode containing the dataset.
        * :class:`~pydicom.dataset.Dataset`: a dataset instance
    ds_out : pydicom.dataset.Dataset, optional
        A :class:`~pydicom.dataset.Dataset` that will be updated with the
        non-retired group ``0x0028`` image pixel module elements and the group
        ``0x0002`` file meta information elements from the dataset in `src`.
        **Only available when `src` is a path or file-like.**
    specific_tags : list[int | pydicom.tag.BaseTag], optional
        A list of additional tags from the dataset in `src` to be added to the
        `ds_out` dataset.
    indices : Iterable[int] | None, optional
        If ``None`` (default) then iterate through the entire pixel data,
        otherwise only iterate through the frames specified by `indices`.
    raw : bool, optional
        If ``True`` then yield the decoded pixel data after only
        minimal processing (see the processing section above). If ``False``
        (default) then additional processing may be applied to convert the
        pixel data to it's most commonly used form (such as converting from
        YCbCr to RGB).
    decoding_plugin : str, optional
        The name of the decoding plugin to use when decoding compressed
        pixel data. If no `decoding_plugin` is specified (default) then all
        available plugins will be tried and the result from the first successful
        one yielded. For information on the available plugins for each
        decoder see the :doc:`API documentation</reference/pixels.decoders>`.
    **kwargs
        Optional keyword parameters for controlling decoding are also
        available, please see the :doc:`decoding options documentation
        </guides/decoding/decoder_options>` for more information.

    Yields
    -------
    numpy.ndarray
        A single frame of decoded pixel data with shape:

        * (rows, columns) for single sample data
        * (rows, columns, samples) for multi-sample data

        A writeable :class:`~numpy.ndarray` is yielded by default. For
        native transfer syntaxes with ``view_only=True`` a read-only
        :class:`~numpy.ndarray` will be yielded.
    r   r   r   ru   rg   NmUnable to decode the pixel data as the dataset's 'file_meta' has no (0002,0010) 'Transfer Syntax UID' elementQUnable to decode the pixel data as a (0002,0010) 'Transfer Syntax UID' value of '' is not supportedT)r  validater  r   rw   strictrbr3   r4   rf   )r   r   r   r   r   r   rs   rt   NotImplementedErrorr   rv   r   r   r   resolveopenr   r
   tellseek_DEFAULT_TAGSset_GROUP_0028r   listru   set_original_encodingoriginal_encodingr   r   close)r   r  r^   r  r  r   r_   r   r   r}   ru   r|   r   r~   iteratorr   r  pathr]   file_offsettagsr!   r!   r%   iter_pixels  s   






r6  padc                 C   s   | j dkrdS t| | tstdt| j dkr|  } | j d d r6t| t	d| j d d  } tj
| ddd	} |  }|rRt|d
 rP|d S |S |S )af  Pack a binary :class:`numpy.ndarray` for use with *Pixel Data*.

    Should be used in conjunction with (0028,0100) *Bits Allocated* = 1.

    .. versionchanged:: 2.1

        Added the `pad` keyword parameter and changed to allow `arr` to be
        2 or 3D.

    Parameters
    ----------
    arr : numpy.ndarray
        The :class:`numpy.ndarray` containing 1-bit data as ints. `arr` must
        only contain integer values of 0 and 1 and must have an 'uint'  or
        'int' :class:`numpy.dtype`. For the sake of efficiency it's recommended
        that the length of `arr` be a multiple of 8 (i.e. that any empty
        bit-padding to round out the byte has already been added). The input
        `arr` should either be shaped as (rows, columns) or (frames, rows,
        columns) or the equivalent 1D array used to ensure that the packed
        data is in the correct order.
    pad : bool, optional
        If ``True`` (default) then add a null byte to the end of the packed
        data to ensure even length, otherwise no padding will be added.

    Returns
    -------
    bytes
        The bit packed data.

    Raises
    ------
    ValueError
        If `arr` contains anything other than 0 or 1.

    References
    ----------
    DICOM Standard, Part 5,
    :dcm:`Section 8.1.1<part05/chapter_8.html#sect_8.1.1>` and
    :dcm:`Annex D<part05/chapter_D.html>`
    )r   r   z=Only binary arrays (containing ones or zeroes) can be packed.r   r   r9   u1littlebitorderrW   r   )shapenparray_equalastypeboolr   rx   ravelr   zerospackbitsr   )r   r7  packedr!   r!   r%   	pack_bits  s   
) rE  package_nameminimum_version.c              
   C   s^   zt | d}tdd |jdD |kW S  ty. } zt| W Y d}~dS d}~ww )zlReturn True if `package_name` is available and its version is greater or
    equal to `minimum_version`
    __version__c                 s   r;   r<   r=   r[   r!   r!   r%   rA     rB   z(_passes_version_check.<locals>.<genexpr>.NF)	importlibimport_moduletuplerH  splitry   LOGGERdebug)rF  rG  moduleexcr!   r!   r%   _passes_version_check  s    rR  )r  r^   r   r  r   r   c             	   K   s  ddl m} ddlm} t| |rT| }	t|	di }
|
dd }s%tdz||}W n ty;   td|j	 d	w t
|	fi |}|j|	f|d
||d|d S t| dsgt| jd
d}|d}ntt| }| }|d t}|dur|rt|nt }|tB ddhB }zIt|t|fi |\}	}|d }z||}W n ty   td|j	 d	w |j|f|d
||d|\}}W t| ds|  n|| nt| ds|  w || w t||r|	j|_|j|	j  |j|	j |S )ad  Return decoded pixel data from `src` as :class:`~numpy.ndarray`.

    .. versionadded:: 3.0

    .. warning::

        This function requires `NumPy <https://numpy.org/>`_ and may require
        the installation of additional packages to perform the actual pixel
        data decompression. See the :doc:`pixel data decompression documentation
        </guides/user/image_data_handlers>` for more information.

    **Memory Usage**

    To minimize memory usage `src` should be the path to the dataset
    or a `file-like object <https://docs.python.org/3/glossary.html#term-file-object>`_
    containing the dataset.

    **Processing**

    The following processing operations on the raw pixel data are always
    performed:

    * Natively encoded bit-packed pixel data for a :ref:`bits allocated
      <bits_allocated>` of ``1`` will be unpacked.
    * Natively encoded pixel data with a :ref:`photometric interpretation
      <photometric_interpretation>` of ``"YBR_FULL_422"`` will
      have it's sub-sampling removed.
    * The output array will be reshaped to the specified dimensions.
    * JPEG-LS or JPEG 2000 encoded data whose signedness doesn't match the
      expected :ref:`pixel representation<pixel_representation>` will be
      converted to match.

    If ``raw = False`` (the default) then the following processing operation
    will also be performed:

    * Pixel data with a :ref:`photometric interpretation
      <photometric_interpretation>` of ``"YBR_FULL"`` or
      ``"YBR_FULL_422"`` will be converted to RGB.

    Examples
    --------

     Read a DICOM dataset and return the entire pixel data::

        from pydicom import dcmread
        from pydicom.pixels import pixel_array

        ds = dcmread("path/to/dataset.dcm")
        arr = pixel_array(ds)

    Return the entire pixel data from a dataset while minimizing memory usage::

        from pydicom.pixels import pixel_array

        arr = pixel_array("path/to/dataset.dcm")

    Return the 3rd frame of a dataset containing at least 3 frames while
    minimizing memory usage::

        from pydicom.pixels import pixel_array

        with open("path/to/dataset.dcm", "rb") as f:
            arr = pixel_array(f, index=2)  # 'index' starts at 0

    Parameters
    ----------
    src : str | PathLike[str] | file-like | pydicom.dataset.Dataset

        * :class:`str` | :class:`os.PathLike`: the path to a DICOM dataset
          containing pixel data, or
        * file-like: a `file-like object
          <https://docs.python.org/3/glossary.html#term-file-object>`_ in
          'rb' mode containing the dataset.
        * :class:`~pydicom.dataset.Dataset`: a dataset instance
    ds_out : pydicom.dataset.Dataset, optional
        A :class:`~pydicom.dataset.Dataset` that will be updated with the
        non-retired group ``0x0028`` image pixel module elements and the group
        ``0x0002`` file meta information elements from the dataset in `src`.
        **Only available when `src` is a path or file-like.**
    specific_tags : list[int | pydicom.tag.BaseTag], optional
        A list of additional tags from the dataset in `src` to be added to the
        `ds_out` dataset.
    index : int | None, optional
        If ``None`` (default) then return an array containing all the
        frames in the pixel data, otherwise return only the frame from the
        specified `index`, which starts at 0 for the first frame.
    raw : bool, optional
        If ``True`` then return the decoded pixel data after only
        minimal processing (see the processing section above). If ``False``
        (default) then additional processing may be applied to convert the
        pixel data to it's most commonly used form (such as converting from
        YCbCr to RGB).
    decoding_plugin : str, optional
        The name of the decoding plugin to use when decoding compressed
        pixel data. If no `decoding_plugin` is specified (default) then all
        available plugins will be tried and the result from the first successful
        one returned. For information on the available plugins for each
        decoder see the :doc:`API documentation</reference/pixels.decoders>`.
    **kwargs
        Optional keyword parameters for controlling decoding, please see the
        :doc:`decoding options documentation</guides/decoding/decoder_options>`
        for more information.

    Returns
    -------
    numpy.ndarray
         One or more frames of decoded pixel data with shape:

        * (rows, columns) for single frame, single sample data
        * (rows, columns, samples) for single frame, multi-sample data
        * (frames, rows, columns) for multi-frame, single sample data
        * (frames, rows, columns, samples) for multi-frame, multi-sample data

        A writeable :class:`~numpy.ndarray` is returned by default. For
        native transfer syntaxes with ``view_only=True`` a read-only
        :class:`~numpy.ndarray` will be returned.
    r   r   r   ru   rg   Nr  r   r!  T)r   r"  r  r   rw   r#  r%  r3   r4   rf   )r   r   r   r   r   r   rs   rt   r&  r   rv   as_arrayr   r   r'  r(  r   r
   r)  r*  r+  r,  r-  r   r.  r1  ru   r/  r0  r   r   )r   r  r^   r   r  r   r_   r   r   r}   ru   r|   r   r~   r3  r]   r4  r5  r   r  r!   r!   r%   r     s   










r   as_floatznp.dtypec                 C   s   t stdt| dr| jjd }n| jd }|du r&tdt| j d|sDt	t
| j}|dkr5d}n|dkr<d	}n
td
| dd}t	t
| j}|dkrSd}n|dkrd|d dkrd|t|7 }ntd
| dzt|}W n ty   td| dw |tdkkr|d}|S )a  Return a :class:`numpy.dtype` for the pixel data in `ds`.

    Suitable for use with IODs containing the Image Pixel module (with
    ``as_float=False``) and the Floating Point Image Pixel and Double Floating
    Point Image Pixel modules (with ``as_float=True``).

    +------------------------------------------+------------------+
    | Element                                  | Supported        |
    +-------------+---------------------+------+ values           |
    | Tag         | Keyword             | Type |                  |
    +=============+=====================+======+==================+
    | (0028,0101) | BitsAllocated       | 1    | 1, 8, 16, 32, 64 |
    +-------------+---------------------+------+------------------+
    | (0028,0103) | PixelRepresentation | 1    | 0, 1             |
    +-------------+---------------------+------+------------------+

    Parameters
    ----------
    ds : Dataset
        The :class:`~pydicom.dataset.Dataset` containing the pixel data you
        wish to get the data type for.
    as_float : bool, optional
        If ``True`` then return a float dtype, otherwise return an integer
        dtype (default ``False``). Float dtypes are only supported when
        (0028,0101) *Bits Allocated* is 32 or 64.

    Returns
    -------
    numpy.dtype
        A :class:`numpy.dtype` suitable for containing the pixel data.

    Raises
    ------
    NotImplementedError
        If the pixel data is of a type that isn't supported by either numpy
        or *pydicom*.
    z)Numpy is required to determine the dtype.ru   r   NzeUnable to determine the endianness of the dataset, please set an appropriate Transfer Syntax UID in 'z.file_meta'r   uintr>   zRUnable to determine the data type to use to contain the Pixel Data as a value of 'z3' for '(0028,0103) Pixel Representation' is invalidfloatuint8r9   z-' for '(0028,0100) Bits Allocated' is invalidzThe data type 'z<' needed to contain the Pixel Data is not supported by numpyr9  S)HAVE_NPImportErrorr   ru   _tsyntax_encodingr0  rt   type__name__r   r>   r   r   r   r   r=  dtyper  r&  r	   newbyteorder)r}   rT  ri   
pixel_repr	dtype_strr-   r^  r!   r!   r%   pixel_dtype  sV   &



rb  c                 C   sN  t stdt| }tt| j}|dk rtd| d|dkrA| jj}|dv r+d}n
|dv r2d}n| j	}|dvrAtd| d	tt| j
}tt| j}|dkr~|dkr^||||}|S |dkrl|||||}|S |||||}|dd
dd}|S |dkr|||}|S |dkr||||}|S ||||}|dd
d}|S )a  Return a reshaped :class:`numpy.ndarray` `arr`.

    +------------------------------------------+-----------+----------+
    | Element                                  | Supported |          |
    +-------------+---------------------+------+ values    |          |
    | Tag         | Keyword             | Type |           |          |
    +=============+=====================+======+===========+==========+
    | (0028,0002) | SamplesPerPixel     | 1    | N > 0     | Required |
    +-------------+---------------------+------+-----------+----------+
    | (0028,0006) | PlanarConfiguration | 1C   | 0, 1      | Optional |
    +-------------+---------------------+------+-----------+----------+
    | (0028,0008) | NumberOfFrames      | 1C   | N > 0     | Optional |
    +-------------+---------------------+------+-----------+----------+
    | (0028,0010) | Rows                | 1    | N > 0     | Required |
    +-------------+---------------------+------+-----------+----------+
    | (0028,0011) | Columns             | 1    | N > 0     | Required |
    +-------------+---------------------+------+-----------+----------+

    (0028,0008) *Number of Frames* is required when *Pixel Data* contains
    more than 1 frame. (0028,0006) *Planar Configuration* is required when
    (0028,0002) *Samples per Pixel* is greater than 1. For certain
    compressed transfer syntaxes it is always taken to be either 0 or 1 as
    shown in the table below.

    +---------------------------------------------+-----------------------+
    | Transfer Syntax                             | Planar Configuration  |
    +------------------------+--------------------+                       |
    | UID                    | Name               |                       |
    +========================+====================+=======================+
    | 1.2.840.10008.1.2.4.50 | JPEG Baseline      | 0                     |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.57 | JPEG Lossless,     | 0                     |
    |                        | Non-hierarchical   |                       |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.70 | JPEG Lossless,     | 0                     |
    |                        | Non-hierarchical,  |                       |
    |                        | SV1                |                       |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.80 | JPEG-LS Lossless   | 0                     |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.81 | JPEG-LS Lossy      | 0                     |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.90 | JPEG 2000 Lossless | 0                     |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.4.91 | JPEG 2000 Lossy    | 0                     |
    +------------------------+--------------------+-----------------------+
    | 1.2.840.10008.1.2.5    | RLE Lossless       | 1                     |
    +------------------------+--------------------+-----------------------+

    .. versionchanged:: 2.1

        JPEG-LS transfer syntaxes changed to *Planar Configuration* of 0

    Parameters
    ----------
    ds : dataset.Dataset
        The :class:`~pydicom.dataset.Dataset` containing the Image Pixel module
        corresponding to the data in `arr`.
    arr : numpy.ndarray
        The 1D array containing the pixel data.

    Returns
    -------
    numpy.ndarray
        A reshaped array containing the pixel data. The shape of the array
        depends on the contents of the dataset:

        * For single frame, single sample data (rows, columns)
        * For single frame, multi-sample data (rows, columns, samples)
        * For multi-frame, single sample data (frames, rows, columns)
        * For multi-frame, multi-sample data (frames, rows, columns, samples)

    References
    ----------

    * DICOM Standard, Part 3,
      :dcm:`Annex C.7.6.3.1<part03/sect_C.7.6.3.html#sect_C.7.6.3.1>`
    * DICOM Standard, Part 5, :dcm:`Section 8.2<part05/sect_8.2.html>`
    z-Numpy is required to reshape the pixel array.r   z0Unable to reshape the pixel array as a value of z0 for (0028,0002) 'Samples per Pixel' is invalid.)z1.2.840.10008.1.2.4.50z1.2.840.10008.1.2.4.57z1.2.840.10008.1.2.4.70z1.2.840.10008.1.2.4.80z1.2.840.10008.1.2.4.81z1.2.840.10008.1.2.4.90z1.2.840.10008.1.2.4.91r   )z1.2.840.10008.1.2.5)r   r   z3 for (0028,0006) 'Planar Configuration' is invalid.rW   r   )rY  rZ  r   r   r>   r   r   ru   rg   r   r   r   reshape	transpose)r}   r   r   
nr_samplestransfer_syntaxr)   r+   r,   r!   r!   r%   reshape_pixel_array:  sT   P
		rg  )r   c                C   s   ddl m} ddlm} | dd }s| dd }r-td|j d|j d	|j d
t| ds6| | _	| j	dd}|rK|j
sKtd|j di }	|j|j|j}
}}|jdvsb|jdvrjtd| d|jd|jd|jd|jd|jd|jdi}z|| }W n ty   td| dw |dkr|dvrtd| d| |dkrd|
d fnd|	d< d|dkr|
d n|
d f|	d< d|dkr|
d n|
d f|	d< nN|d vrtd| d!| |
d" |krtd| d#|
 |dkrdnd|
d f|	d< d|dkr|
d n|
d f|	d< d|dkr|
d n|
d f|	d< d|  k r2|jd$ ksBn td%| d&|jjd$  d| | }}|jd'krSdnd|d   }|jd'krfd| d nd|d  d }||k sx||krtd(| d)| d*| d)| d+	d|f|	d,< |dkrd-nd|	d.< d|f|	d/< d|jd$ f|	d0< d|f|	d1< d|d f|	d2< d|jd'krdndf|	d3< |	 D ]!\}\}}|dkrt| || q|d4kr|| v r| |= q||jkr3| }tj|j d d |d5}|ddd6 |ddd7< |ddd6 |ddd7< |ddd6 |ddd7< |ddd6 |ddd7< |}|! }t"|d dkrB|nd8#|d9f| _$| d: }| j%d$krWt&j'nt&j(|_&d;|_)d| _*i | _+|rk|j,rot-| j	_.|r~t/ }|| _0|| j	_1dS dS )<aD
  Use an :class:`~numpy.ndarray` to set a dataset's *Pixel Data* and related
    Image Pixel module elements.

    .. versionadded:: 3.0

    The following :dcm:`Image Pixel<part03/sect_C.7.6.3.3.html#table_C.7-11c>`
    module elements values will be added, updated or removed as necessary:

    * (0028,0002) *Samples per Pixel* using a value corresponding to
      `photometric_interpretation`.
    * (0028,0004) *Photometric Interpretation* from `photometric_interpretation`.
    * (0028,0006) *Planar Configuration* will be added and set to ``0`` if
      *Samples per Pixel* is > 1, otherwise it will be removed.
    * (0028,0008) *Number of Frames* from the array :attr:`~numpy.ndarray.shape`,
      however it will be removed if `arr` only contains a single frame.
    * (0028,0010) *Rows* and (0028,0011) *Columns* from the array
      :attr:`~numpy.ndarray.shape`.
    * (0028,0100) *Bits Allocated* from the array :class:`~numpy.dtype`.
    * (0028,0101) *Bits Stored* and (0028,0102) *High Bit* from `bits_stored`.
    * (0028,0103) *Pixel Representation* from the array :class:`~numpy.dtype`.

    In addition:

    * The *Transfer Syntax UID* will be set to *Explicit VR Little
      Endian* if it doesn't already exist or uses a compressed (encapsulated)
      transfer syntax.
    * If `generate_instance_uid` is ``True`` (default) then the *SOP Instance UID*
      will be added or updated.

    Parameters
    ----------
    ds : pydicom.dataset.Dataset
        The little endian encoded dataset to be modified.
    arr : np.ndarray
        An array with :class:`~numpy.dtype` uint8, uint16, int8 or int16. The
        array must be shaped as one of the following:

        * (rows, columns) for a single frame of grayscale data.
        * (frames, rows, columns) for multi-frame grayscale data.
        * (rows, columns, samples) for a single frame of multi-sample data
          such as RGB.
        * (frames, rows, columns, samples) for multi-frame, multi-sample data.
    photometric_interpretation : str
        The value to use for (0028,0004) *Photometric Interpretation*. Valid values
        are ``"MONOCHROME1"``, ``"MONOCHROME2"``, ``"PALETTE COLOR"``, ``"RGB"``,
        ``"YBR_FULL"``, ``"YBR_FULL_422"``.
    bits_stored : int
        The value to use for (0028,0101) *Bits Stored*. Must be no greater than
        the number of bits used by the :attr:`~numpy.dtype.itemsize` of `arr`.
    generate_instance_uid : bool, optional
        If ``True`` (default) then add or update the (0008,0018) *SOP Instance
        UID* element with a value generated using :func:`~pydicom.uid.generate_uid`.
    r   r   )r   i Ni	 zThe dataset has an existing z 'zv' element which indicates the (0008,0016) 'SOP Class UID' value is not suitable for a dataset with 'Pixel Data'. The 'z<' element should be deleted and the 'SOP Class UID' changed.ru   rg   zThe dataset's transfer syntax 'z'' is big-endian, which is not supported)ui)r   rW   zUnsupported ndarray dtype 'z'', must be int8, int16, uint8 or uint16r   r   z0Unsupported 'photometric_interpretation' value '')rW   r   zAn ndarray with 'z(' data must have 2 or 3 dimensions, not +)-Nr   r   rW   r   )r   ro   z(' data must have 3 or 4 dimensions, not r   zM' data must have shape (rows, columns, 3) or (frames, rows, columns, 3), not r9   zInvalid 'bits_stored' value 'zc', must be greater than 0 and less than or equal to the number of bits for the ndarray's itemsize 'rh  z$The range of values in the ndarray [z, z;] is greater than that allowed by the 'bits_stored' value []r   )rk  r   r   r   r   r   HighBitr   rl  r^  r   ro   r   r   r7   F)2r   r   pydicom.pixels.commonr   rs   rt   r   r   r   ru   ri   r&  r<  ndimr^  kinditemsizer   MONOCHROME1MONOCHROME2PALETTE_COLORRGBYBR_FULLr   KeyErrorminmaxr   setattrrA  r=  emptysizer   rx   r   r7   r   r   r   r   r   r   r   r   r   rg   r   r   r   )r}   r   r(   r.   r   r   PIr   r|   changesr<  rq  r^  interpretationsre  
actual_min
actual_maxallowed_minallowed_maxkeyword	operationr   outr   r   r!   r!   r%   set_pixel_data  s   = 


 """ 
&
&r  rS  znp.ndarray | bytesc                 C   sN   t rtj| dd}tj|dd}|r|S | S |rtddttj	| S )a  Unpack the bit-packed data in `src`.

    Suitable for use when (0028,0011) *Bits Allocated* or (60xx,0100) *Overlay
    Bits Allocated* is 1.

    If `NumPy <https://numpy.org/>`_ is available then it will be used to
    unpack the data, otherwise only the standard library will be used, which
    is about 20 times slower.

    .. versionchanged:: 2.3

        Added the `as_array` keyword parameter, support for unpacking
        without NumPy, and added :class:`bytes` as a possible return type

    Parameters
    ----------
    src : bytes
        The bit-packed data.
    as_array : bool, optional
        If ``False`` then return the unpacked data as :class:`bytes`, otherwise
        return a :class:`numpy.ndarray` (default, requires NumPy).

    Returns
    -------
    bytes or numpy.ndarray
        The unpacked data as an :class:`numpy.ndarray` (if NumPy is available
        and ``as_array == True``) or :class:`bytes` otherwise.

    Raises
    ------
    ValueError
        If `as_array` is ``True`` and NumPy is not available.

    References
    ----------
    DICOM Standard, Part 5,
    :dcm:`Section 8.1.1<part05/chapter_8.html#sect_8.1.1>` and
    :dcm:`Annex D<part05/chapter_D.html>`
    r8  ro  r9  r:  z1unpack_bits() requires NumPy if 'as_array = True'r   )
rY  r=  
frombuffer
unpackbitsr   r   r   maprH   __getitem__)r   rS  r   r!   r!   r%   unpack_bits  s   (r  r<   )rD   )T)F)r}   r   r   r  r`   r  )W__doc__collections.abcr   r   r   rJ  loggingpathlibr   structr   r   sysr	   typingr
   r   r   r   numpyr=  rY  rZ  pydicom.charsetr   pydicom._dicom_dictr   pydicom.encapsr   r   pydicom.miscr   pydicom.tagr   pydicom.uidr   r   r   r   r   pydicom.valuerepr   osr   r   r   	getLoggerr]  rN  r   r-  r   keysr+  r{   r   rH   dictr>   rD   __annotations__r  r  r  r.  rL  r   r   rv   r@  rV  r   r   r   r   r   r
  r  r   r6  rE  rR  r   rb  rg  r  r  r!   r!   r!   r%   <module>   sj  



ZA
	


 g
 ,B?=g"
	
 UB
	
 O
j 
 M