î
hÐR\v   ã               @   sh   d  d l  m Z d d l m Z m Z d  d l Z d
 Z Gd d „  d e ƒ Z Gd d	 „  d	 e ƒ Z	 d S)é    )Úprint_functioné   )ÚImageÚ_imagingmorphNé	   c               @   sp   e  Z d  Z d Z d d d d „ Z d d „  Z d d „  Z d	 d
 „  Z d d „  Z d d „  Z	 d d „  Z
 d S)Ú
LutBuildera~  A class for building a MorphLut from a descriptive language

      The input patterns is a list of a strings sequences like these::

          4:(...
             .1.
             111)->1

      (whitespaces including linebreaks are ignored). The option 4
      describes a series of symmetry operations (in this case a
      4-rotation), the pattern is described by:

      - . or X - Ignore
      - 1 - Pixel is on
      - 0 - Pixel is off

      The result of the operation is described after "->" string.

      The default is to return the current pixel value, which is
      returned if no other match is found.

      Operations:

      - 4 - 4 way rotation
      - N - Negate
      - 1 - Dummy op for no other operation (an op must always be given)
      - M - Mirroring

      Example::

          lb = LutBuilder(patterns = ["4:(... .1. 111)->1"])
          lut = lb.build_lut()

    Nc             C   s¾   | d  k	 r | |  _  n	 g  |  _  d  |  _ | d  k	 rº i d d g d 6d g d 6d d g d 6d g d	 6d d
 g d 6d d d g d 6} | | k rª t d | d ƒ ‚ n  | | |  _  n  d  S)Nz1:(... ... ...)->0z4:(00. 01. ...)->1Zcornerz4:(... .0. .1.)->1Z	dilation4z4:(... .0. ..1)->1Z	dilation8z4:(... .1. .0.)->0Zerosion4z4:(... .1. ..0)->0Zerosion8z4:(.0. .1. ...)->1z4:(01. .1. ...)->1ZedgezUnknown pattern ú!)ÚpatternsÚlutÚ	Exception)Úselfr	   Úop_nameZknown_patterns© r   úC/var/www/dbchiro/venv/lib/python3.4/site-packages/PIL/ImageMorph.pyÚ__init__3   s(    		




zLutBuilder.__init__c             C   s   |  j  | 7_  d  S)N)r	   )r   r	   r   r   r   Úadd_patternsL   s    zLutBuilder.add_patternsc                sA   d d g ‰ d ‰  t  ‡  ‡ f d d †  t t ƒ Dƒ ƒ |  _ d  S)Nr   r   é   c             3   s#   |  ] } ˆ | ˆ  @d  k Vq d S)r   Nr   )Ú.0Úi)ÚmÚsymbolsr   r   ú	<genexpr>R   s    z/LutBuilder.build_default_lut.<locals>.<genexpr>é   )Ú	bytearrayÚrangeÚLUT_SIZEr
   )r   r   )r   r   r   Úbuild_default_lutO   s    zLutBuilder.build_default_lutc             C   s   |  j  S)N)r
   )r   r   r   r   Úget_lutT   s    zLutBuilder.get_lutc                s8   t  | ƒ d k s t ‚ d j ‡  f d d †  | Dƒ ƒ S)z„string_permute takes a pattern and a permutation and returns the
        string permuted according to the permutation list.
        r   Ú c             3   s   |  ] } ˆ  | Vq d  S)Nr   )r   Úp)Úpatternr   r   r   \   s    z-LutBuilder._string_permute.<locals>.<genexpr>)ÚlenÚAssertionErrorÚjoin)r   r    Zpermutationr   )r    r   Ú_string_permuteW   s    zLutBuilder._string_permutec       	      C   sˆ  | | f g } d | k r… | d d } xY t  d ƒ D]H } | j |  j | d d d d d d d d d d	 d
 g	 ƒ | f ƒ q6 Wn  d | k rû t | ƒ } x[ | d | … D]F \ } } | j |  j | d
 d d d	 d d d d d g	 ƒ | f ƒ q® Wn  d | k r„t | ƒ } xn | d | … D]Y \ } } | j d d ƒ j d d ƒ j d d ƒ } d t | ƒ } | j | | f ƒ q$Wn  | S)zÉpattern_permute takes a basic pattern and its result and clones
        the pattern according to the modifications described in the $options
        parameter. It returns a list of all cloned patterns.Ú4r   r   r   é   é   é   é   é   é   ÚMÚNÚ0ÚZÚ1éÿÿÿÿr1   )r   Úappendr$   r!   ÚreplaceÚint)	r   Zbasic_patternÚoptionsZbasic_resultr	   Úresr   Únr    r   r   r   Ú_pattern_permute^   s2    	 	 zLutBuilder._pattern_permutec       
      C   sÄ  |  j  ƒ  g  } x¶ |  j D]« } t j d | j d d ƒ ƒ } | s[ t d | d ƒ ‚ n  | j d ƒ } | j d ƒ } t | j d ƒ ƒ } | j d	 d ƒ j d d ƒ } | |  j | | | ƒ 7} q Wx_ t	 | ƒ D]Q \ } } | d
 j d d ƒ j d d ƒ } t j
 | ƒ } | | d f | | <qÖ Wx t t ƒ D] } t | ƒ d d … } d d t | ƒ | d d d … } x= | D]5 \ } }	 | j | ƒ r€d
 d g |	 |  j | <q€q€Wq8W|  j S)zlCompile all patterns into a morphology lut.

        TBD :Build based on (file) morphlut:modify_lut
        z(\w*):?\s*\((.+?)\)\s*->\s*(\d)Ú
r   zSyntax error in pattern "ú"r   r+   r'   ú r   Ú.ÚXz[01]Nr.   r   r1   )r   r	   ÚreÚsearchr3   r   Úgroupr4   r8   Ú	enumerateÚcompiler   r   Úbinr!   Úmatchr
   )
r   r	   r   r   r5   r    Úresultr   Z
bitpatternÚrr   r   r   Ú	build_lutƒ   s.    
"%"zLutBuilder.build_lut)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r$   r8   rG   r   r   r   r   r      s   "%r   c               @   ss   e  Z d  Z d Z d d d d d „ Z d d „  Z d d „  Z d	 d
 „  Z d d „  Z d d „  Z	 d d „  Z
 d S)ÚMorphOpz*A class for binary morphological operatorsNc             C   s[   | |  _  | d k	 r0 t d | ƒ j ƒ  |  _  n' | d k	 rW t d | ƒ j ƒ  |  _  n  d S)z&Create a binary morphological operatorNr   r	   )r
   r   rG   )r   r
   r   r	   r   r   r   r   ·   s
    	zMorphOp.__init__c             C   s‹   |  j  d k r t d ƒ ‚ n  | j d k r< t d ƒ ‚ n  t j | j | j d ƒ } t j t |  j  ƒ | j	 j
 | j	 j
 ƒ } | | f S)z‡Run a single morphological operation on an image

        Returns a tuple of the number of changed pixels and the
        morphed imageNzNo operator loadedÚLz0Image must be binary, meaning it must use mode L)r
   r   Úmoder   ÚnewÚsizer   ÚapplyÚbytesÚimÚid)r   ÚimageZoutimageÚcountr   r   r   rQ   Â   s    $zMorphOp.applyc             C   s[   |  j  d k r t d ƒ ‚ n  | j d k r< t d ƒ ‚ n  t j t |  j  ƒ | j j ƒ S)zªGet a list of coordinates matching the morphological operation on
        an image.

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels.NzNo operator loadedrM   z0Image must be binary, meaning it must use mode L)r
   r   rN   r   rD   rR   rS   rT   )r   rU   r   r   r   rD   Ñ   s
    zMorphOp.matchc             C   s1   | j  d k r t d ƒ ‚ n  t j | j j ƒ S)z‹Get a list of all turned on pixels in a binary image

        Returns a list of tuples of (x,y) coordinates
        of all matching pixels.rM   z0Image must be binary, meaning it must use mode L)rN   r   r   Úget_on_pixelsrS   rT   )r   rU   r   r   r   rW   Þ   s    zMorphOp.get_on_pixelsc          	   C   s^   t  | d ƒ  } t | j ƒ  ƒ |  _ Wd QXt |  j ƒ t k rZ d |  _ t d ƒ ‚ n  d S)z!Load an operator from an mrl fileÚrbNzWrong size operator file!)Úopenr   Úreadr
   r!   r   r   )r   ÚfilenameÚfr   r   r   Úload_lutè   s
    	zMorphOp.load_lutc          	   C   sJ   |  j  d k r t d ƒ ‚ n  t | d ƒ  } | j |  j  ƒ Wd QXd S)zSave an operator to an mrl fileNzNo operator loadedÚwb)r
   r   rY   Úwrite)r   r[   r\   r   r   r   Úsave_lutñ   s    zMorphOp.save_lutc             C   s   | |  _  d S)z#Set the lut from an external sourceN)r
   )r   r
   r   r   r   Úset_lutø   s    zMorphOp.set_lut)rH   rI   rJ   rK   r   rQ   rD   rW   r]   r`   ra   r   r   r   r   rL   ´   s   
	rL   i   )
Ú
__future__r   r   r   r   r>   r   Úobjectr   rL   r   r   r   r   Ú<module>   s
   ¤