a
    d                     @   s`   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ dd	d
Z	dd Z
G dd dZdS )    N)Pool)path)tqdm     F(   c	                    s  t |t |ks,J dt | dt | td|  d| d tdt |  |dsftdt|rtd	| d
 td |r.i  i td| d tt |dd fdd}	t	|}
t
||D ]&\}}|
jtt| |||f|	d q|
  |
    tdt | d |du rtt| |d tj}td|tj|g\}}|j}td| |t | }|d }tj||d}tt |dd|jdd}tt|dd}tt
||D ]\}\}}d d |  |d!}|r& | }| \}}}n$tt| |||\}}}|\}}}||| || d"| d#| d#| d$| d%
 || dkr|  |jdd}q؈  |  |  |  td& dS )'u  Make lmdb from images.

    Contents of lmdb. The file structure is:
    example.lmdb
    ├── data.mdb
    ├── lock.mdb
    ├── meta_info.txt

    The data.mdb and lock.mdb are standard lmdb files and you can refer to
    https://lmdb.readthedocs.io/en/release/ for more details.

    The meta_info.txt is a specified txt file to record the meta information
    of our datasets. It will be automatically created when preparing
    datasets by our provided dataset tools.
    Each line in the txt file records 1)image name (with extension),
    2)image shape, and 3)compression level, separated by a white space.

    For example, the meta information could be:
    `000_00000000.png (720,1280,3) 1`, which means:
    1) image name (with extension): 000_00000000.png;
    2) image shape: (720,1280,3);
    3) compression level: 1

    We use the image name without extension as the lmdb key.

    If `multiprocessing_read` is True, it will read all the images to memory
    using multiprocessing. Thus, your server needs to have enough memory.

    Args:
        data_path (str): Data path for reading images.
        lmdb_path (str): Lmdb save path.
        img_path_list (str): Image path list.
        keys (str): Used for lmdb keys.
        batch (int): After processing batch images, lmdb commits.
            Default: 5000.
        compress_level (int): Compress level when encoding images. Default: 1.
        multiprocessing_read (bool): Whether use multiprocessing to read all
            the images to memory. Default: False.
        n_thread (int): For multiprocessing.
        map_size (int | None): Map size for lmdb env. If None, use the
            estimated size from images. Default: None
    z<img_path_list and keys should have the same length, but got z and zCreate lmdb for z
, save to z...zTotoal images: .lmdb lmdb_path must end with '.lmdb'.Folder  already exists. Exit.r   z+Read images with multiprocessing, #thread: z ...image)totalunitc                    s0   | \} |< |<  d d|  dS )z#get the image data and update pbar.r   zRead N)updateset_description)argkeyZdatasetZpbarZshapes `/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/utils/lmdb_util.pycallbackN   s    
z%make_lmdb_from_imgs.<locals>.callback)argsr   zFinish reading z images.Nr   .pngzData size per image is: 
   map_sizechunkTwritemeta_info.txtwzWrite ascii.png (,) 
z
Finish writing lmdb.)lenprintendswith
ValueErrorospexistssysexitr   r   zipZapply_asyncread_img_workerjoinclosecv2imreadIMREAD_UNCHANGEDimencodeIMWRITE_PNG_COMPRESSIONnbyteslmdbopenbegin	enumerater   r   encodeputr   commit)Z	data_path	lmdb_pathZimg_path_listkeysbatchcompress_levelZmultiprocessing_readZn_threadr   r   poolr   r   img_img_byteZdata_size_per_img	data_sizeenvtxntxt_fileidxkey_bytehr    c	img_shaper   r   r   make_lmdb_from_imgs	   sn    4


 




(rP   c           	      C   s\   t | t j}|jdkr(|j\}}d}n|j\}}}t d|t j|g\}}|||||ffS )a  Read image worker.

    Args:
        path (str): Image path.
        key (str): Image key.
        compress_level (int): Compress level when encoding images.

    Returns:
        str: Image key.
        byte: Image byte.
        tuple[int]: Image shape.
       r   r   )r2   r3   r4   ndimshaper5   r6   )	r   r   rB   rD   rM   r    rN   rE   rF   r   r   r   r/      s    

r/   c                   @   s*   e Zd ZdZdddZdd Zd	d
 ZdS )	LmdbMakera8  LMDB Maker.

    Args:
        lmdb_path (str): Lmdb save path.
        map_size (int): Map size for lmdb env. Default: 1024 ** 4, 1TB.
        batch (int): After processing batch images, lmdb commits.
            Default: 5000.
        compress_level (int): Compress level when encoding images. Default: 1.
            r   r   c                 C   s   | dstdt|r6td| d td || _|| _|| _	t
j||d| _| jjdd| _tt|d	d
| _d| _d S )Nr   r	   r
   r   r   r   Tr   r   r    r   )r(   r)   r*   r+   r'   r,   r-   r?   rA   rB   r8   r9   rH   r:   rI   r0   rJ   counter)selfr?   r   rA   rB   r   r   r   __init__   s    


zLmdbMaker.__init__c                 C   s   |  j d7  _ |d}| j|| |\}}}| j| d| d| d| d| j d
 | j | j dkr| j  | j	j
dd	| _d S )
Nr   r!   r"   r#   r$   r%   r   Tr   )rV   r<   rI   r=   rJ   r   rB   rA   r>   rH   r:   )rW   rF   r   rO   rL   rM   r    rN   r   r   r   r=      s    

,
zLmdbMaker.putc                 C   s"   | j   | j  | j  d S )N)rI   r>   rH   r1   rJ   )rW   r   r   r   r1      s    

zLmdbMaker.closeN)rU   r   r   )__name__
__module____qualname____doc__rX   r=   r1   r   r   r   r   rT      s   

rT   )r   r   Fr   N)r2   r8   r,   multiprocessingr   osr   r*   r   rP   r/   rT   r   r   r   r   <module>   s        
{