§
    ‡Ûg¤J  ã                   ó  — 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mZ ddlZddl	Z	ddl
Z
ddlmZmZ ddlZddlZddlmZ ddlZddlmZ ddlmZ  ej        e¦  «        Zg d¢Zd	„ Zd
„ Zd„ Zd#d„Z G d„ de ¦  «        Z! G d„ d¦  «        Z" G d„ de"¦  «        Z# G d„ de"¦  «        Z$ G d„ de$¦  «        Z%d„ Z&i Z' e&¦   «           e%¦   «         Z(d„ Z)d„ Z*d„ Z+ ej,        ¦   «         d„ ¦   «         Z-d„ Z.d„ Z/d„ Z0d$d!„Z1d"„ Z2dS )%z(
Utilities for comparing image results.
é    N)ÚPath)ÚTemporaryDirectoryÚTemporaryFile)ÚImage)Úcbook)ÚImageComparisonFailure)Úcalculate_rmsÚcomparable_formatsÚcompare_imagesc                 óX   — t           j                             | ¦  «        \  }}|›d|›|›�S )zQ
    Make a new filename by inserting *purpose* before the file's extension.
    ú-)ÚosÚpathÚsplitext)ÚfnameÚpurposeÚbaseÚexts       úP/granary/edev/quantum/lib/python3.11/site-packages/matplotlib/testing/compare.pyÚmake_test_filenamer      s2   € õ ”× Ò  Ñ'Ô'�I€Dˆ#Ø˜˜˜g˜g s sÐ+Ð+ó    c                  óv   — t          t          j        ¦   «         d¦  «        } |                      dd¬¦  «         | S )NÚ
test_cacheT)ÚparentsÚexist_ok)r   ÚmplÚget_cachedirÚmkdir)Ú	cache_dirs    r   Ú_get_cache_pathr    %   s6   € Ý•SÔ%Ñ'Ô'¨Ñ6Ô6€IØ‡O‚O˜D¨4€OÑ0Ô0Ð0ØÐr   c                  ó8   — t          t          ¦   «         ¦  «        S ©N)Ústrr    © r   r   Úget_cache_dirr%   +   s   € Ý�Ñ Ô Ñ!Ô!Ð!r   é   c                 ó’  — t          j        ¦   «         }t          | d¦  «        5 }	 |                     |¦  «        }|sn|                     |¦  «         Œ.	 d d d ¦  «         n# 1 swxY w Y   t          | ¦  «        j        dk    rM|                     t          t          j	        d¦  «        j
        ¦  «                             d¦  «        ¦  «         ndt          | ¦  «        j        dk    rL|                     t          t          j	        d¦  «        j
        ¦  «                             d¦  «        ¦  «         |                     ¦   «         S )NÚrbTz.pdfÚgszutf-8ú.svgÚinkscape)ÚhashlibÚmd5ÚopenÚreadÚupdater   Úsuffixr#   r   Ú_get_executable_infoÚversionÚencodeÚ	hexdigest)r   Ú
block_sizer-   ÚfdÚdatas        r   Úget_file_hashr9   /   s]  € Ý
Œ+‰-Œ-€CÝ	ˆd�DÑ	Ô	ð ˜Rð	Ø—7’7˜:Ñ&Ô&ˆDØð ØØ�JŠJ�tÑÔÐð		ð ð	ð ð ñ ô ð ð ð ð ð ð øøøð ð ð ð õ ˆD�z„zÔ˜FÒ"Ð"Ø�
Š
•3•sÔ/°Ñ5Ô5Ô=Ñ>Ô>ß’F˜7‘O”Oñ	%ô 	%ð 	%ð 	%å	ˆd‰ŒÔ	˜fÒ	$Ð	$Ø�
Š
•3•sÔ/°
Ñ;Ô;ÔCÑDÔDß’F˜7‘O”Oñ	%ô 	%ð 	%ð �=Š=‰?Œ?Ðs   ¤0A!Á!A%Á(A%c                   ó   — e Zd ZdS )Ú_ConverterErrorN)Ú__name__Ú
__module__Ú__qualname__r$   r   r   r;   r;   B   s   € € € € € Ø€Dr   r;   c                   ó    — e Zd Zd„ Zd„ Zd„ ZdS )Ú
_Converterc                 óF   — d | _         t          j        | j        ¦  «         d S r"   )Ú_procÚatexitÚregisterÚ__del__)Úselfs    r   Ú__init__z_Converter.__init__G   s#   € ØˆŒ
õ
 	Œ˜œÑ%Ô%Ð%Ð%Ð%r   c                 ó  — | j         rƒ| j                              ¦   «          | j                              ¦   «          t          d | j         j        | j         j        | j         j        g¦  «        D ]}|                     ¦   «          Œd | _         d S d S r"   )rB   ÚkillÚwaitÚfilterÚstdinÚstdoutÚstderrÚclose)rF   Ústreams     r   rE   z_Converter.__del__O   s�   € ØŒ:ð 	ØŒJ�OŠOÑÔÐØŒJ�OŠOÑÔÐÝ  ¨¬
Ô(8Ø(,¬
Ô(9Ø(,¬
Ô(9ð(;ñ <ô <ð ð �ð —’‘”��ØˆDŒJˆJˆJð	ð 	r   c                 ó2  — t          ¦   «         }	 | j        j                             d¦  «        }|s.t	          t          j        t          |¦  «        ¦  «        ¦  «        ‚|                     |¦  «         | 	                    |¦  «        rt          |¦  «        S Œ‰)z!Read until the prompt is reached.Té   )
Ú	bytearrayrB   rM   r/   r;   r   ÚfsdecodeÚbytesÚextendÚendswith)rF   Ú
terminatorÚbufÚcs       r   Ú_read_untilz_Converter._read_untilY   s‚   € å‰kŒkˆð	"Ø”
Ô!×&Ò& qÑ)Ô)ˆAØð ?Ý%¥b¤kµ%¸±*´*Ñ&=Ô&=Ñ>Ô>Ð>Ø�JŠJ�q‰MŒMˆMØ�|Š|˜JÑ'Ô'ð "Ý˜S‘z”zÐ!ð	"r   N)r<   r=   r>   rG   rE   r[   r$   r   r   r@   r@   F   sA   € € € € € ð&ð &ð &ðð ð ð	"ð 	"ð 	"ð 	"ð 	"r   r@   c                   ó   — e Zd Zd„ ZdS )Ú_GSConverterc                 ó¢  — | j         s“t          j        t          j        d¦  «        j        ddddgt          j        t          j        ¬¦  «        | _         	 |                      d¦  «         n0# t          $ r#}t          d|j
        d	         z   ¦  «        d ‚d }~ww xY wd
„ }| j         j                             d ||¦  «        z   dz    ||¦  «        z   dz   ¦  «         | j         j                             ¦   «          |                      d¦  «        }|                     d¦  «        r|                      d¦  «        nd}|st          j                             |¦  «        st|rt%          |d d…         ¦  «        nd	}| j         j                             d|z  ¦  «         t'          ||z                        t+          j        ¦   «         d¦  «        ¦  «        ‚d S )Nr)   z	-dNOSAFERz	-dNOPAUSEz	-dEPSCropz-sDEVICE=png16m)rL   rM   s   
GSzFailed to start Ghostscript:

r   c                 ó¢   — t          j        | ¦  «                             dd¦  «                             dd¦  «                             dd¦  «        S )Nó   \s   \\ó   (s   \(ó   )s   \))r   ÚfsencodeÚreplace)Únames    r   Úencode_and_escapez0_GSConverter.__call__.<locals>.encode_and_escapes   sA   € Ý”K Ñ%Ô%ß’W˜U GÑ,Ô,ß’W˜T 6Ñ*Ô*ß’W˜T 6Ñ*Ô*ð,r   s   << /OutputFile (s   ) >> setpagedevice (s   ) run flush
)ó   GS<s   GS>rg   ó   >r   éÿÿÿÿs   pop
rd   )rB   Ú
subprocessÚPopenr   r2   Ú
executableÚPIPEr[   r;   ÚOSErrorÚargsrL   ÚwriteÚflushrW   r   r   ÚexistsÚintr   ÚdecodeÚsysÚgetfilesystemencoding)rF   ÚorigÚdestÚerrrf   ÚstackÚ
stack_sizes          r   Ú__call__z_GSConverter.__call__f   s  € ØŒzð 
	PÝ#Ô)ÝÔ)¨$Ñ/Ô/Ô:Ø˜k¨;Ð8IðKõ !”o­j¬oð	?ñ ?ô ?ˆDŒJð
PØ× Ò  Ñ)Ô)Ð)Ð)øÝ"ð Pð Pð PÝØ6¸¼À!¼ÑDñFô FØKOðPøøøøðPøøøð	,ð 	,ð 	,ð 	Œ
Ô×ÒØØÐ Ñ%Ô%ñ&à%ñ&ð  Ð Ñ%Ô%ñ&ð ñ	ñ	 ô 	 ð 	 ð 	Œ
Ô×ÒÑ Ô Ð à×ÒÐ/Ñ0Ô0ˆØ*-¯,ª,°vÑ*>Ô*>ÐG�× Ò  Ñ&Ô&Ð&ÀCˆØð 	N�œŸš tÑ,Ô,ð 	NØ,1Ð8�˜U 3 B 3œZ™œ˜°qˆJØŒJÔ×"Ò" 8¨jÑ#8Ñ9Ô9Ð9å(Ø�u‘×$Ò$¥SÔ%>Ñ%@Ô%@À)ÑLÔLñNô Nð Nð		Nð 	Ns   ÁA+ Á+
BÁ5BÂBN)r<   r=   r>   r|   r$   r   r   r]   r]   e   s(   € € € € € ð"Nð "Nð "Nð "Nð "Nr   r]   c                   ó$   ‡ — e Zd Zd„ Zˆ fd„Zˆ xZS )Ú_SVGConverterc                 óÞ  — t          j        d¦  «        j        j        dk     }|rdnd}t	          | d¦  «        s2t          ¦   «         | _        t          j        | j        | j	        ¦  «         | j
        r| j
                             ¦   «         ��+| j
        �a| j
                             ¦   «         �Ht          d | j
        j        | j
        j        | j
        j        g¦  «        D ]}|                     ¦   «          Œi t"          j        ¥d| j        j        dœ¥}t)          ¦   «         }t+          j        |rg d¢ndd	gt*          j        t*          j        ||| j        j        ¬
¦  «        | _
        || j
        _        	 |                      |¦  «         n0# t2          $ r#}t5          d|j        d         z   ¦  «        |‚d }~ww xY wt9          | j        j        t#          j        d¦  «        ¦  «        }	t9          | j        j        t#          j        d¦  «        ¦  «        }
	 |	                     t9          |¦  «                             ¦   «         ¦  «         n%# t4          $ r tA          j!        ||	¦  «         Y nw xY w| j
        j         "                    |rdnd¦  «         | j
        j         #                    ¦   «          	 |                      |¦  «         n‚# t2          $ ru}| j
        j         $                    d¦  «         tK          | j
        j         &                    ¦   «          '                    tQ          j)        ¦   «         d¦  «        ¦  «        |‚d }~ww xY wt#          j*        |	¦  «         tA          j+        |
|¦  «         d S )Nr+   rR   s   
>s   > Ú_tmpdirÚ )ÚDISPLAYÚINKSCAPE_PROFILE_DIR)r+   z--without-guiú--shellr„   )rL   rM   rN   ÚenvÚcwdz/Failed to start Inkscape in interactive mode:

r   s   f.svgs   f.pngs   f.svg --export-png=f.png
s;   file-open:f.svg;export-filename:f.png;export-do;file-close
rd   ),r   r2   r3   ÚmajorÚhasattrr   r€   ÚweakrefÚfinalizerE   rB   ÚpollrK   rL   rM   rN   rO   r   Úenvironre   r   rj   rk   rm   r[   r;   rn   ro   r   rT   Ú
symlink_toÚresolveÚshutilÚcopyfilerp   rq   Úseekr   r/   rt   ru   rv   ÚremoveÚmove)rF   rw   rx   Úold_inkscaperX   rP   r…   rN   ry   Úinkscape_origÚinkscape_dests              r   r|   z_SVGConverter.__call__Œ   sˆ  € ÝÔ/°
Ñ;Ô;ÔCÔIÈAÒMˆØ+Ð6�V�V°ˆ
Ý�t˜YÑ'Ô'ð 	9Ý-Ñ/Ô/ˆDŒLõ Ô˜Tœ\¨4¬<Ñ8Ô8Ð8Ø”
ð #	,Ø”:—?’?Ñ$Ô$Ñ0ØŒzÐ%¨$¬*¯/ª/Ñ*;Ô*;Ð*GÝ$ T¨D¬JÔ,<Ø,0¬JÔ,=Ø,0¬JÔ,=ð,?ñ @ô @ð #ð #�Fð —L’L‘N”N�N�Nð
Ý”*ð
ð à(,¬Ô(9ð
ð 
ð 
ˆCõ #‘_”_ˆFÝ#Ô)Ø<Hð (Ð8Ð8Ð8Ð8Ø˜YÐ'Ý ”o­j¬oÀfØ˜Tœ\Ô.ð	0ñ 0ô 0ˆDŒJð !'ˆDŒJÔð,Ø× Ò  Ñ,Ô,Ð,Ð,øÝ"ð ,ð ,ð ,ÝØGØ”h˜q”kñ"ñ#ô #à(+ð,øøøøð,øøøõ ˜Tœ\Ô.µ´¸HÑ0EÔ0EÑFÔFˆÝ˜Tœ\Ô.µ´¸HÑ0EÔ0EÑFÔFˆð	1Ø×$Ò$¥T¨$¡Z¤Z×%7Ò%7Ñ%9Ô%9Ñ:Ô:Ð:Ð:øÝð 	1ð 	1ð 	1ÝŒO˜D -Ñ0Ô0Ð0Ð0Ð0ð	1øøøàŒ
Ô×ÒØ-9ð LÐ)Ð)ØKñ	Mô 	Mð 	Mð 	Œ
Ô×ÒÑ Ô Ð ð		FØ×Ò˜ZÑ(Ô(Ð(Ð(øÝð 	Fð 	Fð 	Fð ŒJÔ×"Ò" 1Ñ%Ô%Ð%Ý(Ø”
Ô!×&Ò&Ñ(Ô(×/Ò/ÝÔ-Ñ/Ô/°ñ<ô <ñ=ô =àBEðFøøøøð	Føøøõ 	Œ	�-Ñ Ô Ð ÝŒ�M 4Ñ(Ô(Ð(Ð(Ð(sC   Å1F Æ
F4ÆF/Æ/F4È4I ÉI'É&I'Ê,K Ë
MËA0L<Ì<Mc                 óž   •— t          ¦   «                              ¦   «          t          | d¦  «        r| j                             ¦   «          d S d S )Nr€   )ÚsuperrE   rˆ   r€   Úcleanup)rF   Ú	__class__s    €r   rE   z_SVGConverter.__del__Ó   sM   ø€ Ý‰Œ�ŠÑÔÐÝ�4˜Ñ#Ô#ð 	#ØŒL× Ò Ñ"Ô"Ð"Ð"Ð"ð	#ð 	#r   )r<   r=   r>   r|   rE   Ú__classcell__©rš   s   @r   r~   r~   ‹   sK   ø€ € € € € ðE)ð E)ð E)ðN#ð #ð #ð #ð #ð #ð #ð #ð #r   r~   c                   ó"   ‡ — e Zd ZdZˆ fd„Zˆ xZS )Ú _SVGWithMatplotlibFontsConverterzÚ
    A SVG converter which explicitly adds the fonts shipped by Matplotlib to
    Inkspace's font search path, to better support `svg.fonttype = "none"`
    (which is in particular used by certain mathtext tests).
    c                 ó  •— t          | d¦  «        sRt          ¦   «         | _        t          j        t          j        d¦  «        t          | j        j        d¦  «        ¦  «         t          ¦   «          
                    ||¦  «        S )Nr€   z	fonts/ttfÚfonts)rˆ   r   r€   r�   Úcopytreer   Ú_get_data_pathr   re   r˜   r|   )rF   rw   rx   rš   s      €r   r|   z)_SVGWithMatplotlibFontsConverter.__call__à   so   ø€ Ý�t˜YÑ'Ô'ð 	>Ý-Ñ/Ô/ˆDŒLÝŒO�EÔ0°Ñ=Ô=Ý  ¤Ô!2°GÑ<Ô<ñ>ô >ð >å‰wŒw×Ò  dÑ+Ô+Ð+r   )r<   r=   r>   Ú__doc__r|   r›   rœ   s   @r   rž   rž   Ù   sB   ø€ € € € € ðð ð,ð ,ð ,ð ,ð ,ð ,ð ,ð ,ð ,r   rž   c                  ó  — 	 t          j        d¦  «         t          ¦   «         xt          d<   t          d<   n# t           j        $ r Y nw xY w	 t          j        d¦  «         t          ¦   «         t          d<   d S # t           j        $ r Y d S w xY w)Nr)   ÚpdfÚepsr+   Úsvg)r   r2   r]   Ú	converterÚExecutableNotFoundErrorr~   r$   r   r   Ú_update_converterrª   è   s­   € ð=ÝÔ  Ñ&Ô&Ð&õ /;©n¬nÐ<�	�%Ñ�9 UÑ+Ð+øõ Ô&ð ð ð Øˆðøøøð+ÝÔ  Ñ,Ô,Ð,õ )™?œ?�	�%ÑÐÐøõ Ô&ð ð ð Øˆˆðøøøs!   ‚7 ·A	ÁA	ÁA9 Á9BÂBc                  ó   — dgt           ¢S )z¹
    Return the list of file formats that `.compare_images` can compare
    on this system.

    Returns
    -------
    list of str
        E.g. ``['png', 'pdf', 'svg', 'eps']``.

    Úpng)r¨   r$   r   r   r
   r
      s   € ð Ð•IÐÐr   c                 ó,  — t          | ¦  «        }|                     ¦   «         st          |› d�¦  «        ‚|j        dd…         t          vr"ddl}|                     d|j        › d�¦  «         |j        |j        › d|j        dd…         › d�z  }|                     ¦   «         r5| 	                    ¦   «         j
        | 	                    ¦   «         j
        k     �r.|rt          ¦   «         nd}|�}t          ¦   «          t          |¦  «        }|||j        z   z  }|                     ¦   «         r?t                               d	| ¦  «         t!          j        ||¦  «         t%          |¦  «        S t                               d
| ¦  «         t          |j        dd…                  }|j        dk    r|                     ¦   «         }	d|	v rt(          } |||¦  «         |�0t                               d| ¦  «         t!          j        ||¦  «         t%          |¦  «        S )a�  
    Convert the named file to png; return the name of the created file.

    If *cache* is True, the result of the conversion is cached in
    `matplotlib.get_cachedir() + '/test_cache/'`.  The caching is based on a
    hash of the exact contents of the input file.  Old cache entries are
    automatically deleted as needed to keep the size of the cache capped to
    twice the size of all baseline images.
    z does not existrR   Nr   zDon't know how to convert z files to pngÚ_z.pngz"For %s: reusing cached conversion.zFor %s: converting to png.r*   zstyle="font:z"For %s: caching conversion result.)r   rr   ÚIOErrorr1   r¨   ÚpytestÚskipÚparentÚstemÚstatÚst_mtimer    Ú'_register_conversion_cache_cleaner_oncer9   Ú_logÚdebugr�   r�   r#   Ú	read_textÚ$_svg_with_matplotlib_fonts_converter)
ÚfilenameÚcacher   r°   Únewpathr   Ú
hash_valueÚcached_pathÚconvertÚcontentss
             r   rÀ   rÀ     sÿ  € õ �‰>Œ>€DØ�;Š;‰=Œ=ð 0Ý˜Ð.Ð.Ð.Ñ/Ô/Ð/Ø„{�1�2�2„�iÐ'Ð'ØˆˆˆØ�ŠÐK°´ÐKÐKÐKÑLÔLÐLØŒk˜tœyÐ@Ð@¨4¬;°q°r°r¬?Ð@Ð@Ð@Ñ@€Gð �>Š>ÑÔð 2˜wŸ|š|™~œ~Ô6¸¿º¹¼Ô9MÒMÑMØ).Ð8•OÑ%Ô%Ð%°Dˆ	àÐ Ý3Ñ5Ô5Ð5Ý& tÑ,Ô,ˆJØ# z°G´NÑ'BÑCˆKØ×!Ò!Ñ#Ô#ð $Ý—
’
Ð?ÀÑJÔJÐJÝ” ¨WÑ5Ô5Ð5Ý˜7‘|”|Ð#å�
Š
Ð/°Ñ:Ô:Ð:Ý˜DœK¨¨¨œOÔ,ˆØŒ;˜&Ò Ð Ø—~’~Ñ'Ô'ˆHØ Ð)Ð)õ ?�Øˆ��gÑÔÐàÐ Ý�JŠJÐ;¸XÑFÔFÐFÝŒO˜G [Ñ1Ô1Ð1åˆw‰<Œ<Ðr   c                  ór  ‡— t          d„ t          t          j        ¦  «        j                             d¦  «        D ¦   «         ¦  «        } d| z  }t          j        t          ¦   «         ¦  «        5  d„ t          ¦   «                              d¦  «        D ¦   «         Št          d„ ‰ 	                    ¦   «         D ¦   «         ¦  «        }t          ‰ˆfd„d¬	¦  «        }||k    r>|                     ¦   «         }|‰|         j        z  }|                     ¦   «          ||k    °>d d d ¦  «         d S # 1 swxY w Y   d S )
Nc              3   óH   K  — | ]}|                      ¦   «         j        V — Œd S r"   )r´   Úst_size©Ú.0r   s     r   ú	<genexpr>z*_clean_conversion_cache.<locals>.<genexpr>B  sI   è è € ð Oð Oàð 	�	Š	‰ŒÔðOð Oð Oð Oð Oð Or   z**/baseline_images/**/*é   c                 ó8   — i | ]}||                      ¦   «         “ŒS r$   )r´   rÅ   s     r   ú
<dictcomp>z+_clean_conversion_cache.<locals>.<dictcomp>J  s5   € ð Gð Gð GØ"&ˆD�$—)’)‘+”+ðGð Gð Gr   Ú*c              3   ó$   K  — | ]}|j         V — Œd S r"   )rÄ   )rÆ   r´   s     r   rÇ   z*_clean_conversion_cache.<locals>.<genexpr>L  s$   è è € ÐFÐF¨$˜œÐFÐFÐFÐFÐFÐFr   c                 ó   •— ‰|          j         S r"   )Úst_atime)r   Ú
cache_stats    €r   ú<lambda>z)_clean_conversion_cache.<locals>.<lambda>N  s   ø€ ¨°DÔ)9Ô)B€ r   T)ÚkeyÚreverse)Úsumr   r   Ú__file__r²   Úglobr   Ú
_lock_pathr    ÚvaluesÚsortedÚpoprÄ   Úunlink)Úbaseline_images_sizeÚmax_cache_sizeÚ
cache_sizeÚpaths_by_atimer   rÏ   s        @r   Ú_clean_conversion_cacherß   ?  s«  ø€ õ ð Oð Oå�œÑ&Ô&Ô-×2Ò2Ð3LÑMÔMðOñ Oô Oñ Oô OÐð
 Ð-Ñ-€Nå	Ô	�/Ñ+Ô+Ñ	,Ô	,ð 
ð 
ðGð GÝ*9Ñ*;Ô*;×*@Ò*@ÀÑ*EÔ*EðGñ Gô Gˆ
åÐFÐF°*×2CÒ2CÑ2EÔ2EÐFÑFÔFÑFÔFˆ
ÝØÐBÐBÐBÐBØðñ ô ˆð ˜>Ò)Ð)Ø!×%Ò%Ñ'Ô'ˆDØ˜* TÔ*Ô2Ñ2ˆJØ�KŠK‰MŒMˆMð ˜>Ò)Ð)ð
ð 
ð 
ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
øøøð 
ð 
ð 
ð 
ð 
ð 
s   Á/B0D,Ä,D0Ä3D0c                  ó8   — t          j        t          ¦  «         d S r"   )rC   rD   rß   r$   r   r   r¶   r¶   V  s   € å
„OÕ+Ñ,Ô,Ð,Ð,Ð,r   c                 ó:  — | dd…         dk    rŠ|dd…         dk    r||j         \  }}}|j         \  }}}	|t          |dz  |dz  z
  ¦  «        t          |dz  |dz  z   ¦  «        …t          |dz  |dz  z
  ¦  «        t          |dz  |dz  z   ¦  «        …f         }||fS )Niùÿÿÿéüÿÿÿr¦   r¥   rÈ   )Úshapers   )
Úactual_pathÚactual_imageÚexpected_pathÚexpected_imageÚawÚahÚadÚewÚehÚeds
             r   Úcrop_to_samerî   [  sÉ   € ð �2�b�5Ô˜UÒ"Ð" }°R¸°UÔ';¸uÒ'DÐ'DØ!Ô'‰
ˆˆB�Ø#Ô)‰
ˆˆB�Ø#¥C¨¨Q©°°a±©Ñ$8Ô$8½Ø�‰F�R˜!‘V‰Oñ:ô :ð %Ý! " q¡&¨2°©6¡/Ñ2Ô2µ3°r¸A±vÀÀQÁ±Ñ3GÔ3GÐGð%Hô Iˆà˜Ð'Ð'r   c                 ó  — | j         |j         k    r-t          d                     | j         |j         ¦  «        ¦  «        ‚t          j        | |z
                       t          ¦  «        dz                       ¦   «         ¦  «        S )zR
    Calculate the per-pixel errors, then compute the root mean square error.
    ú9Image sizes do not match expected size: {} actual size {}rÈ   )rã   r   ÚformatÚnpÚsqrtÚastypeÚfloatÚmean)rç   rå   s     r   r	   r	   f  sz   € ð Ô˜|Ô1Ò1Ð1Ý$ðß#šV NÔ$8¸,Ô:LÑMÔMñOô Oð 	Oõ Œ7�^ lÑ2×:Ò:½5ÑAÔAÀQÑF×LÒLÑNÔNÑOÔOÐOr   c                 óÚ   — t          j        | ¦  «        }|j        dk    s$|                     ¦   «         d         d         dk    r|                     d¦  «        }t          j        |¦  «        S )NÚRGBAé   r   éÿ   ÚRGB)r   r.   ÚmodeÚ
getextremarÀ   rò   Úasarray)r   Úimgs     r   Ú_load_imager   v  s]   € Ý
Œ*�TÑ
Ô
€Cð „x�6ÒÐ˜SŸ^š^Ñ-Ô-¨aÔ0°Ô3°sÒ:Ð:Ø�kŠk˜%Ñ Ô ˆÝŒ:�c‰?Œ?Ðr   Fc                 óR  ‡
— t          j        |¦  «        }t           j                             |¦  «        st	          d|z  ¦  «        ‚t          j        |¦  «        j        dk    rt	          d|z  ¦  «        ‚t          j        | ¦  «        } t           j                             | ¦  «        st          d| z  ¦  «        ‚|                      d¦  «        d         }|dk    r"t          |d¬	¦  «        }t          | d¬	¦  «        } t          | ¦  «        }t          |¦  «        }t          ||| |¦  «        \  }}t          |d
¦  «        }|dk    rt          j        ||¦  «        rdS |                     t          j        ¦  «        }|                     t          j        ¦  «        }t#          ||¦  «        }||k    rdS t%          | ||¦  «         t'          |t)          | ¦  «        t)          |¦  «        t)          |¦  «        |¬¦  «        Š
|s%g d¢}	d                     ˆ
fd„|	D ¦   «         ¦  «        Š
‰
S )a+  
    Compare two "image" files checking differences within a tolerance.

    The two given filenames may point to files which are convertible to
    PNG via the `.converter` dictionary. The underlying RMS is calculated
    with the `.calculate_rms` function.

    Parameters
    ----------
    expected : str
        The filename of the expected image.
    actual : str
        The filename of the actual image.
    tol : float
        The tolerance (a color value difference, where 255 is the
        maximal difference).  The test fails if the average pixel
        difference is greater than this value.
    in_decorator : bool
        Determines the output format. If called from image_comparison
        decorator, this should be True. (default=False)

    Returns
    -------
    None or dict or str
        Return *None* if the images are equal within the given tolerance.

        If the images differ, the return value depends on  *in_decorator*.
        If *in_decorator* is true, a dict with the following entries is
        returned:

        - *rms*: The RMS of the image difference.
        - *expected*: The filename of the expected image.
        - *actual*: The filename of the actual image.
        - *diff_image*: The filename of the difference image.
        - *tol*: The comparison tolerance.

        Otherwise, a human-readable multi-line string representation of this
        information is returned.

    Examples
    --------
    ::

        img1 = "./baseline/plot.png"
        img2 = "./output/plot.png"
        compare_images(img1, img2, 0.001)

    zOutput image %s does not exist.r   zOutput image file %s is empty.z!Baseline image %r does not exist.ú.ri   r¬   T)r¼   zfailed-diffN)ÚrmsÚexpectedÚactualÚdiffÚtol)z!Error: Image files did not match.zRMS Value: {rms}zExpected:  
    {expected}zActual:    
    {actual}zDifference:
    {diff}zTolerance: 
    {tol}z
  c                 ó*   •— g | ]} |j         d i ‰¤Ž‘ŒS )r$   ©rñ   )rÆ   ÚlineÚresultss     €r   ú
<listcomp>z"compare_images.<locals>.<listcomp>ä  s+   ø€ ÐKÐKÐK¸$˜{˜tœ{Ð5Ð5¨WÐ5Ð5ÐKÐKÐKr   )r   Úfspathr   rr   Ú	Exceptionr´   rÄ   r¯   ÚsplitrÀ   r   rî   r   rò   Úarray_equalrô   Úint16r	   Úsave_diff_imageÚdictr#   Újoin)r  r  r  Úin_decoratorÚ	extensionrç   rå   Ú
diff_imager  Útemplater  s             @r   r   r   €  s/  ø€ õb ŒY�vÑÔ€FÝŒ7�>Š>˜&Ñ!Ô!ð DÝÐ9¸FÑBÑCÔCÐCÝ	„wˆv�„Ô !Ò#Ð#ÝÐ8¸6ÑAÑBÔBÐBõ Œy˜Ñ"Ô"€HÝŒ7�>Š>˜(Ñ#Ô#ð FÝÐ9¸HÑDÑEÔEÐEØ—’˜sÑ#Ô# BÔ'€IØ�EÒÐÝ˜ tÐ,Ñ,Ô,ˆÝ˜8¨4Ð0Ñ0Ô0ˆõ ! Ñ*Ô*€NÝ˜vÑ&Ô&€Lå#/Ø�˜h¨ñ$8ô $8Ñ €L�.õ $ F¨MÑ:Ô:€Jà
ˆa‚x€xÝŒ>˜.¨,Ñ7Ô7ð 	Ø�4ð $×*Ò*­2¬8Ñ4Ô4€NØ×&Ò&¥r¤xÑ0Ô0€Lå
˜¨Ñ
5Ô
5€Cà
ˆc‚z€zØˆtå�H˜f jÑ1Ô1Ð1å�s¥S¨¡]¤]Ý˜f™+œ+­C°
©O¬OÀðFñ Fô F€Gð ð Mð0ð 0ð 0ˆð —+’+ÐKÐKÐKÐKÀ(ÐKÑKÔKÑLÔLˆØ€Nr   c                 óx  — t          | ¦  «        }t          |¦  «        }t          ||| |¦  «        \  }}t          j        |t          ¦  «        }t          j        |t          ¦  «        }|j        |j        k    r-t          d                     |j        |j        ¦  «        ¦  «        ‚t          j        ||z
  ¦  «        }|dz  }t          j	        |dd¦  «         
                    t          j        ¦  «        }|j        d         dk    rd|dd…dd…df<   t          j        |¦  «                             |d	¬
¦  «         dS )zÏ
    Parameters
    ----------
    expected : str
        File path of expected image.
    actual : str
        File path of actual image.
    output : str
        File path to save difference image to.
    rð   é
   r   rú   rÈ   é   Nrù   r¬   r	  )r   rî   rò   Úarrayrõ   rã   r   rñ   ÚabsÚcliprô   Úuint8r   Ú	fromarrayÚsave)r  r  Úoutputrç   rå   Úabs_diffs         r   r  r  è  s4  € õ ! Ñ*Ô*€NÝ˜vÑ&Ô&€LÝ#/Ø�˜h¨ñ$8ô $8Ñ €L�.å”X˜n­eÑ4Ô4€NÝ”8˜L­%Ñ0Ô0€LØÔ˜|Ô1Ò1Ð1Ý$ðß#šV NÔ$8¸,Ô:LÑMÔMñOô Oð 	Oõ Œv�n |Ñ3Ñ4Ô4€Hð ��N€HÝŒw�x  CÑ(Ô(×/Ò/µ´Ñ9Ô9€Hà„~�aÔ˜AÒÐØˆ����A�A�A�q�Ñå	„O�HÑÔ×"Ò" 6°%Ð"Ñ8Ô8Ð8Ð8Ð8r   )r&   )F)3r£   rC   Ú	functoolsr,   Úloggingr   Úpathlibr   r�   rj   ru   Útempfiler   r   r‰   Únumpyrò   ÚPILr   Ú
matplotlibr   r   Úmatplotlib.testing.exceptionsr   Ú	getLoggerr<   r·   Ú__all__r   r    r%   r9   r  r;   r@   r]   r~   rž   rª   r¨   rº   r
   rÀ   rß   Ú	lru_cacher¶   rî   r	   r   r   r  r$   r   r   ú<module>r/     s  ððð ð €€€Ø Ð Ð Ð Ø €€€Ø €€€Ø 	€	€	€	Ø Ð Ð Ð Ð Ð Ø €€€Ø Ð Ð Ð Ø 
€
€
€
Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ø €€€à Ð Ð Ð Ø Ð Ð Ð Ð Ð à Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø @Ð @Ð @Ð @Ð @Ð @à€wÔ˜Ñ"Ô"€à
CÐ
CÐ
C€ð,ð ,ð ,ðð ð ð"ð "ð "ðð ð ð ð&	ð 	ð 	ð 	ð 	�iñ 	ô 	ð 	ð"ð "ð "ð "ð "ñ "ô "ð "ð>#Nð #Nð #Nð #Nð #N�:ñ #Nô #Nð #NðLK#ð K#ð K#ð K#ð K#�Jñ K#ô K#ð K#ð\,ð ,ð ,ð ,ð , }ñ ,ô ,ð ,ð+ð +ð +ð& €	Ø Ð Ñ Ô Ð Ø'GÐ'GÑ'IÔ'IÐ $ðð ð ð.ð .ð .ðbð ð ð. €ÔÑÔð-ð -ñ Ôð-ð(ð (ð (ð	Pð 	Pð 	Pð ð ð ðeð eð eð eðP9ð 9ð 9ð 9ð 9r   