o
    i2&                     @   s   d Z ddlmZmZmZ zddlZdZW n ey   dZY nw ddl	m
Z
 ddlmZ er:ddlmZ dd	lmZ d
ZddiZdefddZddeeef dedefddZdeeef ddddfddZdddeddfddZdS )a  Use the `numpy <https://numpy.org/>`_ package to convert supported *Overlay
Data* to a :class:`numpy.ndarray`.

**Supported data**

The numpy handler supports the conversion of data in the (60xx,3000)
*Overlay Data* element to a :class:`~numpy.ndarray` provided the
related :dcm:`Overlay Plane<part03/sect_C.9.2.html>` and :dcm:`Multi-frame
Overlay<part03/sect_C.9.3.html>` module elements have values given in the
table below.

+------------------------------------------------+--------------+
| Element                                        | Supported    |
+-------------+---------------------------+------+ values       |
| Tag         | Keyword                   | Type |              |
+=============+===========================+======+==============+
| (60xx,0010) | OverlayRows               | 1    | N > 0        |
+-------------+---------------------------+------+--------------+
| (60xx,0011) | OverlayColumns            | 1    | N > 0        |
+-------------+---------------------------+------+--------------+
| (60xx,0015) | NumberOfFramesInOverlay   | 1    | N > 0        |
+-------------+---------------------------+------+--------------+
| (60xx,0100) | OverlayBitsAllocated      | 1    | 1            |
+-------------+---------------------------+------+--------------+
| (60xx,0102) | OverlayBitPosition        | 1    | 0            |
+-------------+---------------------------+------+--------------+

    )TYPE_CHECKINGcastAnyNTF)warn_and_log)unpack_bits)Dataset)DataElementzNumpy Overlaynumpy)zhttps://numpy.org/NumPyreturnc                   C   s   t S )z8Return ``True`` if the handler has its dependencies met.)HAVE_NP r   r   T/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/pydicom/overlays/numpy_handler.pyis_available4   s   r   byteselemunitc                 C   s<   | d | d  }|| d 9 }|dkr|S |d |d dk S )aV  Return the expected length (in terms of bytes or pixels) of the *Overlay
    Data*.

    +------------------------------------------------+-------------+
    | Element                                        | Required or |
    +-------------+---------------------------+------+ optional    |
    | Tag         | Keyword                   | Type |             |
    +=============+===========================+======+=============+
    | (60xx,0010) | OverlayRows               | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (60xx,0011) | OverlayColumns            | 1    | Required    |
    +-------------+---------------------------+------+-------------+
    | (60xx,0015) | NumberOfFramesInOverlay   | 1    | Required    |
    +-------------+---------------------------+------+-------------+

    Parameters
    ----------
    elem : dict
        A :class:`dict` with the keys as the element keywords and values the
        corresponding element values (such as ``{'OverlayRows': 512, ...}``)
        for the elements listed in the table above.
    unit : str, optional
        If ``'bytes'`` then returns the expected length of the *Overlay Data*
        in whole bytes and NOT including an odd length trailing NULL padding
        byte. If ``'pixels'`` then returns the expected length of the *Overlay
        Data* in terms of the total number of pixels (default ``'bytes'``).

    Returns
    -------
    int
        The expected length of the *Overlay Data* in either whole bytes or
        pixels, excluding the NULL trailing padding byte for odd length data.
    OverlayRowsOverlayColumnsNumberOfFramesInOverlaypixels   r   r   )r   r   lengthr   r   r   get_expected_length9   s
   "r   arr
np.ndarrayc                 C   s^   t std| d }| d }| d }|dk rtd| d|dkr)||||S |||S )an  Return a reshaped :class:`numpy.ndarray` `arr`.

    +------------------------------------------------+--------------+
    | Element                                        | Supported    |
    +-------------+---------------------------+------+ values       |
    | Tag         | Keyword                   | Type |              |
    +=============+===========================+======+==============+
    | (60xx,0010) | OverlayRows               | 1    | N > 0        |
    +-------------+---------------------------+------+--------------+
    | (60xx,0011) | OverlayColumns            | 1    | N > 0        |
    +-------------+---------------------------+------+--------------+
    | (60xx,0015) | NumberOfFramesInOverlay   | 1    | N > 0        |
    +-------------+---------------------------+------+--------------+

    Parameters
    ----------
    elem : dict
        A :class:`dict` with the keys as the element keywords and values the
        corresponding element values (such as ``{'OverlayRows': 512, ...}``)
        for the elements listed in the table above.
    arr : numpy.ndarray
        A 1D array containing the overlay data.

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

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

    References
    ----------

    * DICOM Standard, Part 3, Sections :dcm:`C.9.2<part03/sect_C.9.2.html>`
      and :dcm:`C.9.3<part03/sect_C.9.3.html>`
    * DICOM Standard, Part 5, :dcm:`Section 8.2<part05/sect_8.2.html>`
    z/Numpy is required to reshape the overlay array.r   r   r      z2Unable to reshape the overlay array as a value of z: for (60xx,0015) 'Number of Frames in Overlay' is invalid.)r   ImportError
ValueErrorreshape)r   r   	nr_framesnr_rows
nr_columnsr   r   r   reshape_overlay_arrayg   s   (
r#   dsr   groupc                 C   sZ  t std| |dfd| |dfd| |dfd| |dfdd}dd	 | D }|r:td
d| dd | D }| |dfd}|du rTd|d< n|j|d< t|}tt	t
|d }||d  }||k r||krytd ntd| d| d||krtd| d||  d t|dd}	t	dt|d d|	 }
t||
S )a  Return a :class:`numpy.ndarray` of the *Overlay Data*.

    Parameters
    ----------
    ds : Dataset
        The :class:`Dataset` containing an Overlay Plane module and the
        *Overlay Data* to be converted.
    group : int
        The group part of the *Overlay Data* element tag, e.g. ``0x6000``,
        ``0x6010``, etc. Must be between 0x6000 and 0x60FF.

    Returns
    -------
    np.ndarray
        The contents of (`group`,3000) *Overlay Data* as an array.

    Raises
    ------
    AttributeError
        If `ds` is missing a required element.
    ValueError
        If the actual length of the overlay data doesn't match the expected
        length.
    z'The overlay data handler requires numpyi 0  N         )OverlayDataOverlayBitsAllocatedr   r   c                 S   s   g | ]
\}}|d u r|qS )Nr   .0kkvvr   r   r   
<listcomp>   s    z%get_overlay_array.<locals>.<listcomp>zdUnable to convert the overlay data as the following required elements are missing from the dataset: z, c                 S   s   i | ]\}}||j qS r   )valuer+   r   r   r   
<dictcomp>   s    z%get_overlay_array.<locals>.<dictcomp>   r   r   r)      z9The overlay data length is odd and misses a padding byte.z/The length of the overlay data in the dataset (z+ bytes) doesn't match the expected length (z] bytes). The dataset may be corrupted or there may be an issue with the overlay data handler.z. bytes) indicates it contains excess padding. z/ bytes will be removed from the end of the datar   )r   r   )r   r   getitemsAttributeErrorjoinr0   r   lenr   r   r   r   r   r#   )r$   r%   r   missingelem_valuesr    expected_lenactual_lengthpadded_expected_len	nr_pixelsr   r   r   r   get_overlay_array   sR   



r?   )r   )__doc__typingr   r   r   r	   npr   r   pydicom.miscr   pydicom.pixels.utilsr   pydicom.datasetr   pydicom.dataelemr   HANDLER_NAMEDEPENDENCIESboolr   dictstrintr   r#   r?   r   r   r   r   <module>   s&    .;