
    ?g                        d dl Z d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlm	Z	m
Z
mZ  e ed            Zi Zd	gd
z  d gd
z  z   Zi Zg dddgddgdZi Zej)                         D ]  \  ZZeD ]  Zeee<   	  dZdZdZeeegZdZeeeefZeeeefZdZ G d de       Z!	 	 	 dHdZ"i dddd	edfdZ#di dd	efdZ$dIdZ%d  Z&d! Z'd" Z( G d# d$      Z)d% Z*dJd&Z+d' Z,d( Z-dKd)Z.dLd*Z/d+ Z0d, Z1d- Z2d. Z3d/ Z4d0 Z5d1 Z6d2 Z7d3 Z8d4 Z9d5 Z:d6 Z;dLd7Z<d8 Z=d9 Z>dMd:Z?d; Z@d< ZAd= ZBd> ZCd? ZDd@ ZEdA ZFdB ZGdC ZHdD ZIdNdEZJdOdFZKdG ZLy)P    N)StringIO)cycle)Image)	ImageDraw)ImageEnhance)ImageOps
ImageChopsImageFilter         )JPGJPEGJPETIFTIFFSVGSVGZ)r   r   r   CrossRoundedSquarezrounded_corner_r%d_f%dz!rounded_rectangle_r%d_f%d_s%s_p%sc                       e Zd Zy)InvalidWriteFormatErrorN)__name__
__module____qualname__     4/usr/share/cinnamon/cinnamon-settings/bin/imtools.pyr   r   3   s    r   r   c	           
         |i }t        |       r | j                  dk7  r| j                  d      } | j                  }	| j                  }
d}|
dk7  rT|
dk7  r| j                  d      } d}
dj	                  d|	||||||fD cg c]  }t        |       c}      }||v r||   \  }}|)|	d   t        |      z   d|z  z   |	d   t        |      z   d|z  z   f}|
dk(  r#t        |       }t        j                  d	|d      }n.t        j                  |
|	|      }t        j                  |
||      }|t        |d      z   }|t        |d      z   }t        ||||||	d   z   ||	d   z   f       ~d}||k  r*|j                  t        j                        }|dz  }||k  r*|
dk(  r*t        j                  d||      }|j                  |       ~n	|}||f|<   |t!        |d      z
  }|t!        |d      z
  }|
dk(  rpt        || ||f|        |r\t        |      }t        |t        j                  d|j                  |      d
t#        j$                  |             |j                  |       |S t        || ||f       |S c c}w )a  Add a gaussian blur drop shadow to an image.

    :param image: The image to overlay on top of the shadow.
    :param type: PIL Image
    :param offset:

        Offset of the shadow from the image as an (x,y) tuple.
        Can be positive or negative.

    :type offset: tuple of integers
    :param background_color: Background color behind the image.
    :param shadow_color: Shadow color (darkness).
    :param border:

        Width of the border around the image.  This must be wide
        enough to account for the blurring of the shadow.

    :param shadow_blur:

        Number of times to apply the filter.  More shadow_blur
        produce a more blurred shadow, but increase processing time.
    NRGBARGB shadow_r         Lr   r   )has_transparencymodeconvertsizejoinstrabs	get_alphar   newmaxpastefilterr
   BLURputalphaminr	   invert)imagehorizontal_offsetvertical_offsetbackground_colorshadow_colorbordershadow_blurforce_background_colorcacher,   r*   backxid	back_size
image_maskshadowshadow_left
shadow_topn
image_left	image_topmasks                          r   drop_shadowrN   7   s   2 }5::#7f% ::D::DD v~5=MM%(EDWWy$'8/6S^'7'G Hc!f H I
 ;#BiOD)|!Ws#455F
B!Ws?33a&j@B	 6>"5)JYYsIq1F4|<JYYtY0@AFs#4a88c/155
fj;
#.a#8*tAw:N#P 	Q +o]];#3#34FFA +o
 6>99VY=DMM&!DiE"I #/33J_a00Iv~dEJ	2E:!T?D$		%4DE*++D13MM$ K 	dEJ	23KyHs   >I3Td   z#FFFFFFc                 *   | j                   dk7  r| j                  d      } |rd|fz  }t        | j                  ||||      }t	        | t        j                  d| j                  |      dt        j                  |             | j                  |       | S )Nr!      r"   r(   )
r*   r+   create_rounded_rectangler,   r3   r   r1   r	   r8   r6   )	r9   rA   	round_allrounding_typeradiusopacitypos
back_colorrM   s	            r   round_imagerY      s     zzVf%=###EJJvwLD	%5%**j96


D
!#	NN4Lr   )iX  i  c                    | \  }}t         ||| |fz  }||v r||   S t         ||| t        fz  }||v r||   }	net        j                  d| d      x}	||<   t	        j
                  |	      }
|
j                  |d||z
  |f|       |
j                  d||||z
  f|       |t        k(  r|	S t        ||fz  }||v r||   }nt        ||      x}||<   t        j                  d||fd      }|	j                         }t        |      D ]  \  }}|t        k(  r|t        k(  r|}n|}|dz  r%||z
  }|j                  t        j                        }nd}|dk  rd}n$||z
  }|j                  t        j                        }t!        ||||f        |||<   |S )Nr'   r   fillr   r%   )ROUNDED_RECTANGLE_ID	CROSS_POSr   r1   r   Draw	rectangle	CORNER_IDcreate_cornercopy	enumerateCROSSROUNDED	transposeFLIP_LEFT_RIGHTFLIP_TOP_BOTTOMr3   )r,   rA   rU   rV   rW   im_xim_yrounded_rectangle_idcross_idcrossdraw	corner_idcornerr`   rounded_rectangleindexangleelementrC   ys                       r   rR   rR      s    JD$/67D#2NNu$)** (67D)*LLu(OE&+iiT1&==EE(O>>%(DNNFAtf}d;'NJNNAvtTF];'NJ)L 11	9%F(5fg(FFFU9%IIcFF#3S9	!JJL%cN 	6LE5~ #qy6M!++E,A,ABqy6M!++E,A,AB#Wq!f5#	6$ '8"#  r   c                     t        j                  d|| z  || z  fd      }t        j                  |      }|j	                  ddd|z  | z  d|z  | z  fdd|       |j                  | | ft         j                        }|S )Nr'   r   r%      i  r[   )r   r1   r   r_   piesliceresizeLANCZOS)rU   rV   factorrq   ro   s        r   rb   rb      s    YYsVf_fvo>BF>>&!DMM1aVf,a&j6.ABs  *]]FF+U]];FMr   c                 l    | j                  d      j                         } t        j                  | |       S )a[  Guess the image format by the file extension.

    :param ext: file extension
    :type ext: string
    :returns: image format
    :rtype: string

    .. warning::

        This is only meant to check before saving files. For existing files
        open the image with PIL and check its format attribute.

    >>> get_format('jpg')
    'JPEG'
    .)lstripupperFORMATS_BY_EXTget)exts    r   
get_formatr      s-      **S/


!Cc3''r   c                 >    t        j                  t        |             S )zOpen image from format data.

    :param data: image format data
    :type data: string
    :returns: image
    :rtype: pil.Image
    )r   openr   )datas    r   open_image_datar      s     ::htn%%r   c                 *    t        t        |             S )zOpen local files or remote files over http and transpose the
    image to its exif orientation.

    :param uri: image location
    :type uri: string
    :returns: image
    :rtype: pil.Image
    )transpose_exif
open_image)uris    r   open_image_exifr     s     *S/**r   c                       e Zd ZdZd Zd Zy)_ByteCounterzHelper class to count how many bytes are written to a file.

    .. see also:: :func:`get_size`

    >>> bc = _ByteCounter()
    >>> bc.write('12345')
    >>> bc.bytes
    5
    c                     d| _         y )Nr   )bytes)selfs    r   __init__z_ByteCounter.__init__  s	    
r   c                 @    | xj                   t        |      z  c_         y N)r   len)r   r   s     r   writez_ByteCounter.write!  s    

c$i
r   N)r   r   r   __doc__r   r   r   r   r   r   r     s     r   r   c                     	 t               } | j                  ||fi | |j                  S # t        $ r: t	               } | j                  ||fi | t        |j                               cY S w xY w)zGets the size in bytes if the image would be written to a file.

    :param format: image file format (e.g. ``'JPEG'``)
    :type format: string
    :returns: the file size in bytes
    :rtype: int
    )r   saver   AttributeErrorr   r   getvalue)imformatoptionsouts       r   get_sizer   %  si    #nV'w'yy #jV'w'3<<>""	#s   ), A A/.A/c                     |i }||z   dz  x}|d<   ||k(  s||k(  rt        |d      S t        | |fi |}t        ||z
        |k  r|S ||kD  rt        | |||||      S t        | |||||      S )a  Figure out recursively the quality save parameter to obtain a
    certain image size. This mostly used for ``JPEG`` images.

    :param im: image
    :type im: pil.Image
    :param format: image file format (e.g. ``'JPEG'``)
    :type format: string
    :param down: minimum file size in bytes
    :type down: int
    :param up: maximum file size in bytes
    :type up: int
    :param delta: fault tolerance in bytes
    :type delta: int
    :param options: image save options
    :type options: dict
    :returns: save quality
    :rtype: int

    Example::

        filename = '/home/stani/sync/Desktop/IMGA3345.JPG'
        im = Image.open(filename)
        q = get_quality(im, 300000, "JPEG")
        im.save(filename.replace('.jpg', '_sized.jpg'))
    r%   qualityr&   )upr   )downr   r   )r2   r   r/   get_quality)	r   r,   r   r   r   deltar   qss	            r   r   r   8  s    4 "Ri1_,A	DyAG1ayV'w'A
1t8}u	
T2tVTaII2tV!GLLr   c                 v   | j                   dk(  r| j                  d      } n.| j                   dk7  r| j                   dk(  rd| j                  v s| S t        |      dk(  r|d   dk7  rd}nd}t	        j
                  || j                  |      }| j                   dk(  r|dk(  r| j                  d      } t        |       rt        || | 	       |S | j                   dk(  rR| j                         }| j                  d   }|d
d ||dz  |dz  dz    | j                  |       | j                  d= | }|S t        ||        |S )zFills given image with background color.

    :param image: source image
    :type image: pil.Image
    :param color: background color
    :type color: tuple of int
    :returns: filled image
    :rtype: pil.Image
    LAr!   PtransparencyrQ   r   r"   )rM   N   )r*   r+   infor   r   r1   r,   	has_alphar3   
getpalette
putpalette)r9   colorr*   rB   paletters   s         r   fill_background_colorr   `  s6    zzTf%	v	s"~'C
5zQ59+99T5::u-DzzSTV^f%dE& K 
s	""$

>*,1"1I	519q=)!JJ~& K 	dEKr   c	                 Z   t        t        |            }|dz  }t        ||      }t        j                  d| d      }	|dk(  rUt        d| d   |j                  d         D ]3  }
t        d| d   |j                  d         D ]  }t        |	|||
f        5 |	S |dk(  rt        t        | d         |j                  d   z  t        | d         |j                  d   z        }t        |j                  d   |z        }t        |j                  d   |z        }|j                  ||f      }t        |	|| d   |z
  dz  | d   |z
  dz  f       |	S |d	k(  rNt        ||||| |j                        }|r!t        t        |      }|j                  |      }t        |	||d
       |	S t        d|z        )a  Generate new layer for backgrounds or watermarks on which a given
    image ``mark`` can be positioned, scaled or repeated.

    :param image_size: size of the reference image
    :type image_size: tuple of int
    :param mark: image mark
    :type mark: pil.Image
    :param method: ``'Tile'``, ``'Scale'``, ``'By Offset'``
    :type method: string
    :param horizontal_offset: horizontal offset
    :type horizontal_offset: int
    :param vertical_offset: vertical offset
    :type vertical_offset: int
    :param horizontal_justification: ``'Left'``, ``'Middle'``, ``'Right'``
    :type horizontal_justification: string
    :param vertical_justification: ``'Top'``, ``'Middle'``, ``'Bottom'``
    :type vertical_justification: string
    :param orientation: mark orientation (e.g. ``'ROTATE_270'``)
    :type orientation: string
    :param opacity: opacity within ``[0, 1]``
    :type opacity: float
    :returns: generated layer
    :rtype: pil.Image

    .. see also:: :func:`reduce_opacity`
    g      Y@r!   )r   r   r   r   Tiler   r&   Scaler%   z	By OffsetT)forcez'Unknown method "%s" for generate_layer.)convert_safe_moder   reduce_opacityr   r1   ranger,   r3   r7   floatintrz   calculate_locationgetattrrg   
ValueError)
image_sizemarkmethodr:   r;   horizontal_justificationvertical_justificationorientationrV   layerrv   rC   ratiowhlocationorientation_values                    r   generate_layerr     s   < Z-.DuG$(DIIfj,7Eq*Q-16 	+A1jmTYYq\: +eTAq6*+	+. L) 
7	E*Q-(499Q<7*Q-(499Q<79		!u$%		!u$%{{Aq6"eTZ]Q.!3']Q.!35 	6 L 
;	%$&<		#  '{ ;>>"34DeT840 L BVKLLr   c                 ~    | j                         }t        |      dk(  r|S t        |D cg c]  }| c}      S c c}w )zGet a color with same color component values.

    >>> im = Image.new('RGB', (1,1))
    >>> identity_color(im, 2)
    (2, 2, 2)
    >>> im = Image.new('L', (1,1))
    >>> identity_color(im, 7)
    7
    r&   )getbandsr   tuple)r9   valuebandsbands       r   identity_colorr     s9     NNE
5zQE*D%*++*s   	:c                    t        |      }| j                  |j                  k(  rt        | |j                        } n|+t	        j
                  |j                  |j                        }nz|j                  dv rAt        |      t        k7  r/t	        j
                  |j                  |j                  |d         }n+t	        j
                  |j                  |j                  |      }| j                  |j                        } |j                  \  }}| j                  \  }}t        || ||z
  dz  ||z
  dz  f| j                  d             |} t	        j                  | ||      S )a  Blend two images with each other. If the images differ in size
    the color will be used for undefined pixels.

    :param im1: first image
    :type im1: pil.Image
    :param im2: second image
    :type im2: pil.Image
    :param amount: amount of blending
    :type amount: int
    :param color: color of undefined pixels
    :type color: tuple
    :returns: blended image
    :rtype: pil.Image
    )1r'   r   r%   r!   )
r   r,   r+   r*   r   r1   typer   r3   blend)	im1im2amountr   expandedwehewihis	            r   r   r     s    C
 C
xx388c388$=yy3884HXX#Us(:yy388U1X>Hyy388U;Hkk(--(BBhrBw!mb2g];kk&!	#;;sC((r   c                     |dk  s|dkD  r| S t        |       }t        j                  |      j                  |      }t	        | |       | S )a  Returns an image with reduced opacity if opacity is
    within ``[0, 1]``.

    :param im: source image
    :type im: pil.Image
    :param opacity: opacity within ``[0, 1]``
    :type opacity: float
    :returns im: image
    :rtype: pil.Image

    >>> im = Image.new('RGBA', (1, 1), (255, 255, 255))
    >>> im = reduce_opacity(im, 0.5)
    >>> im.getpixel((0,0))
    (255, 255, 255, 127)
    r   r&   )r0   r   
Brightnessenhance	put_alpha)r   rV   alphas      r   r   r     sI      {gk	bME##E*227;Eb%Ir   c                     |\  }}|\  }}	| dk  r| |z  } |dk  r||z  }|dk(  rd}
n|dk(  r| dz  }
n|dk(  r| }
|dk(  rd}n|dk(  r|	 dz  }n|dk(  r|	 }| 
z   |z   fS )aY  Calculate location based on offset and justification. Offsets
    can be positive and negative.

    :param horizontal_offset: horizontal offset
    :type horizontal_offset: int
    :param vertical_offset: vertical offset
    :type vertical_offset: int
    :param horizontal_justification: ``'Left'``, ``'Middle'``, ``'Right'``
    :type horizontal_justification: string
    :param vertical_justification: ``'Top'``, ``'Middle'``, ``'Bottom'``
    :type vertical_justification: string
    :param canvas_size: size of the total canvas
    :type canvas_size: tuple of int
    :param image_size: size of the image/text which needs to be placed
    :type image_size: tuple of int
    :returns: location
    :rtype: tuple of int

    .. see also:: :func:`generate layer`

    >>> calculate_location(50, 50, 'Left', 'Middle', (100,100), (10,10))
    (50, 45)
    r   LeftMiddler%   RightTopBottomr   )r:   r;   r   r   canvas_sizer   canvas_widthcanvas_heightimage_widthimage_heighthorizontal_deltavertical_deltas               r   r   r     s    4 #.L- *K 1\)=(  6)	!X	-'<!+	!W	,'<&	8	+&*	8	+&//.() )r   c                 @    | D cg c]  }|D ]  }|  c}}S c c}}w )zFlatten a list.

    :param l: list to be flattened
    :type l: list
    :returns: flattened list
    :rtype: list

    >>> flatten([[1, 2], [3]])
    [1, 2, 3]
    r   )lsublistitems      r   flattenr   F  s$     !"6Wg6dD6D666s   c                 8    | j                   j                  d      S )a  Checks if the image has an alpha band.
    i.e. the image mode is either RGBA or LA.
    The transparency in the P mode doesn't count as an alpha band

    :param image: the image to check
    :type image: PIL image object
    :returns: True or False
    :rtype: boolean
    A)r*   endswithr9   s    r   r   r   T  s     ::s##r   c                 Z    | j                   dk(  xr d| j                  v xs t        |       S )zChecks if the image has transparency.
    The image has an alpha band or a P mode with transparency.

    :param image: the image to check
    :type image: PIL image object
    :returns: True or False
    :rtype: boolean
    r   r   )r*   r   r   r   s    r   r)   r)   a  s0     JJ#>.EJJ"> %r   c                     t        |       r| j                         d   S | j                  dk(  r0d| j                  v r"| j	                  d      j                         d   S t        j                  d| j                  d      S )a  Gets the image alpha band. Can handle P mode images with transparency.
    Returns a band with all values set to 255 if no alpha band exists.

    :param image: input image
    :type image: PIL image object
    :returns: alpha as a band
    :rtype: single band image object
    r   r   r   r!   r'   r   )r   splitr*   r   r+   r   r1   r,   r   s    r   r0   r0   n  sh     {{}R  zzS^uzz9}}V$**,R0099S%**c**r   c                 n    t               }t        | |      j                  ||       |j                         S )as  Convert the image in the file bytes of the image. By consequence
    this byte data is different for the chosen format (``JPEG``,
    ``TIFF``, ...).

    .. see also:: :func:`thumbnail.get_format_data`

    :param image: source image
    :type impage: pil.Image
    :param format: image file type format
    :type format: string
    :returns: byte data of the image
    )r   convert_save_mode_by_formatr   r   )r9   r   fs      r   get_format_datar    s.     	
Av.33Av>::<r   c                     | j                  d      }|j                  t        d             t        |j	                  d      j                               S )zGets the palette of an image as a sequence of (r, g, b) tuples.

    :param image: image with a palette
    :type impage: pil.Image
    :returns: palette colors
    :rtype: a sequence of (r, g, b) tuples
    )r   r&   r   r"   )rz   putdatar   listr+   getdata)r9   r   s     r   get_paletter	    s?     ll8$GOOE#J&..011r   c                 4    t        | j                               S )zGet used color indices in an image palette.

    :param image: image with a palette
    :type impage: pil.Image
    :returns: used colors of the palette
    :rtype: set of integers (0-255)
    )setr  r   s    r   get_used_palette_indicesr    s     u}}r   c                    t        |       }d| j                  v r|t        | j                  d   g      z  }t        |      }| j	                  |df      }|j                  |       |j                  d      j                         S )zGet used colors in an image palette as a sequence of (r, g, b) tuples.

    :param image: image with a palette
    :type impage: pil.Image
    :returns: used colors of the palette
    :rtype: sequence of (r, g, b) tuples
    r   r&   r"   )r  r   r  r   rz   r  r+   r  )r9   used_indicesrJ   r   s       r   get_used_palette_colorsr    su     ,E2L#UZZ7899LAllAq6"GOOL!??5!))++r   c                 &    t         t        |       z
  S )zGet unused color indices in an image palette.

    :param image: image with a palette
    :type impage: pil.Image
    :returns: unused color indices of the palette
    :rtype: set of 0-255
    )ALL_PALETTE_INDICESr  r   s    r   get_unused_palette_indicesr    s     !9%!@@@r   c                 p   t        |       }	 |j                  |      }|dkD  r3	 || j                  d   k(  }|r	 ||dz   d j                  |      |z   dz   }|dk(  r&t        t        |             }|r|d   }|||<   ||fS d}||fS # t        $ r d}Y tw xY w# t        $ r d}Y mw xY w# t        $ r d}Y ^w xY w)a  Fit a color into a palette. If the color exists already in the palette
    return its current index, otherwise add the color to the palette if
    possible. Returns -1 for color index if all colors are used already.

    :param image: image with a palette
    :type image: pil.Image
    :param color: color to fit
    :type color: (r, g, b) tuple
    :returns: color index, (new) palette
    :rtype: (r, g, b) tuple, sequence of (r, g, b) tuples
    r   r   Fr&   Nr   )r	  rs   r   r   KeyErrorr  r  )r9   r   r   rs   transparentunuseds         r   fit_color_in_paletter    s     % Ge$ rz	 5::n#==K 	
+11%85@1D {0781IE"GEN '> G'>+    	 K	   s3   B B B' BBB$#B$'B54B5c                     |t        |      }| j                  t        |             d|j                  v r|j                  d   | j                  d<   yy)a0  Copies the palette and transparency of one image to another.

    :param image_to: image with a palette
    :type image_to: pil.Image
    :param image_from: image with a palette
    :type image_from: pil.Image
    :param palette: image palette
    :type palette: sequence of (r, g, b) tuples or None
    Nr   )r	  r   r   r   )image_to
image_fromr   s      r   put_paletter    sN     j)()((2(Gn% )r   c                     | j                   dv r| j                  d      } n| j                   dv r| j                  d      } | j                  |       y)zCopies the given band to the alpha layer of the given image.

    :param image: input image
    :type image: PIL image object
    :param alpha: the alpha band to copy
    :type alpha: single band image object
    )CMYKYCbCrr   r!   r   FN)r*   r+   r6   )r9   r   s     r   r   r     sE     zz++f%	z	!f%	NN5r   c                     | j                   dk(  r| j                  d      S | j                   dk(  r| j                  d      S | j                   dk(  r.d| j                  v r | j                  d      }|j                  d= |S | S )zReturns a copy of the image after removing the alpha band or
    transparency

    :param image: input image
    :type image: PIL image object
    :returns: the input image after removing the alpha band or transparency
    :rtype: PIL image object
    r!   r"   r   r'   r   r   r*   r+   r   r9   imgs     r   remove_alphar%    su     zzV}}U##zzT}}S!!zzS^uzz9mmE"HH^$
Lr   c                     |r||k(  rt        |      rt        |       r| j                  |j                  k(  s|r~t        j                  t	        |             }|j                  |j                  k7  rIt        |      dk(  r'|j                  \  }}|d   |d   |d   |z   |d   |z   f}|j                  |      }nd}t        |      }| j                  |||       |Ct	        |       }	| j                  |||       | j                  |	       y| j                  ||       yy|r| j                  |||       y| j                  ||       |rFt        |      r:t	        |       }	t	        |      }
|	j                  |
|       | j                  |	       yyy)a=  "Pastes the source image into the destination image while using an
    alpha channel if available.

    :param destination: destination image
    :type destination:  PIL image object
    :param source: source image
    :type source: PIL image object
    :param box:

        The box argument is either a 2-tuple giving the upper left corner,
        a 4-tuple defining the left, upper, right, and lower pixel coordinate,
        or None (same as (0, 0)). If a 4-tuple is given, the size of the
        pasted image must match the size of the region.

    :type box: tuple
    :param mask: mask or None

    :type mask: bool or PIL image object
    :param force:

        With mask: Force the invert alpha paste or not.

        Without mask:

        - If ``True`` it will overwrite the alpha channel of the destination
          with the alpha channel of the source image. So in that case the
          pixels of the destination layer will be abandoned and replaced
          by exactly the same pictures of the destination image. This is mostly
          what you need if you paste on a transparent canvas.
        - If ``False`` this will use a mask when the image has an alpha
          channel. In this case pixels of the destination image will appear
          through where the source image is transparent.

    :type force: bool
    r%   r   r&   N)
r   r,   r   r8   r0   r   cropr%  r3   r6   )destinationsourceboxrM   r   invert_alphar   r   source_without_alphadestination_alphasource_alphas              r   r3   r3      s   J $V%;+;+;v{{+J.3'y/EF$$3 3x1}%{{1"1vs1vs1vz3q6A:F#/#4#4S#9L##/#7 2C@'$-k$:! !!"6\J$$%67fc* ( 
&#t,&#&Yv& )+ 6$V,L##L#6  !23	 '5r   c                 l    t        |       }|j                         }t        |       j                  |      S )zCrops all transparent or black background from the image
    :param image: input image
    :type image: PIL image object
    :returns: the cropped image
    :rtype: PIL image object
    )r0   getbboxr   r'  )r9   r   r*  s      r   	auto_cropr1  n  s/     eE
--/CU#((--r   c                    |dk(  r| j                   dk(  r| S | j                   dv r% | j                  d      j                  |g|i |S | j                   dv rct        |       } | j                  d      j                  |g|ddi|}t        |d|j	                  t
                     d|j                  d<   |S  | j                  d      j                  |g|i |S | j                   dk(  r*|d	k(  r% | j                  d
      j                  d	g|i |S t        |       rI|dvrE| j                   dk(  r| j                  d
      } | j                  d=  | j                  |g|i |} | S  | j                  |g|i |S )aj  Returns a converted copy of an image

    :param image: input image
    :type image: PIL image object
    :param mode: the new mode
    :type mode: string
    :param args: extra options
    :type args: tuple of values
    :param keyw: extra keyword options
    :type keyw: dictionary of options
    :returns: the converted image
    :rtype: PIL image object
    r   r  r'   )r!   r   r"   colorsr   r   r   r!   )r*   r+   r0   r3   point	COLOR_MAPr   r)   )r9   r*   argskeywr   outputs         r   r+   r+   {  s    s{::L::#-5==%--dBTBTBB::'e$E1U]]5)111#'1 1+/1F&u{{9-/*-FKK'M+u}}U#++D@4@4@@zzSTT\ -u}}V$,,TADADAAD$>::MM&)E

>*d2T2T25==----r   c                     | j                   dv r| j                  d      S | j                   dk(  r.d| j                  v r | j                  d      }|j                  d= |S | j                   dv r| j                  d      S | S )zConverts image into a processing-safe mode.

    :param image: input image
    :type image: PIL image object
    :returns: the converted image
    :rtype: PIL image object
    r  r'   r   r   r!   )r   r  r  RGBXr"   r"  r#  s     r   r   r     sv     zzZ}}S!!zzS^uzz9mmF#HH^$
zz33}}U##Lr   c                 ~   | j                   dk(  r|dvrt        |       } |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   d	v r| j                  d      S | j                         S |d
k(  r/| j                   dv r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  rt        | dt        j                        S |dk(  r0| j                   dk7  r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  r0| j                   dk7  r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  rN| j                   dv r| j                  d      S | j                   dv r| j                  d      S | j                         S |dk(  r/| j                   dvr| j                  d      S | j                         S |dk(  r/| j                   dv r| j                  d      S | j                         S |d k(  r| j                   d!v r| j                  d      S | j                         S )"zConverts image into a saving-safe mode.

    :param image: input image
    :type image: PIL image object
    :param format: target format
    :type format: string
    :returns: the converted image
    :rtype: PIL image object
    r   )GIFPNGr   IMPCXr   )r!   r   r"   )r   r'   BMP)r   r!   r  r  DIB)r  r  EPS)r   r   )r   r!   r  r<  )r   PBMr   r?  )r!   r  r  )r   r   PDF)r!   r  PGMPPM)r   r  r  PSXBM)r   r   )r  r=  )r  r  )r*   r%  r+   r   ADAPTIVErc   )r9   r   s     r   r  r    s    zzS<< 'E::&==''::==%%h ::<g 
5::==%%::77==''^ ::<] 
5::**==''X ::<W 
5::$==%%:://==''N ::<M 
5uc5>>::	5::==%%D ::<C 
5::22==''::$==%%: ::<9 
5::==%%::**==''0 ::</ 
5::==%%* ::<) 
5:://==''::==%%  ::< 
4::$==%%:://=='' ::< 
5::U"==%% ::< 
6	::"==''
 ::<	 
5::**==''::<r   c                     t        | |fi | 	 t        j                  |      }|j                          | j
                  |j
                  k7  r|j
                  S y# t        $ r Y yw xY w)Nr#   )r   r   r   verifyIOErrorr*   )r9   filenamer   
image_files       r   save_check_moderO    sc    $G$ZZ)
 zzZ__$  s   %A 	A&%A&c                     t         j                  j                  |      d   }t        |dd       }t	        | |      } t        | |       y)a(  Saves an image with a filename and raise the specific
    ``InvalidWriteFormatError`` in case of an error instead of a
    ``KeyError``. It can also save IM files with unicode.

    :param image: image
    :type image: pil.Image
    :param filename: image filename
    :type filename: string
    r   r&   N)ospathsplitextr   r  r   )r9   rM  r   r   s       r   save_safelyrT    sC     ''

8
$R
(CAB F'v6Er   c                     | t         j                  k(  rt         j                  S | t         j                  k(  rt         j                  S | S )zGet the reverse transposition method.

    :param transposition: transpostion, e.g. ``Image.ROTATE_90``
    :returns: inverse transpostion, e.g. ``Image.ROTATE_270``
    )r   	ROTATE_90
ROTATE_270)transpositions    r   get_reverse_transpositionrY  !  s:     '	%**	*r   c                    | dk(  rdx}}||fS | dk(  r&t         j                  f}t         j                  f}||fS | dk(  r&t         j                  f}t         j                  f}||fS | dk(  r&t         j                  f}t         j                  f}||fS | dk(  rDt         j                  t         j                  f}t         j
                  t         j                  f}||fS | dk(  r&t         j
                  f}t         j                  f}||fS | dk(  rDt         j                  t         j
                  f}t         j                  t         j                  f}||fS | d	k(  r&t         j                  f}t         j
                  f}||fS dx}}||fS )
zGet the transposition methods necessary to align the image to
    its exif orientation.

    :param orientation: exif orientation
    :type orientation: int
    :returns: (transposition methods, reverse transpostion methods)
    :rtype: tuple
    r&   r   r%   r   rQ               )r   rh   
ROTATE_180ri   rV  rW  )r   rX  transposition_reverses      r   get_exif_transpositionra  .  s    a022-8 ///7 
	--. % 5 5 62 ///1 
	(() % 0 0 1, ///+ 
	--. % 5 5 6& ///% 
	--OO % 0 0!!!" /// 
	(() % 0 /// 
	-- %!!!" /// 
	( % 0 0 1 /// 132-///r   c                 l    t        | d      sy	 | j                         }|sy|d   S # t        $ r Y yw xY w)zGets the exif orientation of an image.

    :param image: image
    :type image: pil.Image
    :returns: orientation
    :rtype: int
    _getexifr&   i  )hasattrrc  r  )r9   _exifs     r   get_exif_orientationrf  X  sD     5*% V} s   ' ' 	33c                 6    |D ]  }| j                  |      }  | S )zTranspose with a sequence of transformations, mainly useful
    for exif.

    :param image: image
    :type image: pil.Image
    :param methods: transposition methods
    :type methods: list
    :returns: transposed image
    :rtype: pil.Image
    )rg   )r9   methodsr   s      r   rg   rg   k  s&      ('(Lr   c                 f    t        |       }t        |      t        |         }|rt        | |      S | S )zTranspose an image to its exif orientation.

    :param image: image
    :type image: pil.Image
    :param reverse: False when opening, True when saving
    :type reverse: bool
    :returns: transposed image
    :rtype: pil.Image
    )rf  ra  r   rg   )r9   reverser   rX  s       r   r   r   {  s6     'u-K*;7GEM..Lr   c                   	
 | t         vrt        |       }t        |z        dz   	fd

fdt        j                  d| |      }t        j                  |      j                  }	fdt        t        d      t        	            D        }|D ]  } |||        |t         | <   t         |    j                         S )a  Draw an n x n checkboard, which is often used as background
    for transparent images. The checkboards are stored in the
    ``CHECKBOARD`` cache.

    :param delta: dimension of one square
    :type delta: int
    :param fg: foreground color
    :type fg: tuple of int
    :param bg: background color
    :type bg: tuple of int
    :returns: checkboard image
    :rtype: pil.Image
    r&   c                     | z  S )z9Return the x/y start coord of the square at column/row i.r   )ir   s    r   sq_startzcheckboard.<locals>.sq_start  s    u9r   c                 0    t        | || dz   |dz   g      S )zReturn the square cornersr&   )map)rm  jrn  s     r   squarezcheckboard.<locals>.square  s!    x!QAq1u!566r   r"   c              3   Z   K   | ]"  \  }}t        |d       D ]  } ||        $ yw)r%   N)r   ).0i_startrq  rm  rJ   rr  s       r   	<genexpr>zcheckboard.<locals>.<genexpr>  s>      2!w!'1a02 !Q< 2< 2s   (+)r   r&   r[   )
CHECKBOARDr2   r   r   r1   r   r_   r`   zipr   r   rc   )r,   r   fgbgdimr9   draw_squaresquaressqrJ   rn  rr  s    `       @@@r   
checkboardr    s     :$ieq 		7 		%r*nnU+552%(va%A2  	%B$	% 
4d  ""r   c                     | j                   dk(  rd| j                  v s| j                   j                  d      r6| j                  d      } t	        | j
                        }t        || d|        |S | S )a  "If the image has a transparent mask, a RGB checkerboard will be
    drawn in the background.

    .. note::

        In case of a thumbnail, the resulting image can not be used for
        the cache, as it replaces the transparency layer with a non
        transparent checkboard.

    :param image: image
    :type image: pil.Image
    :returns: image, with checkboard if transparent
    :rtype: pil.Image
    r   r   r   r!   r(   )r*   r   r   r+   r  r,   r3   )r9   image_bgs     r   add_checkboardr    sa     	

cn

:JJ$f%ejj)hvu-r   )r[  r[  )r   r   r   r   iDDD r^  r   FN)rO   r   r%   )r   rO   i  N)r   r   )r(   NF)F)r^  )r   r   r   )   r  r  )MrQ  ior   	itertoolsr   PILr   r   r   r   r	   r
   r  r   r  rw  r5  	WWW_CACHEEXT_BY_FORMATSr   itemsr   extsr   re   rf   SQUARECORNERSra   r^   ROUNDED_POSr]   	Exceptionr   rN   rY   rR   rb   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r)   r0   r  r	  r  r  r  r  r  r   r%  r3   r1  r+   r   r  rO  rT  rY  ra  rf  rg   r   r  r  r   r   r   <module>r     s  $ 
      1 1%*o 
ECK1#)#		 #FO6?
 "((* %LFD %$s%% 	
	FE
"$	E5%(	'2: 	i 	 =>BJMQhT  4tC[Y  #-Bs%(k/!b(&&	+   "#&%MP!H:z, )D03)v7
$
+"$
2 ,"A$NH"(K4\
.'.T&GT 
'0T& ""#Jr   