B
    •%Z\Å`  ã               @   s
  d Z ddlmZmZmZ ddlZddlZ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 e e¡ZdZd	Zd
ZdZdZdZdZdZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZeeeedœZ ddddgZ!dd „ Z"e"ƒ  dS )!z Lytro Illum Plugin.
    Plugin to read Lytro Illum .lfr and .raw files as produced
    by the Lytro Illum light field camera.
é    )Úabsolute_importÚprint_functionÚdivisionNé   )Úformats)ÚFormat)Úimread)iø  i0  )iÐ  iÐ  é   é   é-   é#   é   é   c               @   s.   e Zd ZdZdZdd„ ZG dd„ dejƒZdS )ÚLytroFormata   Base class for Lytro format.
    The subclasses LytroLfrFormat, LytroLfpFormat, LytroIllumRawFormat and
    LytroF01RawFormat implement the Lytro-LFR, Lytro-LFP and Lytro-RAW format
    for the Illum and original F01 camera respectively.
    Writing is not supported.
    Úic             C   s   dS )NF© )ÚselfÚrequestr   r   ú4lib/python3.7/site-packages/imageio/plugins/lytro.pyÚ
_can_write>   s    zLytroFormat._can_writec               @   s.   e Zd Zddd„Zdd„ Zdd„ Zdd	„ Zd
S )zLytroFormat.Writerr   c             C   s   | j  ¡ | _d S )N)r   Úget_fileZ_fp)r   Úflagsr   r   r   Ú_openE   s    zLytroFormat.Writer._openc             C   s   d S )Nr   )r   r   r   r   Ú_closeH   s    zLytroFormat.Writer._closec             C   s   t dƒ‚d S )Nz)The lytro format cannot write image data.)ÚRuntimeError)r   ÚimÚmetar   r   r   Ú_append_dataM   s    zLytroFormat.Writer._append_datac             C   s   t dƒ‚d S )Nz(The lytro format cannot write meta data.)r   )r   r   r   r   r   Ú_set_meta_dataQ   s    z!LytroFormat.Writer._set_meta_dataN)r   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   ÚWriterD   s   
r"   N)r   r    r!   Ú__doc__Z_modesr   r   r"   r   r   r   r   r   3   s   r   c               @   s6   e Zd ZdZdd„ Zedd„ ƒZG dd„ dejƒZdS )	ÚLytroIllumRawFormatak   This is the Lytro Illum RAW format.
    The raw format is a 10bit image format as used by the Lytro Illum
    light field camera. The format will read the specified raw file and will
    try to load a .txt or .json file with the associated meta data.
    This format does not support writing.


    Parameters for reading
    ----------------------
    None
    c             C   s&   |j d | jd kr"|jdkr"dS d S )Né   ú?)z.rawT)ÚmodeÚmodesÚ	extension)r   r   r   r   r   Ú	_can_readd   s    
zLytroIllumRawFormat._can_readc             C   s’  | dd d… }| dd d… }| dd d… }| dd d… }| dd d… }t  |d¡t  |d¡ }t  |d¡t  t  |d¡d¡ }t  |d¡t  t  |d¡d¡ }t  |d¡t  t  |d	¡d
¡ }t jtt jd}| td td d f¡|d d …dd d…f< | td td d f¡|d d …dd d…f< | td td d f¡|d d …dd d…f< | td td d f¡|d d …dd d…f< t  |d¡ 	t j
¡S )Nr   é   r%   r   r   r
   r	   é0   éÀ   é   )Údtypeg     ø@)ÚnpÚ
left_shiftÚbitwise_andÚright_shiftÚzerosÚLYTRO_ILLUM_IMAGE_SIZEÚuint16ÚreshapeÚdivideÚastypeÚfloat64)ÚarrayÚt0Út1Út2Zt3ZlsbÚimager   r   r   Úrearrange_bitsj   s&       ((((z"LytroIllumRawFormat.rearrange_bitsc               @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )zLytroIllumRawFormat.Readerc             C   s   | j  ¡ | _d | _d S )N)r   r   Ú_fileÚ_data)r   r   r   r   r   Ž   s    z LytroIllumRawFormat.Reader._openc             C   s   | ` d S )N)rB   )r   r   r   r   r   ’   s    z!LytroIllumRawFormat.Reader._closec             C   s   dS )Nr%   r   )r   r   r   r   Ú_get_length—   s    z&LytroIllumRawFormat.Reader._get_lengthc             C   sZ   |dkrt dƒ‚| jd kr&| j ¡ | _tj| jtjd tj¡}t	 
|¡}|| jddfS )N)r   ÚNonez$Lytro file contains only one dataset)r/   r   )Úindex)Ú
IndexErrorrB   rA   Úreadr0   Ú
frombufferÚuint8r9   r6   r$   r@   Ú_get_meta_data)r   rE   ÚrawÚimgr   r   r   Ú	_get_data›   s    

z$LytroIllumRawFormat.Reader._get_datac             C   sx   |dkrt dƒ‚tj | j ¡ ¡d }d }x.dD ]&}tj || ¡r0t t	|| ƒ¡}q0W |d k	rf|S t
 d¡ i S d S )N)r   Nz.Lytro meta data file contains only one datasetr   )z.txtz.TXTz.jsonz.JSONz-No metadata file found for provided raw file.)rF   ÚosÚpathÚsplitextr   Úget_local_filenameÚisfileÚjsonÚloadÚopenÚloggerÚwarning)r   rE   Úfilename_baseÚ	meta_dataÚextr   r   r   rJ   ®   s    

z)LytroIllumRawFormat.Reader._get_meta_dataN)r   r    r!   r   r   rC   rM   rJ   r   r   r   r   ÚReader   s
   r[   N)	r   r    r!   r#   r*   Ústaticmethodr@   r   r[   r   r   r   r   r$   W   s   #r$   c               @   s*   e Zd ZdZdd„ ZG dd„ dejƒZdS )ÚLytroLfrFormata-   This is the Lytro Illum LFR format.
    The lfr is a image and meta data container format as used by the
    Lytro Illum light field camera.
    The format will read the specified lfr file.
    This format does not support writing.

    Parameters for reading
    ----------------------
    None
    c             C   s&   |j d | jd kr"|jdkr"dS d S )Nr%   r&   )z.lfrT)r'   r(   r)   )r   r   r   r   r   r*   Ó   s    
zLytroLfrFormat._can_readc               @   sT   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )zLytroLfrFormat.Readerc       
      C   sÚ  | j  ¡ | _d | _i | _i | _d | _|  ¡  |  ¡  |  	¡  yx| jd d d }|d | jkr<|d | jkr<|d | jkr<| j|d  \}}| j 
|d¡ | j |¡| _| j|d  \}}| j 
|d¡ | j |¡}t | d¡¡| jd< | j|d  \}}| j 
|d¡ | j |¡}t | d¡¡| _| j| jd	< | jd
 d }|d | jkr´| j|d  \}}| j 
|d¡ | j |¡}t|dd}|d }|d }	|||	dœ| jd< W n tk
rÔ   tdƒ‚Y nX d S )NZframesr   ÚframeÚmetadataRefÚimageRefÚprivateMetadataRefÚASCIIÚmetadataÚprivateMetadataZ
thumbnailsZjpeg)ÚformatÚheightÚwidth)r?   rf   rg   Z	thumbnailz+The specified file is not a valid LFR file.)r   r   rA   rB   Ú_chunksrc   Ú_contentÚ_find_headerÚ_find_chunksÚ
_find_metaÚseekrG   Úraw_image_datarS   ÚloadsÚdecodeÚserial_numbersr   ÚKeyErrorr   )
r   Ú
chunk_dictÚdata_posÚsizerc   rq   Zthumbnail_dataZthumbnail_imgZthumbnail_heightZthumbnail_widthr   r   r   r   Ü   sL    zLytroLfrFormat.Reader._openc             C   s   | ` d S )N)rB   )r   r   r   r   r     s    zLytroLfrFormat.Reader._closec             C   s   dS )Nr%   r   )r   r   r   r   rC      s    z!LytroLfrFormat.Reader._get_lengthc             C   s0   d}| j  t¡}||kr tdƒ‚| j  t¡ dS )zH
            Checks if file has correct header and skip it.
            s   ‰LFP

   zThe LFR file header is invalid.N)rA   rG   ÚHEADER_LENGTHr   ÚSIZE_LENGTH)r   Úfile_headerÚheaderr   r   r   rj   $  s
    z"LytroLfrFormat.Reader._find_headerc             C   s:   d}x0t dtƒD ]"}|  |¡\}}}||f| j|< qW dS )zN
            Gets start position and size of data chunks in file.
            s   ‰LFC

    r   N)ÚrangeÚDATA_CHUNKS_ILLUMÚ
_get_chunkrh   )r   Úchunk_headerr   rt   ru   Úsha1r   r   r   rk   1  s    z"LytroLfrFormat.Reader._find_chunksc             C   sD   d}|   |¡\}}}| j |d¡ | j |¡}t | d¡¡| _dS )zt
            Gets a data chunk that contains information over content
            of other data chunks.
            s   ‰LFM

    r   rb   N)r|   rA   rm   rG   rS   ro   rp   ri   )r   Úmeta_headerrt   ru   r~   Údatar   r   r   rl   ;  s
    z LytroLfrFormat.Reader._find_metac             C   s¼   | j  t¡}||krtdƒ‚d}d}t d| j  t¡¡d }|dkr²t| j  t¡ 	d¡ƒ}| j  t
¡ | j  ¡ }| j  |d¡ | j  d¡}x|dkr¢| j  d¡}qŒW | j  dd¡ |||fS )	a_  
            Checks if chunk has correct header and skips it.
            Finds start position and length of next chunk and reads
            sha1-string that identifies the following data chunk.

            Parameters
            ----------
            header : bytes
                Byte string that identifies start of chunk.

            Returns
            -------
                data_pos : int
                    Start position of data chunk in file.
                size : int
                    Size of data chunk.
                sha1 : str
                    Sha1 value of chunk.
            z The LFR chunk header is invalid.Nz>ir   rb   r%   ó    éÿÿÿÿ)rA   rG   rv   r   ÚstructÚunpackrw   ÚstrÚSHA1_LENGTHrp   ÚPADDING_LENGTHÚtellrm   )r   ry   Úheader_chunkrt   r~   ru   Úchr   r   r   r|   H  s     

z LytroLfrFormat.Reader._get_chunkc             C   s>   |dkrt dƒ‚tj| jtjd tj¡}t |¡}|| j	fS )N)r   Nz(Lytro lfr file contains only one dataset)r/   )
rF   r0   rH   rn   rI   r9   r6   r$   r@   rc   )r   rE   rK   r   r   r   r   rM   v  s
    
zLytroLfrFormat.Reader._get_datac             C   s   |dkrt dƒ‚| jS )N)r   Nz.Lytro meta data file contains only one dataset)rF   rc   )r   rE   r   r   r   rJ   ‚  s    z$LytroLfrFormat.Reader._get_meta_dataN)r   r    r!   r   r   rC   rj   rk   rl   r|   rM   rJ   r   r   r   r   r[   Û   s   ?
.r[   N)r   r    r!   r#   r*   r   r[   r   r   r   r   r]   Ç   s   
r]   c               @   s6   e Zd ZdZdd„ Zedd„ ƒZG dd„ dejƒZdS )	ÚLytroF01RawFormata†   This is the Lytro RAW format for the original F01 Lytro camera.
    The raw format is a 12bit image format as used by the Lytro F01
    light field camera. The format will read the specified raw file and will
    try to load a .txt or .json file with the associated meta data.
    This format does not support writing.


    Parameters for reading
    ----------------------
    None

    c             C   s&   |j d | jd kr"|jdkr"dS d S )Nr%   r&   )z.rawT)r'   r(   r)   )r   r   r   r   r   r*   ™  s    
zLytroF01RawFormat._can_readc             C   sÞ   | dd d… }| dd d… }| dd d… }t  |d¡t  t  |d¡d¡ }t  t  |d¡d¡| }t jtt jd	}| td td d f¡|d d …dd d…f< | td td d f¡|d d …dd d…f< t  |d
¡ 	t j
¡S )Nr   r   r%   r   r
   éð   é   é   )r/   g     þ¯@)r0   r1   r3   r2   r4   ÚLYTRO_F01_IMAGE_SIZEr6   r7   r8   r9   r:   )r;   r<   r=   r>   Za0Za1r?   r   r   r   r@   Ÿ  s     ((z LytroF01RawFormat.rearrange_bitsc               @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )zLytroF01RawFormat.Readerc             C   s   | j  ¡ | _d | _d S )N)r   r   rA   rB   )r   r   r   r   r   ¹  s    zLytroF01RawFormat.Reader._openc             C   s   | ` d S )N)rB   )r   r   r   r   r   ½  s    zLytroF01RawFormat.Reader._closec             C   s   dS )Nr%   r   )r   r   r   r   rC   Â  s    z$LytroF01RawFormat.Reader._get_lengthc             C   sZ   |dkrt dƒ‚| jd kr&| j ¡ | _tj| jtjd tj¡}t	 
|¡}|| jddfS )N)r   rD   z$Lytro file contains only one dataset)r/   r   )rE   )rF   rB   rA   rG   r0   rH   rI   r9   r6   r‹   r@   rJ   )r   rE   rK   rL   r   r   r   rM   Æ  s    

z"LytroF01RawFormat.Reader._get_datac             C   sx   |dkrt dƒ‚tj | j ¡ ¡d }d }x.dD ]&}tj || ¡r0t t	|| ƒ¡}q0W |d k	rf|S t
 d¡ i S d S )N)r   Nz.Lytro meta data file contains only one datasetr   )z.txtz.TXTz.jsonz.JSONz-No metadata file found for provided raw file.)rF   rN   rO   rP   r   rQ   rR   rS   rT   rU   rV   rW   )r   rE   rX   rY   rZ   r   r   r   rJ   Ù  s    

z'LytroF01RawFormat.Reader._get_meta_dataN)r   r    r!   r   r   rC   rM   rJ   r   r   r   r   r[   ¸  s
   r[   N)	r   r    r!   r#   r*   r\   r@   r   r[   r   r   r   r   r‹   ‹  s   r‹   c               @   s*   e Zd ZdZdd„ ZG dd„ dejƒZdS )ÚLytroLfpFormata+   This is the Lytro Illum LFP format.
    The lfp is a image and meta data container format as used by the
    Lytro F01 light field camera.
    The format will read the specified lfp file.
    This format does not support writing.

    Parameters for reading
    ----------------------
    None
    c             C   s&   |j d | jd kr"|jdkr"dS d S )Nr%   r&   )z.lfpT)r'   r(   r)   )r   r   r   r   r   r*   þ  s    
zLytroLfpFormat._can_readc               @   sT   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )zLytroLfpFormat.Readerc             C   sf  | j  ¡ | _d | _i | _i | _d | _|  ¡  |  ¡  |  	¡  y| jd d d d }|d | jkr@|d | jkr@|d | jkr@| j|d  \}}| j 
|d¡ | j |¡| _| j|d  \}}| j 
|d¡ | j |¡}t | d¡¡| jd	< | j|d  \}}| j 
|d¡ | j |¡}t | d¡¡| _| j| jd
< W n tk
r`   tdƒ‚Y nX d S )NZpictureZ
frameArrayr   r^   r_   r`   ra   rb   rc   rd   z+The specified file is not a valid LFP file.)r   r   rA   rB   rh   rc   ri   rj   rl   rk   rm   rG   rn   rS   ro   rp   rq   rr   r   )r   rs   rt   ru   rc   rq   r   r   r   r     s6    zLytroLfpFormat.Reader._openc             C   s   | ` d S )N)rB   )r   r   r   r   r   2  s    zLytroLfpFormat.Reader._closec             C   s   dS )Nr%   r   )r   r   r   r   rC   7  s    z!LytroLfpFormat.Reader._get_lengthc             C   s0   d}| j  t¡}||kr tdƒ‚| j  t¡ dS )zH
            Checks if file has correct header and skip it.
            s   ‰LFP

   zThe LFP file header is invalid.N)rA   rG   rv   r   rw   )r   rx   ry   r   r   r   rj   ;  s
    z"LytroLfpFormat.Reader._find_headerc             C   s:   d}x0t dtƒD ]"}|  |¡\}}}||f| j|< qW dS )zN
            Gets start position and size of data chunks in file.
            s   ‰LFC

    r   N)rz   ÚDATA_CHUNKS_F01r|   rh   )r   r}   r   rt   ru   r~   r   r   r   rk   I  s    z"LytroLfpFormat.Reader._find_chunksc             C   sP   d}|   |¡\}}}| j |d¡ | j |¡}t | d¡¡| _| j d¡}dS )zt
            Gets a data chunk that contains information over content
            of other data chunks.
            s   ‰LFM

    r   rb   r+   N)r|   rA   rm   rG   rS   ro   rp   ri   )r   r   rt   ru   r~   r€   r   r   r   rl   S  s    z LytroLfpFormat.Reader._find_metac             C   s¼   | j  t¡}||krtdƒ‚d}d}t d| j  t¡¡d }|dkr²t| j  t¡ 	d¡ƒ}| j  t
¡ | j  ¡ }| j  |d¡ | j  d¡}x|dkr¢| j  d¡}qŒW | j  dd¡ |||fS )	a_  
            Checks if chunk has correct header and skips it.
            Finds start position and length of next chunk and reads
            sha1-string that identifies the following data chunk.

            Parameters
            ----------
            header : bytes
                Byte string that identifies start of chunk.

            Returns
            -------
                data_pos : int
                    Start position of data chunk in file.
                size : int
                    Size of data chunk.
                sha1 : str
                    Sha1 value of chunk.
            z The LFP chunk header is invalid.Nz>ir   rb   r%   r   r‚   )rA   rG   rv   r   rƒ   r„   rw   r…   r†   rp   r‡   rˆ   rm   )r   ry   r‰   rt   r~   ru   rŠ   r   r   r   r|   b  s     

z LytroLfpFormat.Reader._get_chunkc             C   s>   |dkrt dƒ‚tj| jtjd tj¡}t |¡}|| j	fS )N)r   Nz(Lytro lfp file contains only one dataset)r/   )
rF   r0   rH   rn   rI   r9   r6   r‹   r@   rc   )r   rE   rK   r   r   r   r   rM     s
    
zLytroLfpFormat.Reader._get_datac             C   s   |dkrt dƒ‚| jS )N)r   Nz.Lytro meta data file contains only one dataset)rF   rc   )r   rE   r   r   r   rJ   œ  s    z$LytroLfpFormat.Reader._get_meta_dataN)r   r    r!   r   r   rC   rj   rk   rl   r|   rM   rJ   r   r   r   r   r[     s   +
.r[   N)r   r    r!   r#   r*   r   r[   r   r   r   r   r   ò  s   
r   )z	lytro-lfrzlytro-illum-rawz	lytro-lfpzlytro-f01-raw)z	LYTRO-LFRzLytro Illum lfr image fileZlfrr   )zLYTRO-ILLUM-RAWzLytro Illum raw image filerK   r   )z	LYTRO-LFPzLytro F01 lfp image fileZlfpr   )zLYTRO-F01-RAWzLytro F01 raw image filerK   r   c              C   sH   xBt D ]:\} }}}t |  ¡ t¡}|r|| |||ƒ}tj|d qW d S )N)re   )Úfile_formatsÚSPECIAL_CLASSESÚgetÚlowerr   r   Z
add_format)ÚnameZdesrZ   r   Zformat_classre   r   r   r   Ú _create_predefined_lytro_formats·  s
    r—   )#r#   Z
__future__r   r   r   rN   rS   rƒ   ZloggingZnumpyr0   Ú r   Zcorer   r   Z	getLoggerr   rV   r5   r   rv   rw   r†   r‡   r{   r‘   r   r$   r]   r‹   r   r“   r’   r—   r   r   r   r   Ú<module>	   sF   
$p Eg 6