B
    %Z\ah                 @   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	m
Z
 ddlmZmZ ddlmZmZ eeZd	ZG d
d deZG dd deZG dd deZdd Zdd Zdd ZdddZd ddZddlmZmZ dZ e!eeeedZ"dd Z#e#  dS )!z+ Plugin that wraps the the Pillow library.
    )absolute_importprint_functiondivisionN   )formats)Formatimage_as_uint   )pillow_formatspillow_docsa  
    Parameters for reading
    ----------------------
    
    pilmode : str
        From the Pillow documentation:
        
        * 'L' (8-bit pixels, grayscale)
        * 'P' (8-bit pixels, mapped to any other mode using a color palette)
        * 'RGB' (3x8-bit pixels, true color)
        * 'RGBA' (4x8-bit pixels, true color with transparency mask)
        * 'CMYK' (4x8-bit pixels, color separation)
        * 'YCbCr' (3x8-bit pixels, color video format)
        * 'I' (32-bit signed integer pixels)
        * 'F' (32-bit floating point pixels)
        
        PIL also provides limited support for a few special modes, including
        'LA' ('L' with alpha), 'RGBX' (true color with padding) and 'RGBa'
        (true color with premultiplied alpha).
        
        When translating a color image to grayscale (mode 'L', 'I' or 'F'),
        the library uses the ITU-R 601-2 luma transform::
        
            L = R * 299/1000 + G * 587/1000 + B * 114/1000
    as_gray : bool
        If True, the image is converted using mode 'F'. When `mode` is
        not None and `as_gray` is True, the image is first converted
        according to `mode`, and the result is then "flattened" using
        mode 'F'.
c                   sx   e Zd ZdZdZdZdZdZ fddZe	dd	 Z
d
d Zdd Zdd ZG dd dejZG dd dejZ  ZS )PillowFormatz/
    Base format class for Pillow formats.
    FNi c                s    t t| j|| t | _d S )N)superr   __init__	threadingRLock_lock)selfargskwargs)	__class__ 5lib/python3.7/site-packages/imageio/plugins/pillow.pyr   E   s    zPillowFormat.__init__c             C   s   | j S )z The PIL plugin id.
        )
_plugin_id)r   r   r   r   	plugin_idJ   s    zPillowFormat.plugin_idc          	   C   s   | j X | jsBd| _dd l}t|ds.tdddlm} || _n| jd krTtd| j}W d Q R X | jdkrx|	  n|
  |S )NTr   __version__z/Imageio Pillow plugin requires Pillow, not PIL!)Imagez*Imageio Pillow plugin requires Pillow lib.)PNGJPEGZBMPGIFZPPM)r   _pillow_importedPILhasattrImportErrorr   _ImageRuntimeErrorr   ZpreinitZinit)r   r"   r   r   r   r   _init_pillowP   s     



zPillowFormat._init_pillowc             C   sT   |   }|jd | jd krP| j|jkrP|j| j \}}|rP|jrP||jrPdS d S )Nr	   ?T)r'   modemodesr   OPENZ
firstbytes)r   requestr   factoryacceptr   r   r   	_can_readg   s    zPillowFormat._can_readc             C   s<   |   }|jd | jd kr8|j| jkr8| j|jkr8dS d S )Nr	   r(   T)r'   r)   r*   	extension
extensionsr   SAVE)r   r,   r   r   r   r   
_can_writep   s
    zPillowFormat._can_writec               @   sF   e Zd ZdddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dS )zPillowFormat.ReaderNFc             C   s   | j  }y|j| j j \}}W n$ tk
rD   td| j j Y nX |  | _|| jd| _	t
|drv|| j	j | j	jr| j	jjr| j	jj| j	j_t| j	 t|t| j	d| _|d k	r|| jd< d| _t
| j	dr| j	j| _d S )NzFormat %s cannot read images.r   _decompression_bomb_check)as_grayis_grayr)   r	   n_frames)formatr'   r+   r   KeyErrorr&   name	_get_file_fp_imr#   r4   sizepalettedirtyrawmoderawmode_savedpil_try_readdict_palette_is_grayscale_kwargs_lengthr7   )r   pilmoder5   r   r-   r.   r   r   r   _openx   s&    




zPillowFormat.Reader._openc             C   s   d| _ | j S )NF)
_we_own_fpr,   get_file)r   r   r   r   r;      s    zPillowFormat.Reader._get_filec             C   s   t | j | jr| j  d S )N)save_pillow_closer=   rJ   r<   close)r   r   r   r   _close   s    
zPillowFormat.Reader._closec             C   s   | j S )N)rG   )r   r   r   r   _get_length   s    zPillowFormat.Reader._get_lengthc             C   s6   y| j | W n  tk
r0   td| Y nX d S )NzCould not seek to index %i)r=   seekEOFError
IndexError)r   indexr   r   r   _seek   s    zPillowFormat.Reader._seekc             C   s   || j krtd|| j f | j }||kr:| | n x||k rX|d7 }| | q<W | jjr|| jjjr|| jjj| jj_| j	 d  t
| jf| j}|| jjfS )NzImage index %i > %ir	   r   )rG   rR   r=   tellrT   r?   r@   rA   rB   getdatapil_get_framerF   info)r   rS   r   imr   r   r   	_get_data   s    


zPillowFormat.Reader._get_datac             C   s   |d ks|dkst  | jjS )Nr   )rR   r=   rX   )r   rS   r   r   r   _get_meta_data   s    z"PillowFormat.Reader._get_meta_data)NF)
__name__
__module____qualname__rI   r;   rN   rO   rT   rZ   r[   r   r   r   r   Readerw   s   
r_   c               @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
zPillowFormat.Writerc             C   s`   | j  }y|j| j j | _W n$ tk
rB   td| j j Y nX | j	 | _
i | _d| _d S )NzFormat %s cannot write images.F)r8   r'   r2   r   Z
_save_funcr9   r&   r:   r,   rK   r<   _meta_written)r   r   r   r   r   rI      s    
zPillowFormat.Writer._openc             C   s   d S )Nr   )r   r   r   r   rN      s    zPillowFormat.Writer._closec             C   s   | j rtd| jj |jdkrD|jd dkrD|d d d d df }d| _ | j| t|| jj	}d| jkrv|
 }|j| jfd| jj	i| j t| d S )	Nz&Format %s only supports single images.   r	   r   Tbitsr8   )ra   r&   r8   r:   ndimshaper`   updatendarray_to_pilr   quantizeZsaver<   rL   )r   rY   metaZimgr   r   r   _append_data   s    
z PillowFormat.Writer._append_datac             C   s   | j | d S )N)r`   rg   )r   rj   r   r   r   set_meta_data   s    z!PillowFormat.Writer.set_meta_dataN)r\   r]   r^   rI   rN   rk   rl   r   r   r   r   Writer   s   
rm   )r\   r]   r^   __doc__r!   r%   _modes_descriptionr   propertyr   r'   r/   r3   r   r_   rm   __classcell__r   r   )r   r   r   ;   s   	Gr   c               @   s4   e Zd ZdZG dd dejZG dd dejZdS )	PNGFormata
  A PNG format based on Pillow.
    
    This format supports grayscale, RGB and RGBA images.
    
    Parameters for reading
    ----------------------
    ignoregamma : bool
        Avoid gamma correction. Default True.
    pilmode : str
        From the Pillow documentation:
        
        * 'L' (8-bit pixels, grayscale)
        * 'P' (8-bit pixels, mapped to any other mode using a color palette)
        * 'RGB' (3x8-bit pixels, true color)
        * 'RGBA' (4x8-bit pixels, true color with transparency mask)
        * 'CMYK' (4x8-bit pixels, color separation)
        * 'YCbCr' (3x8-bit pixels, color video format)
        * 'I' (32-bit signed integer pixels)
        * 'F' (32-bit floating point pixels)
        
        PIL also provides limited support for a few special modes, including
        'LA' ('L' with alpha), 'RGBX' (true color with padding) and 'RGBa'
        (true color with premultiplied alpha).
        
        When translating a color image to grayscale (mode 'L', 'I' or 'F'),
        the library uses the ITU-R 601-2 luma transform::
        
            L = R * 299/1000 + G * 587/1000 + B * 114/1000
    as_gray : bool
        If True, the image is converted using mode 'F'. When `mode` is
        not None and `as_gray` is True, the image is first converted
        according to `mode`, and the result is then "flattened" using
        mode 'F'.
    
    Parameters for saving
    ---------------------
    optimize : bool
        If present and true, instructs the PNG writer to make the output file
        as small as possible. This includes extra processing in order to find
        optimal encoder settings.
    transparency: 
        This option controls what color image to mark as transparent.
    dpi: tuple of two scalars
        The desired dpi in each direction.
    pnginfo: PIL.PngImagePlugin.PngInfo
        Object containing text tags.
    compress_level: int
        ZLIB compression level, a number between 0 and 9: 1 gives best speed,
        9 gives best compression, 0 gives no compression at all. Default is 9.
        When ``optimize`` option is True ``compress_level`` has no effect
        (it is set to 9 regardless of a value passed).
    compression: int
        Compatibility with the freeimage PNG format. If given, it overrides
        compress_level.
    icc_profile:
        The ICC Profile to include in the saved file.
    bits (experimental): int
        This option controls how many bits to store. If omitted,
        the PNG writer uses 8 bits (256 colors).
    quantize: 
        Compatibility with the freeimage PNG format. If given, it overrides
        bits. In this case, given as a number between 1-256.
    dictionary (experimental): dict
        Set the ZLIB encoder dictionary.
    c               @   s   e Zd ZdddZdd ZdS )	zPNGFormat.ReaderNFTc             C   s   t jj| ||dS )N)rH   r5   )r   r_   rI   )r   rH   r5   ignoregammar   r   r   rI   $  s    zPNGFormat.Reader._openc          	   C   s   t j| |\}}| jjddsyt|d }W n ttfk
rJ   Y n>X t|j	t
jkr^dnd}d}|| | | | d |d d < ||fS )Nrt   Tgammai      g      ?g<Nё\?)r   r_   rZ   r,   r   getfloatr9   
ValueErrordtypenpuint16)r   rS   rY   rX   ru   ZscaleZgainr   r   r   rZ   '  s     zPNGFormat.Reader._get_data)NFT)r\   r]   r^   rI   rZ   r   r   r   r   r_   #  s   
r_   c               @   s   e Zd ZdddZdd ZdS )zPNGFormat.WriterNFc             K   s   | dd|d< |d k	r<|dk s(|dkr4td| ||d< |d k	rzx,tddD ]}d| |krPP qPW td| ||d< |rtd	 d
}x |D ]}||krtd| qW tj|  | j	
| d S )Ncompress_level	   r   z!Invalid PNG compression level: %rr	   r   z)PNG quantize must be power of two, not %rrd   z0PIL PNG writer cannot produce interlaced images.)optimizetransparencyZdpiZpnginford   r}   Zicc_profileZ
dictionaryzInvalid arg for PNG writer: %r)rw   ry   rangeloggerZwarning	TypeErrorr   rm   rI   r`   rg   )r   Zcompressionri   Z
interlacedr   rd   Zok_keyskeyr   r   r   rI   ;  s(    

	
zPNGFormat.Writer._openc             C   sT   t |jdkr4|jdks&|jd dkr4t|dd}nt|dd}tj| || d S )Nr|   r   rc   r	      )bitdepth   )strrz   re   rf   r   r   rm   rk   )r   rY   rj   r   r   r   rk   a  s    &zPNGFormat.Writer._append_data)NNF)r\   r]   r^   rI   rk   r   r   r   r   rm   :  s   
&rm   N)r\   r]   r^   rn   r   r_   rm   r   r   r   r   rs      s   Ars   c               @   s4   e Zd ZdZG dd dejZG dd dejZdS )
JPEGFormata	  A JPEG format based on Pillow.
    
    This format supports grayscale, RGB and RGBA images.
    
    Parameters for reading
    ----------------------
    exifrotate : bool
        Automatically rotate the image according to exif flag. Default True.
    pilmode : str
        From the Pillow documentation:
        
        * 'L' (8-bit pixels, grayscale)
        * 'P' (8-bit pixels, mapped to any other mode using a color palette)
        * 'RGB' (3x8-bit pixels, true color)
        * 'RGBA' (4x8-bit pixels, true color with transparency mask)
        * 'CMYK' (4x8-bit pixels, color separation)
        * 'YCbCr' (3x8-bit pixels, color video format)
        * 'I' (32-bit signed integer pixels)
        * 'F' (32-bit floating point pixels)
        
        PIL also provides limited support for a few special modes, including
        'LA' ('L' with alpha), 'RGBX' (true color with padding) and 'RGBa'
        (true color with premultiplied alpha).
        
        When translating a color image to grayscale (mode 'L', 'I' or 'F'),
        the library uses the ITU-R 601-2 luma transform::
        
            L = R * 299/1000 + G * 587/1000 + B * 114/1000
    as_gray : bool
        If True, the image is converted using mode 'F'. When `mode` is
        not None and `as_gray` is True, the image is first converted
        according to `mode`, and the result is then "flattened" using
        mode 'F'.
    
    Parameters for saving
    ---------------------
    quality : scalar
        The compression factor of the saved image (1..100), higher
        numbers result in higher quality but larger file size. Default 75.
    progressive : bool
        Save as a progressive JPEG file (e.g. for images on the web).
        Default False.
    optimize : bool
        On saving, compute optimal Huffman coding tables (can reduce a few
        percent of file size). Default False.
    dpi : tuple of int
        The pixel density, ``(x,y)``.
    icc_profile : object
        If present and true, the image is stored with the provided ICC profile.
        If this parameter is not provided, the image will be saved with no
        profile attached.
    exif : dict
        If present, the image will be stored with the provided raw EXIF data.
    subsampling : str
        Sets the subsampling for the encoder. See Pillow docs for details.
    qtables : object
        Set the qtables for the encoder. See Pillow docs for details.
    c               @   s.   e Zd ZdddZdd Zdd	 Zd
d ZdS )zJPEGFormat.ReaderNFTc             C   s   t jj| ||dS )N)rH   r5   )r   r_   rI   )r   rH   r5   
exifrotater   r   r   rI     s    zJPEGFormat.Reader._openc             C   sL   | j jds"d| j jddkr8d| _t| j  dS d| _| j  S d S )N)zhttp://zhttps://z.zip/\/TrbF)r,   filename
startswithreplacerJ   openZget_local_filenamerK   )r   r   r   r   r;     s    zJPEGFormat.Reader._get_filec             C   sv   t j| |\}}d|krbddlm} i |d< x2| j  D ] \}}|||}||d |< q>W | 	||}||fS )NZexifr   )TAGS	EXIF_MAIN)
r   r_   rZ   ZPIL.ExifTagsr   r=   Z_getexifitemsrw   _rotate)r   rS   rY   rX   r   tagvalueZdecodedr   r   r   rZ     s    zJPEGFormat.Reader._get_datac             C   s   | j jddry|d d }W n tk
r4   Y nVX |dkr>|dkrRt|d}|dkrft|d	}|d
krxt|}|dkrt|}|S )z Use Orientation information from EXIF meta data to 
            orient the image correctly. Similar code as in FreeImage plugin.
            r   Tr   ZOrientation)r	   r   )rb      r   )      rb   )   r   )r   r   r   r   )r,   r   rw   r9   r{   Zrot90Zfliplr)r   rY   rj   Zorir   r   r   r     s    

zJPEGFormat.Reader._rotate)NFT)r\   r]   r^   rI   r;   rZ   r   r   r   r   r   r_     s   
r_   c               @   s   e Zd ZdddZdd ZdS )	zJPEGFormat.WriterK   Fc             K   sl   t |}|dk s|dkr tdtdtd|}||d< t||d< t||d< tj|  | j	| d S )Nr	   d   z)JPEG quality should be between 1 and 100._   qualityprogressiver   )
intry   minmaxboolr   rm   rI   r`   rg   )r   r   r   r   r   r   r   r   rI     s    zJPEGFormat.Writer._openc             C   s@   |j dkr |jd dkr tdt|dd}tj| || d S )Nrb   rc   r   z$JPEG does not support alpha channel.r   )r   )re   rf   IOErrorr   r   rm   rk   )r   rY   rj   r   r   r   rk     s
    zJPEGFormat.Writer._append_dataN)r   FF)r\   r]   r^   rI   rk   r   r   r   r   rm     s   
rm   N)r\   r]   r^   rn   r   r_   rm   r   r   r   r   r   i  s   :7r   c             C   s(   t | dr$t t| dd dr$|   d S )NrM   fp)r#   getattrrM   )rY   r   r   r   rL     s    
rL   c          
   C   sd   y|   d  W nN tk
r^ } z0d}|d7 }t|}d| j||f }t|W d d }~X Y nX d S )Nr   z8http://pillow.readthedocs.io/en/latest/installation.htmlz#external-librarieszACould not load "%s" 
Reason: "%s"
Please see documentation at: %s)rV   r   r   r   ry   )rY   eZsiteZpillow_error_messageZerror_messager   r   r   rC     s    rC   c             C   sP   | j dkrdS t|  d}|  \}}|||d  }tt|dS )NPF)   rb   r	   r   )r)   r{   ZasarrayZ
getpaletteZreshapeZ
getextremaZallcloseZdiff)Z	pil_imager?   startstopZvalid_paletter   r   r   rE     s    
rE   c       
      C   s  |dkrt | }| }|dk	r4|| jkr0| |}n|r<n| jdkrX|rX| d}n| jdkr| jdddk	r| d}q| jjdkrt| j d tj	}t
| jdr| jj| j_| jjr| jjn| jj}t|}d	|f|_|jd d
ks|jd dkrL|d	 dkrLt|dddd
f dt|jd |j f}|dr|jd d
kr~|dddddgf n|dddddd
gf }t| tj	}y|| }W n  tk
r   | d}Y nX n
| d}n.d| jkr| d}n| jdkr| d}|r |d}n$t|tjsD|jdkrD|d}| jdr| j}	| jdrjdnd}d| jkr|dd}t| | }|	ddd	 |_n4| jdkr| jdkr|dkrd}tj||d }|S )!z 
    is_gray: Whether the image *is* gray (by inspecting its palette).
    as_gray: Whether the resulting image must be converted to gaey.
    mode: The mode to convert to.
    Nr   Lr   RGBA)RGBr   r	   rB   rc   rb   r   Xrv   r   ZBGRr   AZCMYKr   F1zI;16Bz>u2z<u2Sur   r   Ir|   )rz   )rE   r)   ZconvertrX   rw   r?   r{   Z
frombufferrV   uint8r#   rB   rA   lenrf   Zcolumn_stackZonesrz   r   Zarray	Exception
isinstanceZndarrayr>   endswithr   tobytescopyr8   )
rY   r6   r5   r)   rz   framepZ	nchannelsZframe_palettedrf   r   r   r   rW   !  sb    

.2>

"rW   c             C   s   ddl m} | jdkr8t| dd} ddd| jd	  }nv|d
krd}d}| jjdkr^t| } q|  dk r|  dkr| 	t
j} d }}qt| dd} nt| dd} d}d}|dkr|  }| jd	kr||| jj}||d| n"| jd | jd f}||||}|S || |S d S )Nr   )r   rb   r   )r   r   r   )rb   r   r   )Zpngr   zI;16r   fr   r   r   rawr	   )r"   r   re   r   rf   rz   Zkindr   r   Zastyper{   r   r   newTZ	frombytesZ	fromarray)ZarrZ
format_strr   r)   Z	mode_baseZarray_bufferrY   Zimage_shaper   r   r   rh     s2    




rh   )	GIFFormat
TIFFFormatZMPEG)r   r   r    ZTIFFc              C   sx   xrt D ]j\} }}| tkrqt| t}|jp.|}|| d |||j}| |_|tksX|jsft	|  t
 |_t| qW d S )Nz-PIL)r
   IGNORE_FORMATSSPECIAL_FORMATSrw   r   rp   ro   r   rn   r   GENERIC_DOCSr   Z
add_format)idZsummaryZextZ	FormatClsr8   r   r   r   register_pillow_formats  s    
r   )NNNN)N)$rn   Z
__future__r   r   r   Zloggingr   Znumpyr{   r   r   Zcorer   r   Zpillow_infor
   r   Z	getLoggerr\   r   r   r   rs   r   rL   rC   rE   rW   rh   Zpillowmultir   r   r   rD   r   r   r   r   r   r   <module>   s2   
# & 
 
a
.