From 72abc29722c11c71375440608efc71f713bb834b Mon Sep 17 00:00:00 2001 From: DRC Date: Fri, 18 Feb 2011 01:45:24 +0000 Subject: [PATCH] The SIMD quantization algorithm does not produce correct results with the fast forward integer DCT and JPEG qualities >= 98, so for now, use the non-SIMD quantization function under those circumstances. git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.1.x@378 632fc199-4ca6-4c93-a231-07263d6284db --- ChangeLog.txt | 18 +++++++++++------- Makefile.am | 2 ++ jcdctmgr.c | 18 ++++++++++++++---- testimgfst100.jpg | Bin 0 -> 18884 bytes 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 testimgfst100.jpg diff --git a/ChangeLog.txt b/ChangeLog.txt index 0097c41..14d251a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,15 +1,19 @@ 1.1.0 ===== -[1] Since the fast integer forward DCT seems to degrade for JPEG qualities -greater than 95, TurboJPEG/OSS will now automatically use the slow integer -forward DCT when generating JPEG images of quality 96 or greater. This -reduces compression performance by as much as 15% for these high-quality images -but is necessary to ensure that the images are perceptually lossless. +[1] The algorithm used by the SIMD quantization function cannot produce correct +results when the JPEG quality is >= 98 and the fast integer forward DCT is +used. Thus, the non-SIMD quantization function is now used for those cases. -[2] Ported jpgtest.cxx to pure C to avoid the need for a C++ compiler. +[2] Despite the above, the fast integer forward DCT still degrades somewhat for +JPEG qualities greater than 95, so TurboJPEG/OSS will now automatically use the +slow integer forward DCT when generating JPEG images of quality 96 or greater. +This reduces compression performance by as much as 15% for these high-quality +images but is necessary to ensure that the images are perceptually lossless. -[3] Fixed visual artifacts in grayscale JPEG compression caused by a typo in +[3] Ported jpgtest.cxx to pure C to avoid the need for a C++ compiler. + +[4] Fixed visual artifacts in grayscale JPEG compression caused by a typo in the RGB-to-chrominance lookup tables. diff --git a/Makefile.am b/Makefile.am index adfa5c0..ca69a38 100644 --- a/Makefile.am +++ b/Makefile.am @@ -129,6 +129,8 @@ test: testclean all cmp $(srcdir)/testimgint.jpg testoutint.jpg ./cjpeg -dct fast -opt -outfile testoutfst.jpg $(srcdir)/testorig.ppm cmp $(srcdir)/testimgfst.jpg testoutfst.jpg + ./cjpeg -dct fast -quality 100 -opt -outfile testoutfst100.jpg $(srcdir)/testorig.ppm + cmp $(srcdir)/testimgfst100.jpg testoutfst100.jpg ./cjpeg -dct float -outfile testoutflt.jpg $(srcdir)/testorig.ppm if WITH_SIMD cmp $(srcdir)/testimgflt.jpg testoutflt.jpg diff --git a/jcdctmgr.c b/jcdctmgr.c index 156957a..711f9da 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -4,6 +4,7 @@ * Copyright (C) 1994-1996, Thomas G. Lane. * Copyright (C) 1999-2006, MIYASAKA Masaru. * Copyright 2009 Pierre Ossman for Cendio AB + * Copyright (C) 2011 D. R. Commander * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -39,6 +40,8 @@ typedef JMETHOD(void, float_quantize_method_ptr, (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspace)); +METHODDEF(void) quantize (JCOEFPTR, DCTELEM *, DCTELEM *); + typedef struct { struct jpeg_forward_dct pub; /* public fields */ @@ -160,7 +163,7 @@ flss (UINT16 val) * of in a consecutive manner, yet again in order to allow SIMD * routines. */ -LOCAL(void) +LOCAL(int) compute_reciprocal (UINT16 divisor, DCTELEM * dtbl) { UDCTELEM2 fq, fr; @@ -189,6 +192,9 @@ compute_reciprocal (UINT16 divisor, DCTELEM * dtbl) dtbl[DCTSIZE2 * 1] = (DCTELEM) c; /* correction + roundfactor */ dtbl[DCTSIZE2 * 2] = (DCTELEM) (1 << (sizeof(DCTELEM)*8*2 - r)); /* scale */ dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */ + + if(r <= 16) return 0; + else return 1; } /* @@ -232,7 +238,9 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } dtbl = fdct->divisors[qtblno]; for (i = 0; i < DCTSIZE2; i++) { - compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]); + if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i]) + && fdct->quantize == jsimd_quantize) + fdct->quantize = quantize; } break; #endif @@ -266,10 +274,12 @@ start_pass_fdctmgr (j_compress_ptr cinfo) } dtbl = fdct->divisors[qtblno]; for (i = 0; i < DCTSIZE2; i++) { - compute_reciprocal( + if(!compute_reciprocal( DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], (INT32) aanscales[i]), - CONST_BITS-3), &dtbl[i]); + CONST_BITS-3), &dtbl[i]) + && fdct->quantize == jsimd_quantize) + fdct->quantize = quantize; } } break; diff --git a/testimgfst100.jpg b/testimgfst100.jpg new file mode 100644 index 0000000000000000000000000000000000000000..36d9b75e64c75d12f01447ab77faddff16b6b4d0 GIT binary patch literal 18884 zcmbq)Ra70pw(Z8;1b;3T^{G$`}4kU^+%5y zUA0z^?y6d=X3hDr^sxy*mzS2420%an01%%S;A0ga@mc%7mH!y|zghU~{m~1+fCr=k zcAy|A0FW3EP#6#&g8BEC>UsH1O#X} zIA|yU1T+RD6bv~myBGitOU(p`=^O};O_hj4K}r3^w4h-IfkRvp^s{g4l1n40pN3P) z3>@?q5m#FMTj7-zSI8}7&vHHc!W=9P>7$;MH z;4IG#{DKu!rl^r+InKBN+u#;_`8$wnroy{py4@)qjN6ac{h6 z!~6v6b^7k0{@41u#M@Ig5Y_Uu#gb#U_R)ppu!p$g{OIWRF*R9EXOMJ}EgTr28IgfDRz}Kc< z2Io6vv+wJC>&hcX15KIqyTZS^*QNgn|Fs*WD}xnTJQK=&_0)}|YU9;i`z5fqJ8fZ+FPutv3ck{JVyOdS z!WMJi=nSRlv6U=0$Yrmvd8G$?q3-DzZCI#{u&nfDdfR1DsFql1-Jn{BN&ZP96fCAoxB26ui&8EARqnEW1o;kN`Cm!%Z!VN^F9j{46Cp{?)p^r-w^(84d~`$ zv2txfvEZ{QL`Dduuf{J+CG?2Qszf-fdct?)eH4W^X|Te2M#D6XN8{Rj=(|RRjUqI& z_q{DGf1ksdlqYX&M3sbP26m(g-z~2iCis?o^(J0>CKmiFAKJ&3y8oI`7xUFMY6(=f zE*sgwh&eeIxGmoUH;em@~)@xsfRc7KQ_Rm_*8OsFe?n-vFXk&p^Cz}CA!!zKAHSnP-QWX| z>8!R5<2aogp>4_n@x@VBlovLQr`*NaGZ?n$85FR>oi+4G_!!-_<1gF6rKgOYIPf>+ z@;JLDFa~E@rZr4zYQf)SNz0GXm>fBhWO^6{wK(AETFA2#KK9T0`#v3`6NJQ?w+yWC zjwbc_op1&=da*cBZjTF#7vtS*h zz|T?3JU&ODqk{sTQjrW%uvudHUq=)a0s zfxTI*JKAS=Di8Q-kxT^9bk^eFOl)QEcsnB)?ru*s-dzMlK#Re z`M!2;0j7z+OVMiLS_SFSNymq=VRKb3dAJ>?)% zA}**a0FYJT7gNloN7B--wm<(i&SsFfvdZ%Ype4`m4uNn#uEwxV0D=gFner;`kEL`c15)~*sz5HlG7<72$tq5;31!g z`*T%oFwc>QZ;huw$P1Hq;I<~jaxgV~@~~?7kAyxklFo0oKf_}%i}jaMtueamz8qR} z{`z8Zm%d+$Bs}g`Ws+^UP7R5B-16>V+VK>ct-WmRyNcn^SAu!rPI443`A`MIkoTF+ zT*8F$Gcw{LG`R_$&Ncb~2BXRnYL)((5t#h8yD#^^~gjsDzBY zw>lxmlRsgST}vghC$}tsCYTPJ3y_zsy`6BLbZYh>o?vZuc5z{dxj4Vl#4bd7^Q*4Z z`EDk7<2E|!tg-h;OeUDz6S84|KnNch3E@L89|Xj4J8rc8KOkZG;(6)O1~W{-c*p;xqLceUhKX#cGLxMY&3lk& zqnJ9vX@4(nz=9J96G1}Iu#v%nCQ|_(T0*57C$A;7eB`Y;^U@s$8YF~%_uE(Nx%3_> z5awU%x?b|0Z+w|P>fw8GIX+vorYI8l&*HZnyxw~-89O|2O;wiv<+}bMuwHRdJF;0iXt`hLM*rV+T4HDwic4?b~JguDk-#p{G6pRl*IRH9nV!F*8H}bOZce6#FcL+8$ zpI^y>5aAEMfN;K~Kt6H$P{bodb-MS%#)1e>-}Y!6sxhoFI$KP|VBz9Sel7i?>sEdy_*m$d#(i)T*FtI^it>(ef_eQv9x)uQ z*OdJD_4WDw18{`h*sTN>qhQO~>LpTKI@?}L>)C&{A&oBdN6oE~8u~qZ*lX4pl=GND zs=-G>hCpAa>E#hOWoq4-HzIqfg}W|(EUOgaobWD$4%hx?#B~srt zvP7ToRh;yFA}h}E=H`G>jmo7VuN;DI|Hkdmlv<={{o@rq#2Vy5E90(9gRUH;#?JRM zCn;gCX7!VDjalnk?BGSj-l@uieR-68@zvr=n9FW~l+86_291+ha|FS)N|2{nn&5yqK9vR8tc=^_mvfmn!c>)=HnXv_Gn-da zC=sanvE3_!=Zh&FpBFw`mjgV4?OnneKc(Me~a&9fT^a+^2LCyxi&SyCV(6wWM!KSKu1-e*k`tG`)%tsl%<1;A&JPi3;brBL6Oj;Vuy^lpl3s97(Teavj~z zdzZPKqD&4hd7W~neF!ps+xP(3iNviZT;UeJ@46?WC?R*Pf({jqt&R;S)&za^L1jZ2 z87MYk4#StnVt_AdxB?dIS8o_R$sIXzK+jv&kQ7uluWX#ZY6P*&-grH&)xv1z6@R|3 ztfEDYLZk1pxwS(>uA4!1HDfEg^*kz%7$%gc-Gq99l@k!>!}>1ggWBT~K*Xpn+*5L3 zkwg2=3CpmCYvk|kaLB>IP$9D%cX_{&2NMR1OM9_O^9+wvh*Fwa3Ul(T}-YX?on zhgFBpU5I&zyh%0UpzNrk7XoD@ft+X?xY!ZO=7YZVAn*N(N-=UoRATTbMML58 z&%DN+;*KvQ9eo>lCNkB-z@tWSDDvN0)|{(5o_f??VxqH6aFBcezF{AgM+APkyDY1X z;WS2n*H&%aq^8jK4?tm}KX1pH0S@h0@R`CJEhEX#{$^(11mCN0OOZzBIX+mz^DfS7 z_vs?_iRV^esXr{oe2o1w|Auxu+SkXvqmqu2N5n=@0d3;x@h{KeXB&ONIyrZLY#$j{!&LX-{gj;qO-L7`|*u!ca!loqF*AZ z5Cvsg?LifI+1?ZO!eXPVIPd1RadP`;H28IR+*F(!H7>wji_Ue)B0q=c!BB9spa=SjG9Wa|ZnnLp`bmp% zZQW2nsoX_z<_91yQOajk|L!aC)QZYs{$Y4n>rAL7YnAM_27|?kN9}~{^qKoA2OSda zSTg1K>Dirk{gElrzT3dHgK5RJ*<8Y?A2CCp|5G6e&*`H-WwD;!lgdjnG6*vlzt_0i%w`T42dy2%)-ZTF)Hjgdf+QpI#%C02!s<2UUO z0G2PD^qkQ{x8((?)61WK|1?2}`-JMRoDl{FYe;(ubIGl3w_H*3gW)|1nX;`HQgv3% zZxkoY^= z-m|Kg(_4aJm!LW|P%{0Nez5id?mS z;I^ZEgL;zzRtzSQW+UU^)EywJ-LjmfW@@tDkK>HnqCy!mg~6Q@8LJSB z&l>#Ww?2AeJN3X?0!e%fam+C&=2;1`6{Otj9ElOXBIF}{lB6g4uNKmf&nxSks<=W) zBp)@o7CynOHWa4TbiKOVhi zbRx@Ey}JFBPjw4FhM5ku32r9f=zm$qT&56V1ov~QDE@&w=VB4|I)4s$%3pTeoNbEW z>&yE#eYoNa52`yH$3G&WMlTW{M2BDM5|f`s_iD1Oluy-6X9ZRMsQ9YWVA_KpoM${W zg*u33W8)f0MVn84{j$CP#_y3gH3eS|#1N^eT;uTeE7AAa85cn(1rc$cs)o6e6D8#( zQ%254>+YaWm-mF50Yqu-z>!gE4Akd$T?jlkl>0)3g>FzmPU5Df-h;O0vhwQV+)5gF zWJ#j<5-3oPqRwJ@aW;8yhxfD9+Bdk4kPaiJ5K8&fR2nJQe9YBMjh5(lwA!cfaJVcw z{o-S{WAYwHSn~|ben^M7(c^-@B#fIe_DgpRWRx{Zy%;J}Uge1NBzu;l3!h|t6$}al zwjpOYI~yYSP!)}Qrna6ryDJHAmAmIB(U5uVpu)`=E<)oYNO3ji%eRBKWuemqeK6#J zW`jOL7w9g232Ed5*=Yg{DM#04d7IZgncj~tIctevzx`yR)R8}Zia(a^sdY{;z2cq& zbaw5XM4h8zxod>f5``eMtmN01HD!+13Zp&%woeJW4NC+jh1)k8NcMW`i~O@+<)|*- z_OH!VGejvAHAOXP2i4U4(Goj_CT@;?;G=&A+srH+OAIvX6G;Vm*F z*5cw{Fzdrei_48lOGHPSoSK2-uLDuOzQnMd_q=nc?hWna^oYT}{0%G;8|wPA1LZ6k zxqXw=4HldXW;bETI>5pDDj)>JIbK$hERh)YamuTFx6JXf->piWiuYQNt@Qv@b^h9q zyNl!MNSjIA^mq|B31J6?{yPG}XO25M%NLH29+$zDTe5tlBoQ!JwBr`1zMD@#ueGz6NX zGwKs$MHH1_=uj(Pz(CL;S8r>Mb1T@cn9Dt3H5=$K{3Ol`O39F_KIcL z64L6*3-yO=D3Z9d*4AatoQtijDiu9^(eu@WR~n?(0Wwk5yT@?1LP-=5gfqoZa-O#b zMTbEz`txYai+J_F+o~HsxmsIN2aO^6IXUdO4Q;R8} zOV^|2bbUo0#!_{m(rJ#(9mox9a3f0PaalSuwNn#x3@}BeYlYo1m$Nm7dD9oK+j`z} zGX(#H)oHhA%ReY3u+s=%mD@ajF9GV2gjED{$gc1t3fPiyZ@; z-D!4C$QT!IQ_m5|R%ozwu+`{EDG-zfrRuTA8`?1SFMP9I8!(T^7{VKZ7c99Bg5WbK zZ^wqnBtwc;?LjnJpuwZC4Qfzq#GQD`X_sM5e^!(<6Qj+3{sQwJD>y{YKrcsDm8tqe z-bc*bdS}Lc_e4FIC;sptlxDhYR>_cqBhpR|B~%g5ICpe>GE%6fi90itZq7qd3}}Lc z7TpgC@wk&n>gUNz>&Uc`i2IinsO79B_^;z`P2Nk3s*;7^b^hcpf8bZq`9c;4)b;w3 zFIMYcT{t9J@N!LEa-+k$i-We&Ctta6aj1!x%A?rH);el;vx)gN`+VVcNbDeK4G!11 zoAIeOGBkhxKoUnU38P*MK5^W}As>w+FHxPNiL<#qdI`)NtL^37zs$z0iH%&Pd$>Au z4C^9ucD|Fx`mJ8_0RRiGrsvt$dfVnIhh;S=m(N;G(O|P-g@lRV?Am&xk!`I3zoE=- zNiAs!%4Rw<*&Kwlkz(!$pt>V37i05b^z&Is^mCc8rmpM?vAMb1d_0t|!~>}p;F9P*P*TgcXPZu?EE(1aw*=zDq2g7GM66)JXIon~I(TDy8-PhK<N8l$-wEmLck8g;|!P_jc_!@rljXun&`g0{TwEjPFsV zA`0QCQuT5>eA>i(Z_3yhH<3HOwSjAH3e}Oc`r-K*wKbIw4QW#>Kj%mOE1Xa zsOJrwk0iY>oVmzoC1a7E@0ss;{s1^$FZrSpsf0>q-lpDh(a!_xu>;$n5ZH2EZYUYE z?QXOyWM$;lg~j93o1emCt1r^>_=BF?N8WyzvixCZ<*<#=P@$t2gP2`@}Uk(zJ6J9dk#h{l~70@02#Xk13a z+)WARG`eI`k6{STDE`>$xW3bI@VXsK(Ow4fH+prX1yv#&6;9;*d(!6+6<~R~qL-x! zTH&s=|MFF|O9mus(jK#5ixf@yHNaFtwG*;RwPz|IDj$R0t7Gskl0o)!P`D~U&KaMR z59M!!5cvV|o3PQKHX z!w${EgKXT~I7FZVn^3;>nAK6b`2kpS#9V%TeG0gn@{!baTKGDtU-?kc`nwtB+v&S} zc|}Lz)VJdfiMfu@Y`s=ZTqdB(ntIw)TIKi0oC?$5-42W+Hr&*?c?ad+zS)OSnKb`9 zx|pL;&Zmz0y+T@VWKw@k-Hr(+k2qCe{{q~O0w4c$$B&!Pg!+cgL#eO3#s=O$&JEwJ zbH`fN)EJ!8OhS}t9;*i-RDjK^vv>sPv!8|5BxU`vJ)RR{J{e0a#tZ`2budEH&nL z(DQORoIS?K7F0FMx8pew$WP~@|DBKyHjKb^zHAbgFjFGI{RZzGBf}@f<)cw&p(GqM zn)tGPvg!JVkJ73ll+AzDPOkhhu>PnE-ldCy#1aMkHvk%(zRxO(fDl z;{4LgpFioH@H+Q90-5YceHp`&CM-iuPHh(&I~> zv#a|%ah^1Daqx+>v=0oUrVs?ON>~;zw#_Uw{%|FmjvX#Ez~*33l&UoNQ& zl?BxMO!T@^a@V^M4%e*IT?Bx%@6Q(kNKmbG;$RPWd8u1Plzq$ zdZOwkky=2roi_-bS~N=}gT<}3x>UuMl8BF?nwIUTrt48xzwH3$Nsy<|Mrkvy|;#&l{Q&ROVu=q^e8sYK%%sQ=R2yRv(2r=znqVF+J8YN zimJzyCol8^5HOiTMzAEBuezC}G3+wh+E5W3F;|=G9Ho0yBEg7ts5WNadJ;a{-zsdA zyxgQ^tOroO-p!3Qs0?N#wSvmc&uj@P(GL;{EKSO3zkyE;@fm_Zj#UM}4;BMGA@lvv6eGT+NUk(!yrC;ozN);d^ILND>JYonl@G6k% z{wBH+yd0Pemvj8Gsa!)W+%9L7J^uly-Cxct%Aplp1-acgiVo&rr5x?j?G8Wu(w^pY z6Xx4xn%Z(^;jEiu^l)5U<0Ae5==+&B`Z>TwxU;rWd8AAhDPmc(Xrc_qC=LO@nD|(i@WF(57+mzUP5gsaetRx>f1^|bEp0g&L)FgwJkpb-2f#586TZT+xlP_RUjIN;zT zy<_ZY=qG}H&$^c#OzgY!UXu>y_ugJstCU-iOWgBmj=b{)AEP?Bv8gEK^IIoUNK9+m zi%u~<8f$m9Senb5xS*#5W+VU!YUKk;wY&WIQ$Z)|!F-xL{vtlNPf@r;XoWJu-456n2HFG8 z_xkPJ6Z%mKOP^n3bx^yiPl|ug z3=t6KY?pO>)l4g_@TXBc{Y6M zJ{fkh^d|pA#NmL8hpb#fAgQ6^SShH1oVSt>1rHXZ?EyLjBVQoqs}1W{7-bd7YKiyB zeE@98TyV_e>@!WzS$*rZF-+PA%LedHlb|$vVKf>a6;Lv=+VsyaKBpH8$=M=urr?lK zXii88gI=_yDnL^*JB>xo5|^i#u(Q9Coo?`Z3L*@5Z7MOfDOc3Uq$|?M4Ou%+BZ;G_ zw>~}bYi4BvYeI>T7(;KQjg;3q&57Um%S~g3W_>C3fPAV-iOLkJUMC?na9zVeJw{focs(Z_$9= z1jBhf6y1j(5IITX18g^T%n>n#bfIG@BOJ2ie$H zUUI)9rv*D~q^CTr&GF5(6r&!)@)baF(DJD?O>}xOR+5-yHn@PB)ArT4ws@51bfo8~ z>av9`yhk~?&FT7iBQ~P%EXylnwGN~E-@-~&#x+C6R?#0~^whJagMfpjV7EIP{yh#1 z80;)i1G0`=ML(o%trgTolA6iCxlP%79N+CY3I4Zj$KO;x>h z-9hFnr$^H^!%o>4wl}B~#4ahZSq^6@h|m>PieB{BVuAkXTjeZvhBZT40UV}k0SiS) zL?oVvBmy*1Usp?W!j5N@yJrNhM%o;$CKkmGMtMag(y^>fc*{T|d_6RzVC`F1EpQZG z6`L5o5Nit7w0Evqp$i^rw4GcThqlRjVg(O8F~^u9uQoyT_**_D3II%ilmo@t%+rf9 zz(vhRU#;^EC($3`s%E;%qGegjp;QL9prB{uEJ1)h+dbS4!)FK_Xp3pfzeT-CplY_U z_t6xs7l%dy7U7|B!AweP0>O=3uu3eQ>S7v$yhH3|B|10^h-nK_a?T#TRJ@H1WZr8y zX=;wc?E**|GjtLItk2lwhRf^RJlqab>0lOb7O$|#5PA(WU7C`NU~`rdvh1#@t@U5- z5l+ah=%tzn(8x!8K&>%Vh4ga$ketvpbOj7k4c-W~udjri9eyNnuM4Ft&Ch z4udj!4wkYPn-@$^&!2S6ufk87{PyjIT;0PeST$n2DWqaJBf$J-Umkngd{bota**$a zLasH?6@p$ zR>}?Hzbi{-r<)jTpN19-h*{H*+~+KXgjB}6mDkx1yphbns3O}|iPxNF07rZNoOVu; z3|vz;e6~m|0$5Tw%F^H(QdKe2zW%WvrPtGv^0U;1;^nZmoo^_2fH`WZ{{Q7a{Ok^# zr@D6EiKUYl(H%(T8og~|k7!@Iw~YteDXqU~)3-})!Cfe>nBN+yaOZZdX~t3gG{Yi7 z0!i2Cj?P!9A(BmWb#e`ClXtc+mEt)n#%2hSES9#4B+up18@7-8vcfTVGYTQ&k61xAAK^tOv zREzYz@(LF&Y_;$QLQ5a-DC*=js%iZ6xy;H-!_#Kgsn!7vswLk0I0~fOH=KCRhdhoD zXte$asxGDj)jPR;0L%rA3Kj?SgIKL{pHL7rl91A6Ep4DOVo@r5XH8S{*s87?W7U^8 zOhE5bWGRUPBM77=fS)}@Kj>K5puN^H)hxjWv337IQ)nnZ&au4tHFAxHSGrqvPYo}~ zWb2%hRmQJL?Q|RX5;$K(BM(K2?(bl{VMfIUy~T~}o^nZ+Exy~fyO>$cpOB{S3g(ed z?5``bC?wToVj|#~K(ssAu@qD|-jJUnyk048#W0ybXD6_}$TxPa-n`{8buf&8&3w9p z*KPz|9sTSmmV$xbY?=w8D*Ols^I;b+gI9T{3=3Y22(H`7?<=v_?1j)d(6bNM`8bbv zo&s^^1w1hu)`c}xr|UFk)t`!WJcs53M=j))Y&;$`;u&QJki=nzio_7(WtV;RFK z*yW+4q87Tjx{QC!#bda;Z4%=B-Z0n3)~@9ArN(-Q##PM6Z9(3FI|17p?eB&&ejW49 zEp~(RCYL;ly(;ZFNH9f9r@WX;dSTABKBHg*a68 zTuC?ye?k>%8`I-w-w2PrJny9@?|;3d*OBE^fbQ_Ap(HZckqiP~;cTW3>^7tVDo0Bt z3#G2#wmEHsUeA0{7rwd8R?b;o&-^@dJ$ewhSDrvHP|QNLXNZY0O#mrDV9^wR$IpGJ zfF{8g+UIP4;Ge0|_L;9D9wOa7h<=YMislKAL_t7wH7b{%(D9oyj`#%mc?7Ir&#ZeO zj;=+tR0-al4_90%IWsKF-eY+CLn3`Z3_mfQabBjS`SRiB&YXBcW9VcDL;vFDk!<)F z>n(LAF-a!K*whkku~{%ZSOebd}3 zCgpW0*TO_{@ictPiNLzJj&4h<0neo?pK319PCB?dEs8yH{{vvsj_MXae-VsOSRy4X zdAlYvMBtLamkaR<0iEUl%lDveSY6|X*jv6y9q+1fgTBj1rZS0>Sw2wW>APblwyb7q|uy`^G#>c$OVh>Icdq;S^pytUk;Re>h>` zhc_UpD#YH3yBG%gisfwdkdn?;TC}gB+g)lE?Kvkj3GoKIU|box{P(h;_}TPvriuY zXut!_T}zTa@xE|SHqXV}yF2AQ!L&}M1%j9Ry_=jV-ajSk$PGq=e0%tbh4~Ine48=) zfjO~0JRo=~x3sBU`Pb<=OCB51*SK$)mhh%zLf7zo@v;$emqeWFgeK(`F^_!pP$u(v zc;xvv2P%Ea*x^3@$-#@baY3~g2nm~Sx+4I6R`7EF%X+!sRgcZ*-ZgfViO zS{opuLL>5zwCe)z3vEO{FGCLhs$CVM9GdZ?PmYH?OU<~Ft9|!u^227FklgrT`8e>Z z@!$E{li7r_)h%gA^t_6pVd0D_m3ebkEt$?IjRrSHcN^l@aLG9C%Y4;pPZHMOR&Y>} zUV?ti@MAy{t`UV4Y?vs`HeL*XBovu5IbF zUbT1T=#t*Je70$LAG*KT8Qz_~nET3{R&uVl<9R(VB_N!(!I6K1Qa2vzCNzBM;brF| z%0>{6aE06Hn~Ol9nh3fmAx+;aI6xnp^3CsL+g-7vXWi5~n<+y(@iD3;lF_bj=BLCc zR2yMmc8t!5s$n0hQ|6IV%8z$XmMNfphDqBt2!CdjIP-d;ovd{k=R{ap++JB@U$9ZI zh$HuKK%psDm;kGA^d@hTOgTJ~$o(@-#l;8dKWE8`skkd0<@rSur(bJJrB@S`l4yf>Jv2il?tTsQuKPa%Ed8 zy6b}L(rDu>5R@*Dj0G3vAbY3t=mKCafNnPKcMy*!pnO$uyTf0Vu}b#QM*r#Qll&~m z7}f}cC6sRu=0XfmyNlKwqiPrY{tZon0k??dkge(V&TO8^_!BDE!XX%{n8=%K7Zg3J zcf%}=Y`X63+4J)!5ZLv%WcrsA#tQeW>}B_-b>>%&NXUavmwXPnf)4NRpFf5DDh2JI zWv+hlFr#y#K!PLj{FK)8jT+Eg!?bTO_**d~r2C)QhX0g9neL{owSBp9o2QK7$%*)R zmG~7x8t3<(D3T9B_jsZoKLbaxvPPxYO!ra|#qxW!2iGWc!j;lR+mENjgZFv?zRwsj z6tL8vscf0o!zIJ4v~BNm)0kLw>a5t`c)*%?O>j5fZo1 zx}|7h`6BtCy0x_7U2Wy+d#HE*ib&B1&#P-RCBpXay_KbBMu54xsY6Ow5mGlVcMI9K z$tB{%SEkM5w1s#b&A9Gu4dyo9xV5zN&Fd=CAL8f(@I<=!*y1b|Y9{9o@sQy9`_F-8 zV;b18Rpmbb#VYNP(mmSD=*B;|ZEin~hOmLXy~Q8ThL!74iqB@V!jjjyVht^JDj9!n z{_Z9>4oPr!QOv(W26{%YVnbzsaY(egH;%8uwX*dDw{6S`z}?+D>aGV|VPq zBA(%77mSNm2*(>GBT{3N#X2S}3$bs{t&g7xXfB(Euv_qA}y?)x*`>GWe7CHOZ ztpz`96pIgr3*HfYd4{}W!17?4rHkl^3r?*wW%S#!t}0&K{Z_FjpMs}r#;8_2z4%zM zgT+8;ec>Ij+s^MOUHaF(AOOX!x+79)@U}%NQtc{VkEUkN4aM%Aw}G2M&=%RWFd~=* zPY3}fDv*b#%GQf_$7UnwF(M;xTKgzc-fSG2h%53aQ8U!qz?|&3tM$*6uN@l@f)0 zy;=uKW+)h_1#aWo+h6R?CmV)1;>8C*@s+Ag58Aqhg(TdEA)oc#(e;wO5l*_Stqke%XKQ~mVsVm9xTLd`gZ=>*n7;Gt%x4t4l?<1cc zL;p#0HvCMyC?hHC<$U(`YlLKgMWbfQt-J5vczjEdxr`;$Q}QI^Ez}B??M(klzG>wj{)@rj@90o$*p-EMP%{=|VNZ56(zcIt~N+dtn9?`B?I{G=(kfin2(V=+$j zCJGf*cThe*fF9qsMFxe5&S^N5q|oV5Yi)>C)V=4A#{}i^20W|}0Y3QU+yqSBCGoYy!=;JPtuw);YCm+5C|f$fG~O=OoAOfj@j2wA;S2$Q%k_vYNcS zdfK?5tSWaFrqSCK+#Ob$F4%+D4xQ4(%nAYit}wmu#xx?n@-G!W6e46}RzP@W`l>PF zF~9q5EA5J5qg>O7rAT;M9SrZGus_VTUV6)ulBnd4zb&6CCth$C4LMzw9-k?M@(D$W z;GNm9E2H*y4rHs;j`oGSJyN8ebuY9o@D|~`TCKdf9z!M97_UpS6))~r7H>7tS2Q8Q zHBibXbiJqrSDhdQ`&9Ry>Z3`>lSjoc)$C6_rMN&Ma8(^98M~pvyVN?!1se=x)bCno zX=<+Ch6JFj)WXz(jRRiM8{g;$UfX`F#97Mhszk5(rLArRTmPgr(UXzAirK zfGXTeeY1oR(-7@VUGKj!vIf-xThKzsXWS(PGVGTC>Hb|;Ak1zsJ`GL0T@`XJL)S- z469V0`qXUZk$K^zd%=-kSnUOJEwgQ^m5mm}b$ zLfPfd;xjticabOBM(gl5os3HkssdclGA8#JeZ}01pBGfOtJ!n4W*9w6SpScPbA6vG zF_g`mT1ig4bQ1RuRD!e-+H50uFjhAC35R{1@n3aRvs+T8{GDuYwJaKM-BU+n^XhhI zlF_T5G(YTF@zxXOF36*@=cEd|kf(CV)h^5zug&GK)@}@>HiVoaCHVucQ5>&a$0 z06b@a+1!{*9TFNu!z2)BuTT-bUcJAj6|y@dm8gZxyltsUYfEMOgVj$Y!{VKX{RsEa zHG)xx3mhXSIe=INVNLJ7H|zu8i&wdX0$B5W@Xmcae)9>tB|?4eMB!TfaWVZa=># zjQRsuvH%*rm}wJZHaLO`ghlIMlq&{}K;&Shx=RzA34!6e%(u{;0=_RQU)^%3)DDW0 zas4S%mkz(#hBZff3~pw)t$YB+l%D7h1v=$ITkE2Z=qq({LF~hfTEYRlT%CL?{rkJ^ zl=i^e&etUG?hOv?woWi+#Y@#XD*~2Zbr94gEtWm=q?ALF7qR%vPD}`G1@<3;KF)eL1cx^5^ zHC6FQKpnljLS07j^#?$;5L6sbY4I z($odd%nQLB8_vCxuMCo@H$4L#hK#b zsQ|BP%xq1!4_+8zKtv*!1Idy{!VCcK!XL_Ho-j2NPgj^0K^%K_b#7>WGj%s23;CEI zfO~r@o_KzlO8HNjmMm!5)+1v>AL#lx$j;V1AE^C2+Ee#;WrXs=ceJ5sJrz}~;mOu; zBS!hGED-@II>wBkkr$PCt)o&RcVk;Z$iw0PmriCohO8A{20xVAKXHRSS>4C(4yKvv zrgP&KWUXvFkMv&t`3cOOe9w_osr~>YRPoK(jEO+c4_sYk3$**Y#PoTL2z{S67_mB= z(PDIsz`5zJx;8(w)*6!}x*>+#H?sqo~ft(gGm5O!I@ZaakjV#s2PXU3J zbvHKRE)U1NB?R81i@gWwR{tUdbjhiLO4*kJ20bea;s&PY(Lj$kE8IdF9{|BDRne3` zjO*m`FvlpX+hVL~jYBg2j8_bI!oRjXTosvX#%-SOdN`D4nx#nL2J6IbU6rPD%<{QU zo_UxIAip1B8rK;UUCbrsdB#T2&4*l@V=;EeKjH-}%AAy(D-R|!hlEh8n!JI|=9W6w zxK5|NihIv{D&g*IeKqxxTe1K|njZlAXw1m6@R{zL{k_K7i?+D7n)l{SrYJn%7`!peHne{j9qQLan{Sopv{j}&aek!u#1){Tjp7o#{# ztQbhLqaKIf4`1_kdp)u`-xD-f{7;-e_i3aH#NV$8nafc*Hli}yDmyvUh}RTK@mRoL z;e<>gUuELPEo|5{jKoyTg{MCNv_?n>M7p!~BGdo0XRD5t#~qgeQ+~1gMuMmQmJ@>x zn>`!fa`=J?aX;4}^@lpr|A}l(B+(w~2-}9|o6pLO@6$+7#huY<6Z!r$%`Mf}|BZc3 zBrz8PJ|6fYP8wI5feH2s$3AtYD5GRR(4QO6uUuHZ&6e-D?G;shIfD^OpQ^CwosB&~Do?!(<&zVW%Wwab zWCEBD9-#lFc(TlMcar0YFcm2E)ror5fFaTyT@#W8%P#Tv1;NM?Xs!jS*C;IPpBa(o z?r%5W2_or<<}ar(NE2o$3hH z?mzsE;%0mFjxrsvUCb{<{$+ZstmwH*JiK^;WTNLsR3@(+Imi}a*vEQR^auCrKsl8` z0_yw`QEOK+Pjov|!iaZRyIt8hNQ`XpkX({b3NxccBON+PjzqMjaMG4O*{!p?Y?Fu~ zD3n6>UNXS*mjg$G71;fkZjxJ)NL|n6i;Pg(xb0U0)cj1_JC#3Lfx}VtccFMzQ&paU zDwJRq?2W&qGj%S)DZB)3&>Jim5)oG0cts^Oz&0PLa2v@%7^7hQAd1SEN_YU9VuGSH zo(ZPFs3b?rwaHP}6HDv(VMa$mRQ-3Z$rA@d4fMfuY$_?vEp7~U{N5Nx=>qvQO14b1 z9Ca+VuSZUq=8BP=6hTmD(j1bgG;aSdqX=C0OWGp|=M(5!!|}*Od81D$T6yp)h8d8} z9fR5(pkZjibD<1Nwr8f*ELDV{XZ)oQ0w!R1R2tQ1@Usdr%9kg=-Iz{b-YQtekXC5_N2==+%S#`h6SkAJ~KyL z!1JP)EK3=-6rYBs5JW~~QFejBZSnsA+3xh#!;6)v-Mw3NJI$v6I5R}V6R@pJd}#jw z*m#yqxN?Uvj0<*!+}&{thbGbxVPa*Yn1>9s5TuaoRP1cP>2qS_Y@Yf50ET3|f6(zEz!5t#v}!&we+!K76hZ$0 zmY){yeXWP2x1xss06h?KB_9fJ>jL}W+|NY!it1`dl$a3w$5N0A~vkm@W&F zK&;|Q`Oe)l*Ymykc;{mK5>Ims`GKa_b&V^xT9&S2X?*-$20{M!1Tb^GOOfI?4BNP< zEaCH{*!gqk6BlltCc^!bvQCdb?)Lg${Nt{7>etU=iKzRTU#n#LzH$AzIqE|eyM`&k zxK4KN==D|A-=Ec1Dy@f7xAs%U`uGucxenpXsx>Y2*lXA8cP?pDuF>TXp+XIms#mX! zja<||woMqG5-c}9LP-m|k7rce8E&yZGAto{-?hjVve)8AlH|)Ck$go?m51=2 z8}_U*h5fZ>`~6Yl(>(#xQJ9FIFn_L>wJ&d3V}C7nz4%kkacts$2A~N8a7d%5^wGxd z`Um4b=J)qz>&rNsJssOlTQ|+hF9<(+X3_-OZhs&SSJODUyBvo$%#pV^rpTP&NaQa3 z;%<4levJ1mvjq%N7`+GmPQG6;UFbE|`riI6&zD-OTA1Iy9LKsZ$8LTz<$ljD(`4_S zj?M9Nw$en}42$`5YZ%z-Z>G6|OC5*R;aTDMex7aGcKZk!-YY(27--*i{okeOUT~?E z>GFF?=lfE73kzo(obzVq*5I_ji+EMp)T%le59*3v>TS%&$m-S{%ujH3uJci^MKJf} zONRHkX8UcZIl0(|fnHHZR%iaNW=Pg&i>|uzBwYMrV#Lc+6qOeNn>K^m8lApAsBL(N zVSyD;BUjAZ4NvFsdhvJY81W5$QhpwP45Hc|arJxUo$q%AzN?zQI9cF>`Q{AAzvftxpK}ft}G$* zCzjPXS#%JLCqP3RhYCN)8@-tLM*)N^8-^s*ers)af2S03d7s}-bocEaz9IN)nHMZh z%VT(vr|rk`8s9&!)5qR#VC!Z&W+?y$umjcGH%_DEZo$olVATvhUN-(ePByBAE*XS_ z^?%R!e=@^oxX{U$GA0=}N4#U7)djkd*JZNVaSe0kKYN2RMG_QACW7_-x4!vD$WXOg zrrt9z^lkPS`tmeuyFmjND$vvCuOqQ$0Yv%jLQBWz0B+P zx#B({{ZITz{qAQT;5TWAl}p`K8lWXhGq^wj?Hhb)gOU4v?|rFG{ddiaAT=6%jvhpg z>?deJKNaSe)BgZ0S@q38 zT1QDoEDCsur7QhqZP0x#)iXBsytwV#mSkoaVvJ@0`w1Gpb~@{Gve|9)=UHA~{+)Uc zrD;*Tjkj0_%QJ7c`jcKi)TqpHPnL295d7Q`&#R7C7kAn|#*tLbPYuF~tfrqLV&+#N zJTUfE!toF$L`%XxE7|k8BtFY!v}p1~JA%iEP?s{LS3F4p-{{ zd)%S$&CKi2eKxO&@B2upyB?K$oRbXLyR*6m?6A`iPKEQ=un$bGM{939b3P(-G+rQE zUU80pR39_4*=(EUfFjsf0sMOX(xivr@<}j&l590T{{UZgKOw808{qkPVv`kv3yy{- zv+DM}u3VCKA;TC#pINOz#Y~y<%0g(`7*E7_uW~Q(a^!Ojve|7bpZb!%{jWYNaUZRp zkM8~d05WUFm~S7^69!-%%fX6hn1ZPdeqs?(SyPEBaW!Ihj2d*vMB*WkS^IAkLCEYE zeX|}-d34nUB9bS`wW7D_5HvbJyj{bUvfJS$C!Gcr%{kA8ruyuDd(qvv^(N-?Ij%X2 zEA?;DL~pS_I+AO^HYTIf;fg7eB#8tN8UpX{1NtX7J4MiZoA!R+65rQ@xf?B(*XdvC zN6kM+ZBN-XHGeazXKHzWuio!oIy9twxG;q9!DgZUgp6{k=1pV&@J}?KIfAo)e*=)A0O3Cy*sJVRCtNPo!{dliI z))c*JKYN%r=r!ACG!0V8Fe#r1O%V{r!`fzjZ>!XMhRbEL+WwzZc@O%WTNCP!A^!kV GkN?>`nbk=E literal 0 HcmV?d00001 -- 2.40.0