U
    a+d                     @   s4  d Z ddl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m	Z	m
Z
mZmZmZmZmZ eeZdZddddd	d
dZd%ddZdd Zdd Zejdddej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 G dd  d eZ!G d!d" d"e!Z"G d#d$ d$e!Z#e  Z$dS )&z Module imageio/freeimage.py

This module contains the wrapper code for the freeimage library.
The functions defined in this module are relatively thin; just thin
enough so that arguments and results are native Python/numpy data
types.

    N   )get_remote_fileload_libDictresource_dirsIS_PYPYget_platformInternetNotAllowedErrorNeedDownloadErrorFz!libfreeimage-3.16.0-osx10.6.dylibzFreeImage-3.15.4-win32.dllzFreeImage-3.15.1-win64.dllzlibfreeimage-3.16.0-linux32.sozlibfreeimage-3.16.0-linux64.so)Zosx32Zosx64win32Zwin64Zlinux32Zlinux64c                 C   s6   t  }|r2|tkr2dt|  }t|| |d dt_dS )a  Download the FreeImage library to your computer.

    Parameters
    ----------
    directory : str | None
        The directory where the file will be cached if a download was
        required to obtain the file. By default, the appdata directory
        is used. This is also the first directory that is checked for
        a local version of the file.
    force_download : bool | str
        If True, the file will be downloaded even if a local copy exists
        (and this copy will be overwritten). Can also be a YYYY-MM-DD date
        to ensure a file is up-to-date (modified date of a file on disk,
        if present, is checked).
    
freeimage/)fname	directoryforce_downloadN)r   FNAME_PER_PLATFORMr   fi_lib)r   r   platr    r   >/tmp/pip-unpacked-wheel-xbmu82vq/imageio/plugins/_freeimage.pydownload/   s
    r   c               
   C   s   t dd} | r| S t }|r|tkrztdt|  ddW S  tk
rP   Y nJ tk
rj   tdY n0 tk
r } zt	t
| W 5 d}~X Y nX dS )z7Ensure we have our version of the binary freeimage lib.IMAGEIO_FREEIMAGE_LIBNr   F)autozNeed FreeImage library. You can obtain it with either:
  - download using the command: imageio_download_bin freeimage
  - download by calling (in Python): imageio.plugins.freeimage.download()
)osgetenvr   r   r   r	   r
   RuntimeErrorloggerwarningstr)libr   er   r   r   get_freeimage_libF   s    r!   c                 C   s   |  t S N)encodesysgetfilesystemencoding)xr   r   r   efnc   s    r'   i   i dtypec                   @   sT  e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZeejeejeejeejeeje	eje
ejeejeejeejeejeejiZejdfeejdfeejdfeejdfeejdfeejdfeejdfeejdfe	ejdfe
ejdfeejdfeejdfeejdfeejdfeiZeg eg eg eg e	g e
g eg edgedgedgedgiZdS )FI_TYPESr      r                     	   
         N)__name__
__module____qualname__ZFIT_UNKNOWN
FIT_BITMAPZ
FIT_UINT16Z	FIT_INT16Z
FIT_UINT32Z	FIT_INT32Z	FIT_FLOATZ
FIT_DOUBLEZFIT_COMPLEXZ	FIT_RGB16Z
FIT_RGBA16ZFIT_RGBFZ	FIT_RGBAFnumpyuint8uint16int16uint32int32float32float64Z
complex128dtypesfi_types
extra_dimsr   r   r   r   r*   k   s                                        r*   c                   @   s`  e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZdZdZd	ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZd
ZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:dZ;dZ<dZ=dZ>dZ?dZ@dZAdZBdZCdZDdZEdZFdZGdZHdZIdZJdZKdZLdZMdZNdZOdZPdZQdZRdZSdZTdZUdZVdZWdS )IO_FLAGSi   r   r+   r   r-   r1          @         i      i   i    i   i @  i   i   i   r,   r/   r2   N)Xr6   r7   r8   ZFIF_LOAD_NOPIXELSZBMP_DEFAULTZBMP_SAVE_RLEZCUT_DEFAULTZDDS_DEFAULTZEXR_DEFAULTZ	EXR_FLOATZEXR_NONEZEXR_ZIPZEXR_PIZZ	EXR_PXR24ZEXR_B44ZEXR_LCZFAXG3_DEFAULTZGIF_DEFAULTZGIF_LOAD256ZGIF_PLAYBACKZHDR_DEFAULTZICO_DEFAULTZICO_MAKEALPHAZIFF_DEFAULTZJ2K_DEFAULTZJP2_DEFAULTZJPEG_DEFAULTZ	JPEG_FASTZJPEG_ACCURATEZ	JPEG_CMYKZJPEG_EXIFROTATEZJPEG_QUALITYSUPERBZJPEG_QUALITYGOODZJPEG_QUALITYNORMALZJPEG_QUALITYAVERAGEZJPEG_QUALITYBADZJPEG_PROGRESSIVEZJPEG_SUBSAMPLING_411ZJPEG_SUBSAMPLING_420ZJPEG_SUBSAMPLING_422ZJPEG_SUBSAMPLING_444ZJPEG_OPTIMIZEZJPEG_BASELINEZKOALA_DEFAULTZLBM_DEFAULTZMNG_DEFAULTZPCD_DEFAULTZPCD_BASEZPCD_BASEDIV4ZPCD_BASEDIV16ZPCX_DEFAULTZPFM_DEFAULTZPICT_DEFAULTZPNG_DEFAULTZPNG_IGNOREGAMMAZPNG_Z_BEST_SPEEDZPNG_Z_DEFAULT_COMPRESSIONZPNG_Z_BEST_COMPRESSIONZPNG_Z_NO_COMPRESSIONZPNG_INTERLACEDZPNM_DEFAULTZPNM_SAVE_RAWZPNM_SAVE_ASCIIZPSD_DEFAULTZPSD_CMYKZPSD_LABZRAS_DEFAULTZRAW_DEFAULTZRAW_PREVIEWZRAW_DISPLAYZSGI_DEFAULTZTARGA_DEFAULTZTARGA_LOAD_RGB888ZTARGA_SAVE_RLEZTIFF_DEFAULTZ	TIFF_CMYKZTIFF_PACKBITSZTIFF_DEFLATEZTIFF_ADOBE_DEFLATEZ	TIFF_NONEZTIFF_CCITTFAX3ZTIFF_CCITTFAX4ZTIFF_LZWZ	TIFF_JPEGZTIFF_LOGLUVZWBMP_DEFAULTZXBM_DEFAULTZXPM_DEFAULTr   r   r   r   rE      s   rE   c                   @   s4   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdS )METADATA_MODELSr   r+   r   r,   r-   r.   r/   r0   r1   r2   N)r6   r7   r8   ZFIMD_COMMENTSZFIMD_EXIF_MAINZFIMD_EXIF_EXIFZFIMD_EXIF_GPSZFIMD_EXIF_MAKERNOTEZFIMD_EXIF_INTEROPZ	FIMD_IPTCZFIMD_XMPZFIMD_GEOTIFFZFIMD_ANIMATIONr   r   r   r   rL     s   rL   c                $   @   s   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZeejeejeejedejfdejfgeejeejeejeeje	eje
ejeejedejfdejfgeejeejeejedejfdejfdejfdejfgiZdS )METADATA_DATATYPEr+   r   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5         rF         	numeratordenominatorRGBAN) r6   r7   r8   Z	FIDT_BYTE
FIDT_ASCIIZ
FIDT_SHORTZ	FIDT_LONGZFIDT_RATIONALZ
FIDT_SBYTEZFIDT_UNDEFINEDZFIDT_SSHORTZ
FIDT_SLONGZFIDT_SRATIONALZ
FIDT_FLOATZFIDT_DOUBLEZFIDT_IFDZFIDT_PALETTEZ
FIDT_LONG8ZFIDT_SLONG8Z	FIDT_IFD8r:   r;   r<   r>   Zuint64Zint64Zint8r=   r?   r@   rA   rB   r   r   r   r   rM   #  sl                  rM   c                *   @   s  e Zd ZdZejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfejdfd)Zdd Z	e
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d Zdd Zd#ddZd$dd Zd%d!d"ZdS )&	Freeimagea  Class to represent an interface to the FreeImage library.
    This class is relatively thin. It provides a Pythonic API that converts
    Freeimage objects to Python objects, but that's about it.
    The actual implementation should be provided by the plugins.

    The recommended way to call into the Freeimage library (so that
    errors and warnings show up in the right moment) is to use this
    object as a context manager:
    with imageio.fi as lib:
        lib.FreeImage_GetPalette()

    N))FreeImage_AllocateTFreeImage_FindFirstMetadataFreeImage_GetBitsFreeImage_GetPaletteFreeImage_GetTagKeyFreeImage_GetTagValueFreeImage_CreateTagFreeImage_SaveFreeImage_LoadZFreeImage_LoadFromMemoryFreeImage_OpenMultiBitmapZ#FreeImage_LoadMultiBitmapFromMemoryFreeImage_LockPageFreeImage_OpenMemoryFreeImage_GetVersionZFreeImage_GetFIFExtensionListZFreeImage_GetFormatFromFIFZFreeImage_GetFIFDescriptionFreeImage_ColorQuantizeExFreeImage_IsLittleEndianFreeImage_SetOutputMessageZFreeImage_GetFIFCountZFreeImage_IsPluginEnabledFreeImage_GetFileTypeFreeImage_GetTagTypeFreeImage_GetTagLengthFreeImage_FindNextMetadataFreeImage_FindCloseMetadataFreeImage_GetFIFFromFilenameFreeImage_FIFSupportsReadingFreeImage_FIFSupportsWritingFreeImage_FIFSupportsExportTypeFreeImage_FIFSupportsExportBPPFreeImage_GetHeightFreeImage_GetWidthFreeImage_GetImageTypeFreeImage_GetBPPFreeImage_GetColorsUsedFreeImage_ConvertTo32BitsFreeImage_GetPitchFreeImage_Unloadc                    sV   d  _ t  _g  _tjdr*tj	}ntj
}|d tjtj fdd}| _d S )Nwinc                    s6   | d} j| t jdkr2 jd qd S )Nutf-8rJ   r   )decode	_messagesappendlenpop)Zfifmessageselfr   r   error_handler  s    
z)Freeimage.__init__.<locals>.error_handler)r   	threadingRLock_lockr   r$   platform
startswithctypesZWINFUNCTYPE	CFUNCTYPEc_intc_char_p_error_handler)r   Zfunctyper   r   r   r   __init__  s    
zFreeimage.__init__c              
   C   sn   | j d krRz|   W n: tk
rP } zd| _ |  j t|7  _ W 5 d }~X Y nX t| j trht| j | j S )Nz+The freeimage library could not be loaded: )r   load_freeimageOSErrorr   
isinstancer   )r   errr   r   r   r     s    
$
zFreeimage.libc                 C   s&   z
| j  W n tk
r    Y dS X dS )NFT)r   	Exceptionr   r   r   r   has_lib  s
    
zFreeimage.has_libc                 C   s   d}z,|    |   | j ddkr.d}W n tk
rD   Y nX |s`t  |    |   | j| j | j d| _	dS )zTry to load the freeimage lib from the system. If not successful,
        try to download the imageio version and try again.
        Fr}   z3.15TN)
_load_freeimage_register_apir   rf   r~   r   r!   ri   r   Zlib_version)r   successr   r   r   r     s    zFreeimage.load_freeimagec           
   
   C   s   ddg}ddddg}t  }t }|rNt| }|D ]}|dtj|d| q0tdd }|d k	rn|d| zt|||\}}W n6 t	k
r } zt
|d	 }	t	|	W 5 d }~X Y nX || _|| _d S )
NZ	freeimageZlibfreeimageZ	FreeImagezlibfreeimage.dylibzlibfreeimage.sozlibfreeimage.so.3r   r   z&
Please install the FreeImage library.)r   r   r   insertr   pathjoinr   r   r   r   r   Z	lib_fname)
r   Z	lib_namesZexact_lib_namesZres_dirsr   r   dirr   r   err_msgr   r   r   r     s,    zFreeimage._load_freeimagec                 C   s4   | j  D ]$\}\}}t| j|}||_||_q
d S r"   )_APIitemsgetattrr   restypeargtypes)r   fr   r   funcr   r   r   r     s    zFreeimage._register_apic                 C   s   | j   | jS r"   )r   acquirer   r   r   r   r   	__enter__  s    
zFreeimage.__enter__c                 G   s   |    | j  d S r"   )_show_any_warningsr   release)r   argsr   r   r   __exit__  s    zFreeimage.__exit__c                 C   s
   g | _ dS )zwReset the list of output messages. Call this before
        loading or saving an image with the FreeImage API.
        Nr   r   r   r   r   
_reset_log  s    zFreeimage._reset_logc                 C   s&   | j rd| j }|   |S dS dS )zGet the output messages produced since the last reset as
        one string. Returns 'No known reason.' if there are no messages.
        Also resets the log.
         zNo known reason.N)r   r   r   )r   resr   r   r   _get_error_message  s
    zFreeimage._get_error_messagec                 C   s$   | j r td|    |   dS )zIf there were any messages since the last reset, show them
        as a warning. Otherwise do nothing. Also resets the messages.
        zimageio.freeimage warning: N)r   r   r   r   r   r   r   r   r   r   &  s    zFreeimage._show_any_warningsc                 C   s   dd | j D S )zwReturn a list of the last 256 output messages
        (warnings and errors) produced by the FreeImage library.
        c                 S   s   g | ]}|qS r   r   ).0mr   r   r   
<listcomp>3  s     z,Freeimage.get_output_log.<locals>.<listcomp>r   r   r   r   r   get_output_log.  s    zFreeimage.get_output_logc              
   C   s  |  }d}|dkrt d|dkr|dk	rh|t|t|}|t|t|}|t| |dkrtj	
|r|t|d}|dkr|t|}|dkrt d| n>|dkr||st d	| n|dkr||st d
| |W  5 Q R  S Q R X dS )a  Get the freeimage Format (FIF) from a given filename.
        If mode is 'r', will try to determine the format by reading
        the file, otherwise only the filename is used.

        This function also tests whether the format supports reading/writing.
        rwz"Invalid mode (must be "r" or "w").rNr   z$Cannot determine format of file "%s"wz$Cannot write the format of file "%s"z#Cannot read the format of file "%s")
ValueErrorre   r   r   r   ZFreeImage_GetFileTypeFromMemoryc_void_pZFreeImage_CloseMemoryr   r   isfilerj   r'   ro   rq   rp   )r   filenamemodebbr   ftypeZfimemoryr   r   r   getFIF5  s.     zFreeimage.getFIFr   c                 C   s   t | |||S )zXcreate_bitmap(filename, ftype, flags=0)
        Create a wrapped bitmap object.
        )FIBitmapr   r   r   flagsr   r   r   create_bitmap[  s    zFreeimage.create_bitmapc                 C   s   t | |||S )zlcreate_multipage_bitmap(filename, ftype, flags=0)
        Create a wrapped multipage bitmap object.
        )FIMultipageBitmapr   r   r   r   create_multipage_bitmapa  s    z!Freeimage.create_multipage_bitmap)N)r   )r   )r6   r7   r8   __doc__r   r   r   r   r   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rY   O  sv   =
!	
&
rY   c                   @   s>   e Zd Zdd Zdd Zdd Zddd	Zd
d Zdd ZdS )FIBaseBitmapc                 C   s(   || _ || _|| _|| _d | _g | _d S r"   )_fi	_filename_ftype_flags_bitmap_close_funcs)r   r   r   r   r   r   r   r   r   i  s    zFIBaseBitmap.__init__c                 C   s   |    d S r"   )closer   r   r   r   __del__q  s    zFIBaseBitmap.__del__c              
   C   sp   | j d k	rl| jrl| jD ]H}z.| j |d }||dd    W 5 Q R X W q tk
r\   Y qX qg | _d | _ d S )Nr   r+   )r   r   r   r   )r   
close_funcZfunr   r   r   r   t  s    
zFIBaseBitmap.closeNc                 C   s:   | j dk	r
|dkr | jjj|f}|| _ |r6| j| dS )zAFunction to set the bitmap and specify the function to unload it.N)r   r   r   r{   r   r   )r   bitmapr   r   r   r   _set_bitmap  s    
zFIBaseBitmap._set_bitmapc              
   C   s  dd t j D }t }t }| jX}|D ]>\}}||| jt	|}t|}|r0d}|rf|
|d}	||}
||}tj| }|||}tt|}|}|
tjkr|dd}nn|
tjkr<tj|
 }trt|ttfrnDz,tj||d }t|dkr"|d }W n tk
r:   Y nX ||t }|||	< | |t	|}qb|!| q0|W  5 Q R  S Q R X d S )	Nc                 S   s*   g | ]"\}}| d r|dd |fqS )FIMD_r.   N)r   )r   namenumberr   r   r   r     s   
z.FIBaseBitmap.get_meta_data.<locals>.<listcomp>Tr}   replacer(   r+   r   )"rL   __dict__r   r   r   r   r   r[   r   byrefr^   r~   rk   rl   c_charfrom_addressr_   bytes	bytearrayrM   rX   rB   r   r   listtupler:   
frombuffercopyr   r   
setdefaultrm   rn   )r   modelsmetadatatagr   
model_namer   ZmdhandleZmoretag_nametag_type	byte_sizeZchar_ptrdata	tag_bytestag_valr)   subdictr   r   r   get_meta_data  s\    
  





 
 zFIBaseBitmap.get_meta_datac                 C   s  i }t j D ]"\}}|dr|||dd  < qdd }| j}| D ]\}}||d }|d krlqL| D ]p\}	}
| }t|}zFzd}t
|
trz|
d}d}W n tk
r   Y nX |rtj}t|}nNt|
dst|
g}
||
j}|d kr td	|	  W W qt|
 }|
j}|||	d
 ||| ||| ||t| ||| ||}||| j || W nB t!k
r } z"td|	| j" t|f  W 5 d }~X Y nX W 5 |	| X qtqLW 5 Q R X d S )Nr   r.   c                 S   s(   t j D ]\}}| |kr
|  S q
d S r"   )rM   rB   r   )r)   r   Znumpy_dtyper   r   r   get_tag_type_number  s    
z7FIBaseBitmap.set_meta_data.<locals>.get_tag_type_numberFasciiTr)   z>imageio.freeimage warning: Could not determine tag type of %r.r}   z6imagio.freeimage warning: Could not set tag %r: %s, %s)#rL   r   r   r   r   getr`   r   r   ZFreeImage_DeleteTagr   r   r#   UnicodeErrorrM   rX   r   hasattrr:   arrayr)   r   r   tobytessizeZFreeImage_SetTagKeyZFreeImage_SetTagTypeZFreeImage_SetTagCountZFreeImage_SetTagLengthZFreeImage_SetTagValuer^   ZFreeImage_SetMetadatar   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   Zis_asciir   r   Z	tag_countZtag_keyr   r   r   r   set_meta_data  sd    









zFIBaseBitmap.set_meta_data)N)	r6   r7   r8   r   r   r   r   r   r   r   r   r   r   r   h  s   
Cr   c                   @   s^   e Zd ZdZdd ZdddZdddZd	d
 Zdd Zdd Z	dd Z
dd ZdddZdS )r   z!Wrapper for the FI bitmap object.c              
   C   s   t |tjst|j}|j}|d d \}}t|dkr>d}nt|dkrT|d }n|d }ztj|j	|f }|| _
W n tk
r   tdY nX | j\}d|j | }	|||||	ddd}
t|
}
|
std| j  | |
|j|
f W 5 Q R X d S )Nr   r+   r,   r   z,Cannot write arrays of given type and shape.r1   z)Could not allocate bitmap for storage: %s)r   r:   ndarrayAssertionErrorshaper)   r   r*   rC   type_fi_typeKeyErrorr   r   itemsizerZ   r   r   r   r   r   r{   )r   r   r   r)   r   c
n_channelsfi_typer   bppr   r   r   r   allocate  s2    


zFIBitmap.allocateNc              	   C   sr   |d kr| j }| jT}|| jt|| j}t|}|sRtd| j | j	 f | 
||j|f W 5 Q R X d S )NzCould not load bitmap "%s": %s)r   r   rb   r   r'   r   r   r   r   r   r   r{   )r   r   r   r   r   r   r   load_from_filename<  s    
zFIBitmap.load_from_filenamec              	   C   s   |d kr| j }| j}| j}| j}| jv}|tjkrF||||}n|	||}|s^t
d|||t|| j}|d krtd| j  d| j  W 5 Q R X d S )Nz2Cannot save image of this format to this file typezCould not save file `z`: )r   r   r   r   r   r*   r9   rs   rw   rr   	TypeErrorra   r'   r   r   r   )r   r   r   r   r  r   Z	can_writer   r   r   r   save_to_filename^  s&    
 zFIBitmap.save_to_filenamec              	   C   s   |   \}}}| ||d}| j}| }W 5 Q R X dd }t|dkr|r|jtjkr||d }||d }	||d }
|d dkrt|
|	|fS |d dkr||d }t|
|	||fS t	d	| ||
 }|S )
NFc                 S   s   | j dkr| d d d jS | j dkr<| d d d d df jS | j dkrd| d d d d d d df jS | j dkr| d d d d d d d d df jS d S )Nr+   r   r   r,   r-   )ndimTZarrr   r   r   n  s    



z"FIBitmap.get_image_data.<locals>.nr,   r   r+   r   r-   z Cannot handle images of shape %s)_get_type_and_shape_wrap_bitmap_bits_in_arrayr   rh   r   r   r:   r;   Zdstackr   r   )r   r)   r   r  r   r   isler  bgr   ar   r   r   get_image_data  s"    zFIBitmap.get_image_datac              	   C   s  t |tjst|j}|j}| j}| }W 5 Q R X |d d \}}t|dkr`d}||f}	n(t|dkr|d }|||f}	n|d }dd }
| 	|	|d}t|dkrX|rX|j
tjkrX|d d d d df }|d d d d df }|d d d d df }|
||d< |
||d< |
||d< |d dkrh|d d d d df }|
||d< n|
||d d < | jrz| | t|dkr|j
tjkr| j}|| j}W 5 Q R X t|}|std	ztjj}W n$ tk
r   tjd
 d }Y nX t||d d S )Nr   r+   r,   r   c                 S   s   | d d d j S )Nr   )r
  r  r   r   r   r    s    z"FIBitmap.set_image_data.<locals>.nTr-   zCould not get image paletter   rK   )r   r:   r   r   r   r)   r   rh   r   r  r   r;   _need_finish_finish_wrapped_arrayr]   r   r   r   r   GREY_PALETTEr   r   __array_interface__memmove)r   r   r   r)   r   r  r   r  r  Zw_shaper  Zwrapped_arrayrT   rU   rV   rW   paletteZpalette_datar   r   r   set_image_data  sN    
"

zFIBitmap.set_image_datac              	   C   s  | j }|| j}|| j}W 5 Q R X |d }|| }|j}	t|dkr`|	|d |	 |f}
n|	|f}
tj| |}z$d| _	t
rt tj||||
dW S  tk
r   |rd| _	tj||d Y S tt|}tj||d }t|dkr~|d |
d |d  |d f|_|d	|d d	|d
 d	|d f }tj||jd}t|d D ]"}|d	d	d	d	|f j||< qXn0|d
 |
d f|_|d	|d
 d	|d f j}| Y S Y nX d	S )a  Return an ndarray view on the data in a FreeImage bitmap. Only
        valid for as long as the bitmap is loaded (if single page) / locked
        in memory (if multipage). This is used in loading data, but
        also during saving, to prepare a strided numpy array buffer.

        r   r,   r   F)r)   bufferstridesTr(   r   Nr+   )r   rz   r   r\   r   r   r   r   r   r  TEST_NUMPY_NO_STRIDESNotImplementedErrorr:   r   zerosr   r   r   r   r   r)   ranger
  )r   r   r)   saver   pitchbitsheightr   r   r  r   r   r   array2ir   r   r   r    s<     &"z#FIBitmap._wrap_bitmap_bits_in_arrayc              	   C   s  | j *}|| j}|| j}|| j}W 5 Q R X |d |j }|| }||jd  }d|  krndk stn t|jd ||f}	t	|	|j
}
|dkr|j|
ddd|jd df< n>t|D ]4}||ddddf j|
ddd|jd |f< q|
jd d }t|||
j ~
dS )	z-Hardcore way to inject numpy array in bitmap.r1   r   r3   r   r+   Nr   )r   rz   r   r\   rw   r   r   r   r:   r  r)   r
  r   r  r   r  nbytes)r   r   r   r"  r#  r  Z	nchannelsZ	realwidthextraZnewshaper%  r&  Zdata_ptrr   r   r   r  .  s"     2zFIBitmap._finish_wrapped_arrayc              	   C   s  | j }| j6}||}||}|| | _}|s>tdW 5 Q R X d }tj| }|tj	krx| j}|
|}||}W 5 Q R X |r|dkr||}	t|	}	tjd |	j}
t|
tj }
t|
k rg }t||||g |fS ||}t|}| | |  S |dkr,g }nJ|dkr>dg}n8|dkrPdg}n&||}t|}| | |  S n
tj| }t||||g |fS )	NzUnknown image pixel typerJ   rK   r1      r,   rG   r-   )r   r   ru   rt   rv   r   r   r*   rB   r9   rw   rx   r]   r   r   c_uint8r   valuer:   r   r>   r   r  allr)   ry   r   r  rD   )r   r   r   r   hr  r  r)   Zhas_palletter  prD   Z	newbitmapr   r   r   r  H  sL    
















zFIBitmap._get_type_and_shaper   rJ   c              
   C   s   | j |}|| j||dd}t|}|sBtd| j| j  f t| j | j| j	| j
}|||j|f | j|_|W  5 Q R  S Q R X dS )zQuantize the bitmap to make it 8-bit (paletted). Returns a new
        FIBitmap object.
        Only for 24 bit images.
        r   Nz"Could not quantize bitmap "%s": %s)r   rg   r   r   r   r   r   r   r   r   r   r   r{   r   )r   Z	quantizerZpalettesizer   r   newr   r   r   quantize}  s&        
zFIBitmap.quantize)N)N)r   rJ   )r6   r7   r8   r   r  r  r  r  r  r  r  r  r1  r   r   r   r   r     s   $
"
@%745r   c                   @   s<   e Zd ZdZdddZdddZdd Zd	d
 Zdd ZdS )r   z+Wrapper for the multipage FI bitmap object.Nc              	   C   s   |d kr| j }d}d}d}| j^}|| jt||||| j}t|}|sh| j }t	d| j |f | 
||j|f W 5 Q R X d S )NFTz+Could not open file "%s" as multi-image: %s)r   r   rc   r   r'   r   r   r   r   r   r   FreeImage_CloseMultiBitmap)r   r   
create_new	read_onlykeep_cache_in_memoryr   multibitmapr   r   r   r   r    s.    

z$FIMultipageBitmap.load_from_filenamec              	   C   s   |d kr| j }d}d}d}| j\}|| jt||||d}t|}|sfd| j | j f }t|| 	||j
|f W 5 Q R X d S )NTFr   z4Could not open file "%s" for writing multi-image: %s)r   r   rc   r   r'   r   r   r   r   r   r2  )r   r   r3  r4  r5  r   r6  msgr   r   r   r    s,    
z"FIMultipageBitmap.save_to_filenamec              
   C   s*   | j }|| jW  5 Q R  S Q R X d S r"   )r   ZFreeImage_GetPageCountr   )r   r   r   r   r   __len__  s    zFIMultipageBitmap.__len__c              
   C   s   | j v}|| j|}t|}|s>td|| j| j  f t| j | j| j	| j
}|||j| j|df |W  5 Q R  S Q R X dS )zlReturn the sub-bitmap for the given page index.
        Please close the returned bitmap when done.
        z%Could not open sub-image %i in %r: %sFN)r   rd   r   r   r   r   r   r   r   r   r   r   ZFreeImage_UnlockPage)r   indexr   r   Zbmr   r   r   get_page  s    
 zFIMultipageBitmap.get_pagec              	   C   s&   | j }|| j|j W 5 Q R X dS )z*Add a sub-bitmap to the multi-page bitmap.N)r   ZFreeImage_AppendPager   )r   r   r   r   r   r   append_bitmap  s    zFIMultipageBitmap.append_bitmap)N)N)	r6   r7   r8   r   r  r  r8  r:  r;  r   r   r   r   r     s   
2
r   )NF)%r   r   r$   r   r   loggingr:   corer   r   r   r   r   r   r	   r
   	getLoggerr6   r   r  r   r   r!   r'   Zaranger>   r  objectr*   rE   rL   rM   rY   r   r   r   r   r   r   r   r   <module>   sF   	(


>m,   .   u