pax_global_header00006660000000000000000000000064123100722170014505gustar00rootroot0000000000000052 comment=f3169a61d00cefd8eff1ca525bc485f80e0cbe01 lz4-0.0~r114/000077500000000000000000000000001231007221700126635ustar00rootroot00000000000000lz4-0.0~r114/LICENSE000066400000000000000000000024311231007221700136700ustar00rootroot00000000000000LZ4 Library Copyright (c) 2013, Yann Collet All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.lz4-0.0~r114/LZ4_Streaming_Format.odt000066400000000000000000002647541231007221700173470ustar00rootroot00000000000000PK 9-5C^2 ''mimetypeapplication/vnd.oasis.opendocument.textPK9-5C content.xmlrK*kN&ŶTvLV5,SUc HLuίz1~z(A` ͪuH. ],ޛr0=Lfч_Fvx8z4^ll7o|{|tl/Og|47}/Ӈwo/䝩]Wf(]>,qw忯hxId$׳x׌ߞm {s/ǟ&z9, vp7?>.6Թ ?m .[W18;ͷrr O7q|{iĞ Oe?ׯ7~~w~s,}߼wr4;|8 lmhμkbY^۽ooh:7|gśfocƷ7q3p8m!ߔa㸹5oeto0?\x˺qyyOd &kbwa0k7>av1r}6끵?\,{w\?޾~]d>8?EY8?f'+q>o>_G -lz4vxf1ʘo T5MW+k~HOU~|2hipԼ]ͧ?nVh|rL*uȄѬ,g'f|~^y2a|;LnC~̋i/e\.{p8}*̮__jWo_+ﯰ^g9]x+o| 0t0o\ŴQ?laɭ?&f?9[q++3.wk>JZo_7/"@_]O ?'Ÿ@P"L' "A0 b a7*č qBܨ7*č qBܨ7*č q"nX a7,Eܰq"nX 7Cpq!n8 7l^Wjfkl&n&pLJERUIIfVV&-Yhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhha+1Vc,!XB\ c u~8B?|40_9#*uz1ػe{W: 0t a]Rf1c1+Utw߻2ÛPv݄?[AiBB */T_P1bB */T_P1bB */T_P1bB NXR,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,R,K9,K*W}N;ݨAF j8jPQZsԐҳOPd,,,,,,,,,,,,,,,,,,,,,,,,,,,,$0MzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMfc C)0tس g=;A`{xà =:\p,bz.dӎC@C@C@C@C@C@C@C@C@C`C`C CU/gx8[.ggzóy|p2zA~4]]0?Ko{/׿K?%Mr_ pyu0}A4ntf}uѱ`}cvW] x%C5PuuMxZ. ;0\uzGpj_!&0`6]u$€لՑ fSVG3p539Zm/B$I˅ \]e4p=FUߪoI˅ ]p=gN?G-N^C;0\"wfyE/2:Xuu|Z.]-w`E:̇_=_^dBTu=G T-zTG3xd7\f湮|y48jn0=ێ-v#hL.v<}OulJ]TW>{nW *׻G*ufS]z79]e6Gd|,SF K2|f-O `:6 px2z,?aNѭl<þ*iy't_IÖdqty\ɩh>*َF~Gӂor|˘<[{ޭ6XTo]v$9ꇾh>.׿6so|# w]!W V=zD[HJ4(z֠@Em-#ZFlkI c B q4c i6 0l@`%ـKH1fc,!XB 4%;IW[h>lW_f;.r]YP`q]YPFP q]YP q]Y|Pdg#01l8Bv6c,!;1KΦi'jGUo!2W|;cg1v].=e]we]we]w`匽s#5TQueoBAW9M(쪥 E6  "[ՄN[1V`Ĺ#(qnJ[ic i/0&^`%MK@*fcjGUAqWh{)JJ)݋:DP@:}ԡuuCG>PQǺ:}ԡЁCl:=t`{ЁC,0 l#F6l`6md l#F6tmd@6RzzQ;;0`l;v>|we5fTLjٌKFNV^fnv~Aw|Aw|½ʽҽڽ⽁꽁 "*2:BJRZbjrz~uJãҫ͕V;$Nwۄ"jrk3]L(gF95˙Ytrk3]L,gf95˙Ytrk3]L,gf95˙Ytrk3]L,gf95˙Ytrk3]ÿ5KXߚe ,[f5YpͲk-\le ,[f5YpͲk-\le ,[f5YpͲk-\le ,[f5YpͲk-\ld W'm4?GI7ONw8Tw]Eկ07/OM둫\U*+6Z7˗:Oͧ{/o+t:jBnh>lo>ir'q_`d>k#_ί>glrrˏہOf<-򴹰S|T.<'׏hyz˭N5{\ ~PQp+k=ZQRzTԣU-jGUK=ZYRϪzVԳU-jgUK=ZYRϪzVԳU-jgUK}gҍ0xV:ԳҡtgC=+YPJzV:ԳҡtgC=+YPJzT:4K{ 0c,!K{ 0Lϒvx_;<W Upeڗ?괿ӳW@zQ`*{TwU>*1H* HǝT|A[`[`[`[`+vYcϊ{VسbǞ;رgŎ=+vYcϊ{VسbǞ;رgŎ=+vYcYx#Io̯ge~=+Y_zV׳2̯ge~=+Y_zV׳2n;oXuXuXuVu*_u{NZ]U^RRRR~KHKHKHKLKLKLKLK,-1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 . .Ky1c,!gXB c 9;/0rv^`%KHYN1c,!%9XB:m tc %0iK`%͕KH)1Oc,!ݕX+WÄYQR zTԣ(@GJ=*PQR zVԳ(@gJ=+PYR zVԳ(@gJ=+PYR zVԳ(@gJ=+PYR zVԳ(@gJ=+PYR W]BWͷ;o] ^ޮYT B0N DU]uܻãכڌ6cyׯyca~.o|ףY2kv}c_0?zmUT.t;z*Ƕ EϮ`PdCUvjDD"llllllllllllllllllllllllllllllllllllllllHlٲ!8P̀*dT!3tUȼ<&Q ȋsT3z;W-uJq߭hՊͱUu9O5W+6feH۠@۠@۠@۠ƮApApApApS>0"6 LO+ç3vݻ0`tH0`v;0`b<x[Q 0A`lU!ƃغB1A`%xfftxUX[Uc<2P60A& EL+V,2XdZȴBiszHcgّu0q!a1v},:℧y_ҩѣ(ޣ(ޣ(ޣ(#ףPڣPڣPڣPڳPڳPڳPڳPړP:CQFIHFՌ%HLLLLLLLLLLLLD0Q,0Q,0Q,0Q_-'ӡ\בo]aM(zu@݄z-Ճ u@Qd@Qd@Qd Qdeբ0;<+q߭hy-N_^؟ZTcK:15ЌfD 4#jQ͈hF@35Ќfd 4#kYhF@35Ќfd 4#kYhF@35Ќfd 4#kYhF@35Ќfd 4#kYhF@350RA`% KH12XB Tc /0R^`%:KHux1c,!gI ް|7:jBnh>lo>hx<\ ?aN泋Gfhr9;[dt\vxy/`b/2򝞽PԄ&5&sPD JWOɬZT=dGvUQ`!'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1'1''%KVu`%$1$ƒXR3Ԍ%5cIXR3Ԍ%5cIXRY_շrG1uU <yQ:t{u78".".".".".".".".:։݊݊NdSdSdSdSdSdSdSdSdSdSdSdSdSdSdSdSdSdS처@ЫO5Qڅwhۅ׵ۅn܁#3v90`6iu0`6i!72727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727272727277KLOLSLQWL[L _7BjP$! HIbKbMbObQbSbUbWbYb[b]_ v8]h>2W"cWK/h6}iu op#K J B.1v]`YYx`r匣]0{Q:v(0`vlv`d&0uDl&M. MZ]0:ɻ0`6iuw`$R`;;i!c8"0!c8"0!c8"0R?D`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%$L`%(,OPY1lo>ir'q_`d>k#_ί>glrrˏہOf<-򴹰S|T.<'׏hyz˭NuiW n{k母;_^W_^/_?p>6Q./Y6xRr_[ʄ ,Xd؂ lA[PxtY}Wܑ/9,KIg88-CGJSףG[uꦢNd k4ݎ0PvUpJP wUq{˞~b53R-x|AU8HTěqS 8ɛqzט?r^C QezQM/Uخ-@XAU8Rb V[,O1/lb2,@BNd 8O_StXXXXXXXXXGHǍf-W9W9W9W9W9W9W9W9W9W9W9W9W9W9W9W9W9GV|!&3򅜜8rv2 _Ɍ|!E538rz0 _evp*lgUe# ٞEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDBTd Tq/VEAjBUd Xq/fEABVd \q/vEA5vx_n[eۼ JruodovWϖOsc#]]o:kmf=62=LZ `>XgFWǓs8 {0Tگl<þp\V>/W:/wdv9^#i2,9/O ;9"G"o~ryhZ^׿4|YE +lXdÊ&V4ٰɆM6haE +l`d&X4M6hE ,l`d&X4M6hE ,l`d&X4M6hE ,l`d&X4M6hE ,l`d&X4M6hE ,l`d&X4M6hE ,l`d&X4M6hE ,l`d&T4 _X&jxa$jjUTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU@T|aa<qx&0 8La<qx&0 8La<qx&0 pB#! i5kWn 1= Rp2Xr/{_,RPPPPPPPPPPPP]mBݾ ]mr@/8w@ |*oq /Z)/s',)72Q V0ŧ)>| ʇav1oetWwܻ^*0kn5jt"V[M[8qѭ&ejr _^05Lau Skz]+ǫyf[V?.<ڭ.<ڭ^p v v v v u;^pV->ڭ[|[chnnōP5P5P5P5P5P5P5P5P}7t"yn.t-03QGUn &/l|ݞ : :2*TF7 hyN 2 :/8tV_p/(GPp/(GPp/     **8TUp/< _Pyʳ g **8">Z4\hOq߇wChCQ 5Dk$  |A _ *8TVp/ܭ _P[Ar|nkTf!zBxjʀ[[[[[[[[[[[[[[[[[[[[[[[[[[הfhp,?s>8=㍟>z/S=eb*x)_`2>ia)U̞u< |p||Lg?:O&W2|<͛g_}Ζ'O./}y$ ]/isa'B\d;yslFȗ ܅zDeЯȯO^ wF/?!? nnqV ǭF,R?n5dq Wʻ* V.ya/l( ^.7wW *yaHTPvkF D*(TPX SP WP [P _P _P _P _PkͽG[uóN.8&*zYSmW.vweBgUpÛUp# CEEEEEEFFFFF;dc?ʂ"@G"|A?  8D}~ﳮCm_7A޼/~mnXklϿ]+\+s>ZJYMiV\ȲBeŅ,+.dYq!ˊ YV\BŅ,,.dQqf6xIǔېlllllle]6ܼRa5#F͈QbdZ&jLl2QeD .5Y& i5`kP[C l 5j5`kP7Nt c)]Aʍ0`up#ױs\8:Eqz4:N~l{]g&6773 E E E E E E E E E E E ͬ;8vwp켃c;y;8vwp𼃃:м/+_un{ՖՖՖՖՖ WnnӐ;jXcƎ;je#=_bte"my]9<a3bx@ CSèèèèÓ W^ý'{|~D3K|5;ޱ~w߽#b/Dzr,˱/Dzr,˱/Dzr0/ܝY_f轼VgxXo_Ύ~V75urq>c?6yڿl lߗrL \s'5of*>ٻpO_f͓-_7|vfav\fFg|U6T<\S3VL H@<ۍN&#-O†h~6^,Ƴ}Z T/vp9^.4t(]<'[)w}r2`<N.4VGlY&M530UKVH/LӓHs_q~ir8ΚfS8G#j́ zp>}4OY#RQ=ͩf:,'5MWȍR7 cy AI*@Y KTqa,(QBa=ZUw3J$RD0DJi#4E=X\.yYÕHtڄ!D6GDz&#š(Y+|vP$^eInƍGijtYSH/ԃd4O4yMY"POY:P}7\;|Eig死sO|nwv'ϣܾf/W8u::GUFG}Lj⃿Lpe?R}z-:o0xG[mzP6pZ1= |<`vA . %MJ&KGbSNgi|ӣ )G4"QmؔsYͪ}ܼ*fJ*&Jֆ'b2ZTWٙG1Y >,UÂ`h_߇yEbn1cZht, ĂÂ* a<\5YhcD3UH ‚,~Y,Go~VQfux^oug |Kao1ҥ{N{_S7Q=]Y}W}ei>/ʯuɖ|YdrE{eLoy{&Y9g~=O~g֛mqʿrL$o*)E:C\T`8P06SLF[5X/%41X/I8SOB6xHJ=)5ڿi|0+mbd2l M\`%Mud:"HLbL2cd'@BP  *j! vL(>qbXdCf)Y?g 'ΤI]i+U/;uLq4ҿ)9M\1(Ν X|8m#8>x%`d t4U$5 x) RX oJ0X7En$I ;Mx<'ڣR)`kM S mJ,"[@A$&&P5v)Z=SLQ!fh sZhy:S8/M ,M0\Pމoݗ/黯}¶/_7YQNKkZohǕUhiqڎѵ_rd1\P&<-G㛐5΢_zì1=60=sy/εw93fS$SUPi$S*'i x *: q:~)2LVXͯ?IUٹ_I_sJ~Ud2T0W?o"R Jad0NcTX{|T|O~TXį],9h>ض ft%Ν k钜;XYթ6ǪٖBsؖXkX۲筪QUt-faZlZ//5}njQ//ƶ,W ic\njlj$ LJ+*ڲQіXux!e!V{T|[5CShD^jbk_jbji*⢳-FJCCh@EE׭;jKOq0M t[ BU m[aMm b}nAadp0t2SG[۫ZkLwdbCݶT =9g9s[\Glڢ4涸jj-2W#U\Aa6 l*'H̖DvD334cm>Jv)},ub㨲f]5+Hb娸C+*LQš+šl&&ay]\)Eab#fic9|M79-FaMWauum8~XÄ)U+`\TAښkOܝ(J W"SGnnګ(ʔ.WJ< :VUӠ*ojV-ʔ&W5SCϗ<;|EIUdzi^9qAwq*qo {m~X÷dG{G _ǁ/.N8%P8W)4%hD՛@ _ TF VDnyy4r/.r? o.OGg1Y_U/.c{{O걿coL{4V屳狳'mF x{Deѓ{{P{{jcgϷMTLP6/޾ EB5P??o4[)N Iէ=v|qf}89zz'H=_f#*౷狷7r>*Wcsst<& {+ 2Pl sɆiWT,՘3fP}9{ʾ1O6_=+Ñ/O7lY4)da^v/ua^qՑ'˾Qaǫ~@PIF!cUw @@Ѝ=4H EP7~@:rggbW(S{8YmW.yo6v.cC?ujShGef*u8Z J k^mG?赆ٝ\@"\r8ks)j,FWoTvoA/S;}*kebSu.d~ao.QJ>+/>WJB(UjQl~PY5Qѧ?~98R&᏷-~j>Ib$Q]pbunMYa\ 7d|%K띖%kO8-M*G?kqp6t6_,eh6q7mO P&5@ A0BQ>A~TOhYHO h>|,f_>g{߿hyԼ6\t4>9]~ث:n~ǟfZ|ž4nK[qfG蛹?./Ż+|zwDŽ8]~~4h>`lr6lp_w_ wvSmKσY{KEEs.@і@peH%Vq/ ތה_'ӆ,I_/P2mSJt t_Se XwS}[沶=S!=_TaINQTUۯM-Mg E#H, nb9~5|KJYM"gT B; *7u"4G 뼜wjwmJJqEU2稘⊘XS\=\T\T&MF2WD&}*R ]?_&R!0SL{OqPP(9:/#9 R̟Ur"1u73'ڥC޵tM$B_6;.R/rߎ+Y ^;QjqՎZl^U$DeW|P5H1v{ CinVM {=׃n\P\ $ç)yPI TgWnvsOl/؝)mܙH~e6{{0۞;>2Aɵ-TDualvzPvӃk;=Nك:\Goak>M>:9e`Kٔ>G>Gr%֠`pSN8}9z}7xB 8&& C UaiAp(AH[ 8 _+$jZ{cai<.'۟.dXJh(H & 2^jiM(<̂SMbaDAju@ & Rst<oOfpvݗ/xEtPo[.94z7}nBU %\?[ /b-P7*wvo'㩢Z* S&oDJFuYPt%oO/TKO.^\QSN0-xRq12`ꍺE<`򍿎tP*7~g 8+96br6b2nK1qrǶ C\QR}ER}0|sL7oa>Zο~iQ[ި0MLr7 G>Ǔ_iWBu)/I]b|S 5Td OJr7QS饥R~eמو-i{6P_)!vD)Sɾ4KqQPN$) ΢,E5c`cZig,VrdM^!8sXMũxf ͼ:[7Y?\=WIKU8k/v64AE6tq6^j*f0gO/әN14WE ]I r=0r!d%\.8i ڣ: 'MVg#Q iC{9k>,T:jh8Y &pvtlLߩ Y LV糡udrڄVMTh::d(OVɧב&Gc94M\¡THErU U "*2\ZJĺIߙ5֛TXߕMͫ6tO6v$_=9ũjTӔ:ljN+4]b`Um"fQmG\Q4(꒴If޺dmE18iokY`bfVH^MUhYKuI,$H46MS;,ͺdi&2YLUzR24UMЬKf R:Z@]R4ٛCRVӞւ. zv. {PM)l +N[fK0.YY4.ւ(E@·G4xMX 2SEKZB.˄)3Ek@.Ejм ֟:R!-?žSHRa3&o&_f;>kb`ZkėZ#WU.-7K8Fے#l4=.;۲#EҶL5#-:ڲ#$jA: x\tķEG)BoK{*ƅKnrh[s/u߇ɒQݴKdyQF@e#-8WcpiVwmi/ߖFT! oC9GNl@O.ooZaW0X s7*YC6)Z&%Go_~=]3Rmz*Mi@+Mت2 滒e¦nWɁmlJf d{f3i׍ NXDEoC{]1;5e?$=Ϯ&ڣž) vUj Dh+rw B{x6ctǮ#=خ8#,=ڣ*^~{m}DhϱW;l923^LTUσ'!B{]x"u>ϰ /t}[d6/OUDGB{] |=ؕ^`{3?[̮{sJ hQ#ڠ uuPb'45)OWO9#jM)< ,̚"s4ZjZ O49IFVL{Ź.O89WFhq&g(ti`η0NΕ TobNaSxN»,,@S@N[ 'Шx= Mzc¸#¸aKyo!1@4ucn/tnR6u Դ Rx&4cc7l Q-c!јg 8kT4j8R8EEXDcՖ4҄!Ac|2E74Qű(S3ED&aM,J*]@6YIVTQ;$̚,"KGcO,[r$ -dsi ),H)lj<$Hbl|]}kN 2D.'S )QbQBXZIE} 3'ȃ"!RPxQ. fL֑%:S14K*#!.-5{&F7}FT H(5G+I[oDT/a>ZηT6_JܔQHcecŞ~{߷fM7ڍu77 lnX764@Z1X T}d([4Lak>M>:t~Q= =vlеn ]nz˭&prPF#,uW x*s\uݖBPxBBfK!+&KViws%ĩ@%nJڿDn+}_b<ؿ4~ـoLs缻÷j(hhhhnEet#^\\V[kk˭Qjbq<U7 ;7iDޤF*уM7ۃ&ͫ7iΐ^I|՛4'G_&Gy%U ! !ULѵfG޸6 O|ٟh6 N|ٝO_(y<B6(oP<ؠxAe &StFS OEY `Xi%LlsjwƨRD$\Qo27e645/ J,dI2b`&|٘@H}X||QFŌUe[Mb)0QOb/7gMm9UJcR*֕Rv֔;M/q5VS-\lɕP דm=K 1[:b[QN5b[Snp6Ьu\l)rlc7KmEL#ߵUil-\^. iLѱ}]b[aN7i-S L\l+̩ sp-1c[d$ Tx:T+ ̚ %?;)k+*H:*i A0Aj8רnhxdx6SmP ]+ Ti-0]j d.b27Rs]$ɰGy7'| ^z}H{K0ͯߚx0%j-} )_,? NF$fEB˿roϧ'{wds-NgFg h fӿGō:nئDdZA`Ǚh&k2myݮ+dTYGЉ沦Kmnvwjs::ī%J6{"&xBI839SP HmrJ@j<~2Td>|tPdU[i*HV*fI9:\ (a2|/MmohYҞ8/[ {;Ly6HƿDmrlCטX){c.cg E<Z@P`3 'aLȲ,_( ǚ=+1K\f/"CLY; nmLqX xz%WZԀ..vk辱XTK-\ژ+QoV\QȔ+ \"+"`JJ `JJ}|,V+ɸHe43zIBN,a¤gfL҇15ImqIVxւ0oph+(Ll-L"z,2!M cl.脜uu.fAFLTXu-YS 5KvjGbzׄѤO.g٥)cz9QX¤1=avRFaΘ qdE_ &t9kq sTB273'KMx*ڂm1ɓe|9.@ΞJF8Y?+aSqd1Nh{'6RI*p*Uo(z2K 8zp0YZ Nec 2@0gbdkq:WX/KBB}6 ty+T-) <7YPy — fM98d s2t98}'h5)%̕l쳥 d6/58x6PCt吺ꨐ0e" <(H x0PeY@i@AE<ɦLqr\@%j-ҸLɾ`:U؛+7 W<(HlI'u_٢<(̓l+NO(ٱ-Ū6MЌ|.UXcD/:fQZHsy:VS|{ݮQ< tfrMG2R(5ŀ6AÒRBVv.CV '=] #8` =\/o|gH /v t!X_l!Xa8o rRt!X9:,ͷ%>9tijS/ t!X- w&In:,7hU:,Rm,qݶk t!XCvD!iv|!K;AXxXvS@'%̦̦]S!BB!Qs\HLa`hXd݃%09@(̦@z(,-K8@k77+3ۋn@3`>M3<9,C,rkEgl]яҏjDX}@](5kQg!?Gѵ3B'=՞B!uRjI,ޠk:ɸW$l'}MƾNdݭH^d R{W&ĥL|is 6/X 6D?\QWÛh5 8'#]:G'_D3ɘWԙk2IN$uM{ lML?&[杌mB˵&lBl]}(yr/^^]_Ϛxzbc}G{&lVGώwnm7o"E0!.U,V)bׯ_C7rfݭ`uQb R}z;u@*tb%v €d~bǟ 2sGd}`-Gd&= !nw2?agr pYGo9U ^向&d1u1A`)l)s"G Rl9eCO)_KjJFYT*?N )MSAHe?;20 CO)F3U UrYfx}J{Pa/N?L^c~*ZN:up>U wjsiهȃпy{ο8q7Y}6뭽jvvm6.;*M6 jQ)H>Y?ਆ_jn>?__N'ݝWt;zrY]̶_NuYNfQd֬3 ) /E{K7+3f_}q.O'_~7S}n=gd=wq|U 3A}ؽonV؇,x|8QpEPb ^⥀"H )BHD9{&8Pa ъcOa3P A17P19& b/.rI6ck 6\  5&X;9 %X,"(`'!Pˊ^āk (d(ZrNq T`=޹,B"ԻB{x~EG͎5 ,_*HͲ},f*H͆cܬ} ;MJYTLYTJ*C9YTeÛ7}Fϐx 1$j Ȫ }QcH?,GA7#bÑ!QCEwH W+x^P\Ul@]z#H(т{`qbxq!$Z9EɊ+2zD>C o?"[&КYdB:To5Z+k*7p[|[MaB$E  t"+SP4_b;ۺT1v !BbMe{ [ zgW'.6vf}ΠE +& }\w s&~;-G7wήwvDټWz`^UTzCl*^Y*Z}_%xsf,/)V-*^ف}!TvV\}ş+;&]1;nOPN}0ˮa>WvjG{*^2<tr؎~X_Y+;̃?Wvr|)%=O hBjI+TڀRa,ʎ$M;VZ *_~'E*_A_~(#AŚ~-.ECpeidҨG'eB*K+T lB*K+; d4V0o9*rdϹ4- E Y]# gIhtQِn0 ],>yKi Q+ݶy(ULUj&QS/j01S;ҰNM5dլe M5sNG^.^?O$eX65gr\1ōT8J2d*bx "΍\8eu)Lt͠8@Zc'.slęi\_O7Wo/ml6~5^2S-Sa#|SקOU1(~LrS/4MkmGĎ"Cd'T%(R ICŐbHK؋6iBI`Cv$g.b6|ElMv1ܸ`pÒ`xѼ$8NQBufТ("&4i(wEB[f0}Uz IS_jNpbM/'*/uaG`H5`xふěfg:@{`vvK1\>#Sv4ʏp2>3֤0'.y7T"R_bDH]`x4?EQbA/1-B& ͰT@eg. \fMSsZ!pN]"(iPlKV^V {9[#lK+axȊYܨ+h#E}\F0c4"X^inZǙ. }\Vü> "%䲲Ɋ>|pkxA}A#貞v{lkb>g]+n|2m &SxM5}6kÜwELY[Dv>.LMwyUQeK,Z- }\Lp|j֘jJ/gS݁.{9eM@~ xX-&AE~de~\AmtYrqY}h]7y J?.+lF=(xWA((N@Zvl@,/**n@.,'iIJ%@4`<)ڭW="7XמC&@ ͤwfTWvY'WL%}D0wNyN<'NBgD1"n3wE# `厠m3;,vVGfdj3~b,P/p[."p vc2ZIJ~b)ѹ7<~O\at77gz7?g!SNCaj@Z:՚V߰ҵ&aY +PkU5[}\!lmI뿁<]} '3,"tAĎ1؏"x "&%[)0AO'fI|&Lma(c7uD#ZbQOFז>_ީ~Ɩn.; tik[ښxƖ&{^& giL34nj=-/cOKҬ25|X8 !H:o\.Yepj+7Pj2yh!\kՖX9V[Z9H Ֆ]FHa(RUr`* ^?{Z޴QO{{O)}>wyy^zx=MM9x!K,*,Nޠ Su1²>˜[ .YPAV|[bƻk@sgpwC}Y2[N;;r8j1g+{G}Y|H;gp!>Á-Y3:]dxݴs,zYGLgq0`84Ԏ} G3х>9%_Vb u)=( 3Y>C?| ;L~|:` }q qE[$8b},-H4gpdޟwtagh*li"pj8C~Ua .`Z՛{ {U)}x^@N7(9@1 ۊ? hn;N(QD( t@d\[r2?6HP <)fc1JC[2Y0(ocb`A'W}|e3%zi2]4<`SFڋfNfc@jtqٮeRf;>#>J=,4,\,MLus~~h/^y!7ϫ3D?>+,{̛y,Cȏ"?DS?Yg8/iA>Z> l$o:A<h7t~'l{ɝ3}9֯k[y?>ϓYRV?}NV* t'+mf ĔR@>KA/VTy! )lOg{@? ,DX %5ƒ:@>gJVg a*>уa}VZyE96g_&dD R պ~m+Kt*t%M8J8QJ9 UeS>r (,%OHFHRR`u^bCľ*+FW扎p:D6ms6KRvQTĊd>o-2DdSDn>2TIQQ^O0o=Ua;X*zb<U녔²l1V<#GފCbH+XTm+h wAJ[wc8r:k' ytS@x ;JXQ,PSA [TP9OI A~31J,)˯7WEzJc̣o:JUIhz J̆$.Z& %CڸJ%ҝ(MӒ@wZF)ʝV|RjНVըP5R[@5y5 *dTT"o5*T(NlЮ-N*\(MV(JX_^ ėYݚ[ތVD%/kXG3$u[YF;}HNGHQݘpJKSF4Rᔒ"`d4q[m@ځ KP '(3)R݋l S/"( DP' 1\9d J< #yL\ld}LC~і Ѩ@\F hԀ!wa@hEEa{,ZyPg{]z5(l.dw*@2f2Be2ܥMeO"ˣW!Hpy1v98 ˙G Ew3^GԆ yl#llVSA/k*"(OOi3Ywmҽ-J-]1nK_PTV¢׮+ZQew{c j؞w+ٍ6Ews s_dr^b^ Ǘϛ1Z8e} 5z:[f ]5#3П u@(yK@H׶0тzSi_B)_O䵕.f]X6J:@mxTG bFP "i#zģX>"?tcM+C)>C)R`( ] R9WF bq $9!ZiZ麆hu H)t h!)W7|6\ fA)oϫv9N$_Ta}.Y?}wiCPK>|SǓxPK9-5CMETA-INF/manifest.xmlj WG6W3I%3Y6o_ʖx7;?'El~aȑ] b<X ";Hc;i4H1ю>yrlZ3O)aR[T_ gnJ?Pwt͐lDv,䁶V$`ο>q\0=KX*?_ V{8|PK TPK9-5Cmeta.xmln F_WӤN tMpyo.9(.e7p<ݷ"){ ,{z~p-<^bs0s&R3o@=yHjrSO[Y!za 6eD;Gi5[`M_k/كj6^5h0ėsq#cǍe+ j^^&~]SV?PKOPK9-5C settings.xmlVo0W"C`È Uĺ7\ٗ9 ZОWT:/@5bn9 G,9 D#î!F 1SP1@dC1!c9jECnOxxby^>YI#eE->vQn0uGs,kCɭHħ +akFm):BkUtU? #fё\Su6ދ8󃎑3DL$:nZۤͼf;S}kNv\=NAXЈFWĥ9yZ氢gͳ2 逗Hd*Bw#<,`e}Th:EGÌ ᬖ=WE`.QA1N!&q15 }hQ;zzgz@ֲj qd 58Iڹ(UhڴB?Wn}s0p߉/PKø^:!PK9-5CPictures/image1.png=XuXTץ$Ek!.)i{.P;DiD_>w{g^j*r$pppy 88Ƨg#T;9e DFR op (9%(WU^hWN>&w򵽹V'eQVlZ=o ֍qe|ۯwdzxn6]|LO??ڻtqPC 0C rBf{ }E#au#U ŃAm|`?m`V"}ͫ:؛}ZV.`)?!|ŀE~Xd7OY3>P398A`-UڥĜS !QO(=fK|sbx~;R xԯRߢa K#N ]9͑2~ո7B޲ &⓿}Pa]Wn-#&W#ߙWN,x8dqcXOXF:)w=GU@Q!+xvq?hcذYjW`,:AVݴ]_U23=Ta%Km{@Vbpj&Âl`^z䗜!QLBZ#JGB7 sϴͻ}b *,:ޡxD]fɊ]dUF}V[QZsF΍A[!|]]F|S}TƂ]FVQ 뱸]>$=BBtO.@Ȕ`Զo"e[Ё.}"PӼp]KwFE]%V[Xim[ MaZ&x[H(BP;=1P@c-"Ue.ڢU? .4Gmqh!-n9ޝf DۋIŠ r\9ߟȟM]]x?(#!DŽ4Dxd/yTұʇ9m բ%yGN3\&Xܶ..\̥q_[,EDCY6w*mѺ\hR_jY7/1+?1i U0/.pŔK7M yjL+xNĀ4=5Q4ަ r*be3` u9d~ Moږ;LYK$W(Ɇ+?{m&Coa |PK$E= Ҳq5ûQ(囕l AC2~6 \Ә1Mlkj33>:/WS҂/shyp:X,hGL~ӐMukͶZ\Uۻ:ELIL3ю} E @]aǑ0SE&: dx/36;wcmd^e-c%ɎrWB3^Yrb.(!4hp/U>S.yndHpYV{Өh0h55U@Vx;B*Gg̗n _!4N*F5y-\bq>ш5ޛJlyB,ĉa4 //ް)']Ud_cU KzSh~.%ՉA0 }#ToQx1^3{֤+ y}7*Bf/n+1뵳Or̆Ϝ &o~4Mc0c9> FOps]Z& Y>? ,76*ztm[ShYñ2O8 Gpmca' N8pG_0oa0X_yBEjH7:V۱jcb5.L,w֐};p|?fkH7*ߪ OmBN ⬖HC ] J۬H;VX ӧ/]9ɄRY:'k9g|YyI)|c<Y%;^̆EzwOStfx%NG/ e"Ŵ|j; o![zk |c֪?R(oq !Xt o'E~)}" VerB%Kzԩ{wc(k"p`mF[D;(W]\]F_'pkXnQg$`2<w͊6}[,O';?ۀ[8qIxO']Vr5B۔dOIA!}1$UI܈[bzUec#68[臈R |g;0c/c3z'^ϮݽPܠ-9QQVw C]_IqGND!\diSܓ,NT uxce"m%!\P5:x[K?İK:T^;Mh'jqZȏ?C7EԢYZ*tzguB#9eR}Ba){1DrAeky=<9x.sW?҅̾Ii~@' H u*wQI*{ib)Fq53A{淀>cW#\RRΤۇ\+%οa\GK+S-vzyY7 ecdi9uNo1_`t"[.peOܯ7`![{Cqb隍C&mѰաNή)bj x lv[vGͳ^iV  (7Y Zwd5YV:>ϓn5216JG&mP]2ȧȳ7;v?ԓt1(<pY^OwG<䘚w}UHy&rDj= ov3hˏ?wh@]m(_}@ʾI>QO[bYX%`a{pb3;>eG-&rN#_Bo)MN Z|iT=L5vQs| S;i㴬tD4.i1av4LRj9g2U5bM`5׋Wa:pq-aԪMKRlc'9f*bdj^"ikTԯ퇼&.(a0;T\G;kN֓m~*%F4+HS[.lƗgآ~}gFW%å.c=d'Ǥį(T`xۘYNkKJ#pOY_ <;nB- ,4r-h!LFMj*CDi4HYC _5Ϳl}$K5t3c.6 |}-vXq6* Dګ9iMlb0}$8SJ 1kiU^@\;=ECuaIt\Kx (=H_i"ŦZܖW TmgT6)1e쾢ORM6W_ƸP`L.Fvʈ0L/f[]#$9cY,ȮwLߧsm#CK^߁ b͝hN,oaLayėpY/~3=Y| 8>:-6!d< CO^ܟ)s<#Ԃ\Uv{-qSm sٵ[7QR6A zی*LEJSpT(b6ur4%~htl=: ~=Quت$7TݒTC$׹Z*& t(Uۤ0pV a::Q#~je5 _AaGYUkAis:_ H0Z6o |B]'%%GY9ZSwiKG%~36º n5wT.IL=g2+Y)a5~?Ilum.VNᇾs]^kƝԪ{"nF1'?f"m=kӷ?S3FB_C^LCm(ZWփ+$PyvlLT֮4m}Oa͌V?L܃ Ș9kl؞OWPYh"R5aJ|_^{yre Lc4XN?Wfx/?Z.Hc%@f)WYFu6ԩ^PŒ\F=p˳S&n*tGA).i Ff9ͧV5[+tZ0ۖB+4jj۞L ɇy#WCp{즉/'9"IUUu ҀoU@` gRI]7뗺󧜑1o(l8DEPm|mR)( <) #[L-f0t+/ %AZ!ZUJXL?h"D@qf:`gV%Lyx:fGNU LH-+0>'J$_cܔݧ9']` Ei&OH Z-SC).l:Kf(P}fC܁\*(jO2mÐWz*3+-% *Iǡ qвmoC#"2M䐭0Â&bb@jog/ -LXg m%t,YPEm$bԭgH"-QӅ|Ʈ(O&YU̒ f3?qD "MS}ε *{2g>Ta9uOl2ɢsOxޜj-}Lǹ⹬쁲S *(.-갦p!(jdD<*6eFWMQ;E/>9H3Yy|L5WxU.ܶC?Je1#OkaK7VY%Rf9 c)ĺD|v!! ͗xr2>0jxtdm[bQeڰMCo?-TnBwGy>gLY čh*Em1lVa/1Y3 9Swpq[gPQjrR~hB!a1N(El^>K Ycz%"PMi)q)@DžzAqZ+^j%MI(/ %lshakap^ryD%sO{LQpL\EL1rS"]zK>i6ݚY):Csf0n)(}%b+KcWTXOVdԕͱ O>Ƴl$8%T8!jnnoUM6 ^CY+?YjK\;>:⋥FG-~ܓ6deO^ޮC%6 h5q޼ە<^VdcJMۉ-}yߴjA. MMԤT'i`;|r;04T]=kW_6[SNvE[H ^Oˇ~fC("BͺLv? :~K#I+6.:,2POO%*ZZ_'w.IjmlƁh/,%mlVBY,魰O]Փyh}&茺~#5O,YXtFx71zGb179OM]l [\6v{gs`qIK˟th .Ių}cT3c87ҽS29_'>H6;D:ّ| P<O#FxyRG fD2*A!vϮ ByRYV֠.RJ^&а:H^{RW>~~/*M 8 ĕZ c`+pc^:@S!Qt.Uanq(uEm"i4\E|]e%eL9_ҏz2 H|J\`juC매Bi!l.z3ɢ#%A1)I,F0yC .P1W"dAf^LU.y^= oW[Gcd8BO|YI{J4v|P2; ԻdR? %Pa DOFZ? __i(!|mő.u]+{Tpu E zD =]Yj)PKfRPK9-5CPictures/image2.pngXW_ATiabDn鮡%K(CwH7C2< o}ֹ=g'%zBE yV v#xx݅6aaіC޾聽h'_fYwWcꉉi3 3wِD/^mSA)cF4MD!Bl q&X"/*Ϲ|0jz+̾!~:vLL{9!kU`L*,M0 j5KcдpaHY>D@ tP7bG~8 fr&_8h}Zp ZB<""(FRgNyp+GRΫHYwW%|V%jiG+h k#в*\ԣOE!}ǤȟHi6U4Xe7B`ם9p.IoE4{AY8Du[Tţdy} םq[w39Sg؟ߠpmi+VJ);"5'4^\u'>}爐>WDeW`Ekapu4pK ԅOы. S pg$(ws;#)E B`aVtU5HR%XF1Aqܴ71! 5)P@dHRG:^DEpکn> +SR,ٛb!Uv:G!-;⇯eKW_\8I7o)8b4ZC}^Db_059V*V?9Q0zȽܷV_axGt&L a!b5Iu8(,W_;oR+#)eiY%vdyOKzߵ뷉>8 Z̀P(p))BTțU8X33^óL믚0MtS0p_:ml=E]ں# >drヨQa `#omlq4bX*5~N; #6%sX TOaGN@ksUAn՞QQ yσZ>e{[ljuaW\Ƀ>l=9^ΊgMGO0Or |u#dmdZjj$ -Yan oֶsW|7Lt=9LQ2Ffa]H00jF>d{A ;E˹H#(7:B+<~vj܈}Ǔ!Jp0@4׋Ed iD{i=O|eoxgc2Er(J׎B#|:ň}Dzh͠c sAd-BU/iluX( 0s}&v,֐V ~n`̘_  P ?מu׺J|@w_P!b] y ~JUH7L1v;}Qȑ2M \$ma ro|`}{8}uZR&G:{1>)L7^b[j@LosȗE|AJxe"kTʀ`j[ 3nh uuĝ,z$#2p璍 _d—d2b|ǖBKtL轵Oy]ҜDZap̅/@MInQ_ ?mCh^A|;]c${P k^Dz_ Z UgV5w |%%ͱm9N*t9I R鴵*s=a$,x+0ȋGCpXWYD5xn H)\wDA/isXyvU5"e3%Zd{2[t cHCZHd#f1k*t!fKפG\9V{&?YD@z%MMPՌM񾎝.ؼ$Fؠ)c:67;C9,{G4e3]"pG%s a&gZ i^ fZ,$jPY&v2f| =GEe#'.s{1u]p;k_"&Ch~RNYj $ bP1Ujqlo>O#ډ@5obi÷\jIv>co\l)+Â|03' 8'WO7 Gl.FHC=_Ev}`)V^&vB”tcTe6[e[7`R'ݺXO4xTc[K.PvQPG9x((3~ K@ϦR"4*}zN5d28E(oxE!* A 8#bYS3`igBoɄ)'_,CM%qGq2tkI1R4q2⭕}ˉN[U48CՃ&-y|C@wiՁ;N.Qc_ 屩d $68$^Bzs@!gn ^L<;N3AoӴ^aY"fg#t)C/ +xŢd/G`rz>KS(=^ Ԃ;Pnc=\i{mj'_zI|;c# ]ךyQ-M2O⍁wX/o+I+ ei kJlg_5N/Ea[D Z 8s4*A:Ob<ϒ}w&oQ,]ʛEjڬjv6u]ܿ]Olߒysy#:E$"&&Gf@ jxLXX` I)Id1SIf/aB-n#ɋVf=e;**t/sz|*3äN&[OֲI޺f5J\Q<9i*( ;E#"$'G۲^9ͯ3 Cl}Yve&Ϝ}T5rO_Ā7+/___X^4!Tw>^^$u yf$«`E{S [OBt΋ܖ 5d.Om?rǵ%5N!_^`^7a?JN {0뷫\{@IUo[[gś+n4+8W^EDO/$.G(E%wpKTj$GMC;f?~t'3OHK-|Hƀr5JGՏMHp-/ 5ŀ:~f ]UdnrY{5k2cI%sH7 ,ڽpR^}$-NT>GQ FVB܈[OihWPE12[":KyBĥ泯vfdEX,*U'B.?GɈD;gw%| GPҡcЗRin⺢ &gؼ V^H0ZzY\k!m5ZD$u'+B |qw>kp]6Ht1Ifw=mџ`rmE2jaJ4XQF9>=gd:慡p0ކoV5bFz"GVqz)+@p҆$<ۺ*wكzscϒ)e:aMXh'cz/ )wSqg UӒaԫE׼͵ޔ ZfLw[h%" )۱6֩@mڒ yjw\ҲE^(Q !ϛITMba$dΎGF!-?\6aȌ[l]U*ݗHl=Uמݻ&҅&IV"RMPu#0s!5p<״حË.*lՅ@*fH,semqs敇*{upEkǢ$s͜-Pa:buNn>BB}&#}Z}99,i㔔z_~]u_v5'$SI5cjnpRf}Y1-ȻL:K)Z=hzF$:T+ɚ8@1X{c_'NfBVEsw?@@0Yy^0ߤh\||T'bHJ`d#83Zl-v.Ls9#ė"a"Р"-x_eQKE5=$\>)Y~z?`{QK_ sl_%E@vKb*BߖHPK{PK9-5CPictures/image3.pngzeT\&.!]{-;HpwoKq͛wY3ګWs]U 'W00Hߑp0o```'vdD7Lۮ Z_e!!j3 (a=jqM m_8;!2QF$p ; Qv[kϗ;/γZZغ?_R,0NJ*=[J-eOeP6>.ESswo{'[{ãC q{Ԡ GvLƗWB&B/N IȎm~셴Њx^OhS(A˚_emCO~&Mκz b*48)708c1׍dm`#痎 q(PϤ =mp9u u&PC,0z>!8--}s=2fE< VB!ূv jƞBaX7'&5Ba_xuVHKO'%Zؼ)~ձ ޑ^Icѡ9H n}fS3Ghtju[3B+ ,?kl W~Dj+٣uQz`@*V,W֗$@^KQԙ,Re\o`jfӡEjCnl|TSL0*Ӭ/DZiя :~S+bɊLĭ Xf.;*3?~XNb%5D݆̉XBʛ6&4A5yষc%3̳Yh0Џ}ە<ͽg It2ƷLJ HxV Hk^p3-k4N<gf'EI˽[4|&&ÓKPҾ3!8-T|3!]:80B3sw"h1:2w(.˛%Lbs{yc'9fUllB0xGȶْB Fz`D GtZҭCTbryYf򸸰/Ԟ;0Xϻܸ_yXU^:8|BmȽޝ0?6(2;o X~᏶yd$qlhqph8'_BUgWI_xs=IB`Acd^*EuՓa -8Aޠ=a*ز7gN+h&Z'FIydSr~~v<L b|pZ'!`pvPq>-.^m#旀wei8ݔ AZzAW3 setj읧w61X?v-D*9 ǧuA\m v7$/To86;p'VeNvW%{I3ږqcMwuU'4SNY}`Y~op4MM1"sr!ʼnu mۺny;]&W5>ls,e$I O\Fc1/]UK Ԝ= 35BEA7MAǐ/ j~]L;بljm:yYsHZg ugȿS4u>Xs5f {Тwaϸ6:~iq7OY'B.iF!60%PL /FmRv y OG1ȷ$P*+rv\ZiZdgJ0dKgS "QUurF 8+o7X nm& M9R'VڭMZw?@lp%0vl  `G] ܯkA"H}3A\՟|wlo19aͱgMEݵE?DRF*^&3.&ŦY {&-, rh7DwۓSѳ"C~k6Ya"B7iӶuKN!ިCK5Lwg 2h.=J zeB42%w!_ڌ5D3 Bn0 ,k;?N, $Z+ADT1h^7e463B %̺%@BY>}9m5}/6_N{m:M-c %UHved(['&B ZfO?0wRC޶:Ejcާa G~ȁj6 ?>Np /j5焛ä L>$4@-KHc5V6K1 #')f^g!iahx"ֈzgfc H4/nV {c.(&X1rdA|`(3M/X(!QCDZ-ON{SRc* 4\Zo[# %MҪ ~Fn_%kvtye -D)k@ 洞&56% _G?U͂1EJ .H:KP(`JmcgIFZKKyнpr 迬d( q2.y9`%ₑE"M0La)Hd3]&Uđv="S j1?Txs!/D:氡ݿC7I!<6gZ2 A`c BmC _[0ȗ}ᩜϞ۰Z<ؽUi|xz8q;vWH8v.npwݬ-!jl8T>tSpdZ5!q>%iTshfǨ6BK(~w5FwI5k@O&ύh\b`tA}D^_mpy]+]4+??.O2_75@Ia"M`4=sAvET3|~~Y_;'Ξ|y_ڮ^NL=H=)/HViMyA<m=筢1]=_:d)՗_>:x(k٥0<4q2& G|hhQ#Q?i]be~j1S*}&{Lq (8yKR2^ `U݋<(9:[+jneEb/?!ڟhm)i% Z}-/ў<XJڢxZ^$St''nԺA9Ŷ4_s$Pv{71jùoe`H>!vG`ȾQ z|I(X% h7L#ED^ڝ"߿?UGzM,o(1Fe>ka D 8#bwB 5n[ C!Mo߉IЗ.߈A~#Dq0oa" _Fޛ7A$A^dcouQtS:V b"XJz_3E- 5A9Wju8*CZH`42m9ùWJwwgL=%-J{&ܑ2xNt')dڳii<$e lcA}fj1Uq[i*Ym CWjlko=wa zhkRT!%1 x\nk~mpkA8nK͝nỉ¥m0|QUYag> I32l8?qLr5Đ cP|QLQ@qN^N0v蠣/`i OTLjX%BK6g/FȈ j-n%˘B'-j"x>VYk 1+MG^e*1ZAqOAYa?1&+8GXmH1F"lS몏PrKUxYC3x|t78+KWb3ˆD6Mmpu- 7bnb䄄䅚Kرb؟욓:y<8-Vs8S l1sKb5[*o))074^U^ݰ*N=wt^eQ-x7R7tkn4 EZ@;hь CJaț1z|wue%$a ə€q\F\%66m}Ӫqi^k `z:#R =]ggUsDrj!e6<]zYe4Wm~_?smf2( 6 g^,<46hy;i{K!y^Rty6p#ԫYEy깦 [L.v?)gpZg7ڣ6 `dC(5W&ָQ͉XŤi'AgnQ'lbYVN*ZnRAxjoq,JC<C>Hﮃ.|& **$z![th! Bb:4mPV) tǓF0R)D(g+0p]lq㟸k}5n53uX)Vޭ.,͛->LsiNʹ MNK=jإ<$dBN3]o2&l& %-Iﴥx-x1#گT Xu8 p:IC&B}x3k&]ANZkX/j[Cl2EYLp bq &SGjBfd:`#f õŏ{ 78tPs͠lZlUmپzV`gЊhAOl%}˶7sѰIF2 29ZL߯:Q?nztl2w_Źx 22"jC!ߌo[Dⴍ),/&D_.8`8WNVR_쓳4cM$UMmjL2RxpXCr#f KPv!ОXG=.Y2vw1-$9N" 2WJ1w]!ɏ[x!Tŷbh e?ad3Nq*0';i8vna?21 ļʫ#M~@ 9 r+J%%W<#`RO#lOWXqj/i "Ր)"v ƝH*5{ՙ n{gnq嗸S1mYek-8$s=v+ruUG8Y.70vA/H{O$ΝH.| LetxM\ۋDd>3m"*`?:j*+8QLJY}9=)rz_](8̖*Y|h]]C 4_+'vEu/^f/_B*5'5HDCjk  &ˮRI_&Fk{ʕ:P45Q{Gyp! b' H6yϩXQk{%_#s? jHl ܣ#}wö27 2h2UJ'5q"C勃Tl@GK`.6V9ȥ-V&Փm%V4*dY=zjwQObY#2=\G:lʣahcݷ4lnհ7?ΠΥ-յ~OALebB / 7AY]wL+׌I -=v( ,^jڥhiډ/I >Y 𴈉٫FH/1ǫ1~}L4+;m]dDr;-neO6| MϠIc@~KӾ{Q{f3j?fIK~ b;HĖoXyע<-ʇVj#ɵoz0Y$Z6yB;EE &@ +fTM}9H5BNnk%X=Ճ h!ڰLdu nkv~?^(;TX0+'4qM1zr GlJt)dcnlIsc'>qɴ GN!~(`֦$Ӯ#*5? r:zRi?#yL4834,,/I!R,x\,hi&mHbSe,68h7?9iBuS8T"9eL߯02Y0Ν^) 7@ɾS'q#ahUZ R%U)ŵءqNۻ$lº Pcw>c|(VG Ml2>ui» 虡&n#M?漮zruMQt>蟗=J]Tݓa@WIޭcgae~( .FҦO&S<մ R8e^ U;t,2 #aZs =S@DIfoѹl&hLўI\7=bؓT?P-Ҁjƒu[N|V|̮-^3ۛ܌/+U"H[-|R]njÐ|#{#=xjv_Y1o+˻ +@vWU 0I5xy0 sVc\H(yQj+ۙeznə+7w&P6w/P&JR}ʸ >APu$@ڭG~<7F"~BӍdWʏOCg7"A%l֖V8/f9tB=_FW2hTC o q]e1С?}_,oBؐ{`/' Ih gCY!lܒjafc* o]ܯN.(G[S&JWB?ǭ=f!aφ'^uO] E4re ].۶ WI,--FѺ;xҽ,$_XfdƴـV΃ rI=?E\#=+hkԳc<˓Qb?Zl vO>a+|Sx,vR}.u!paܜ T+=0%I 2]s?Еfj.-+]J`]YK~MUx"3댪=E 6pl4œ]] rDhWd&xLng^[6|odA0?PKwd25PK9-5CPictures/image4.pngPNG  IHDRK8tvEIDATx]?v>N )89IEIG. KK&pp^U$˶mb{ %FHc|{F`rR{wn&NdF/#_n;#0E1F~n<#"2|xtp#>}Qa7ũ3WbRF+yV΍b7^{6ևEJbcyn[:٠3^7L|x7-KuHQJu=ġGk]e}/y=I*t6y~Xl2d6Xm>Y%5s4uj]Ӟѕ=-_NVOA${xսܤ-`J#աw&k3GC%/GG"}|hoЪe0!<55V_Cϒ)w7N.':KjXJ-^$Xf!k,\%r 8 8Wl,3};)7|in<>%Fx? lp[p%FQͼ0S|KL0v[NݏSOʺ1VjJ:Уܫ!l^P0pI;l?,TaE}}RX,:CI~HԃVg҇7?=dWq4FZcۺ|u:Be)*dVL p#1+y-ʋ9O&GԫK%9 of=ZIL8D8Švzx+Zsux.B_O'OXN=أ8c^S' Sbc29M;z#(4Q$}+"ߺՌsch'rfe(TDš'rttQ<&x麲G|2u`cmNUbܜh8F!\8W97cPC Mg DŰrZN_@5 ,UגUAJw<5("OE͔zLwӚ93|M>P'2#Q"nJF_.<~m>Ʃytb2eD0W`O4T`2l,rsF ('ycFF@6xp>6|56oҮe]y0B%_ #D PL>37EhZkˮ@Dvei,|.GKYUp[65#|ˢ:qB[Er\}ɿ~RE嘲 ULH=?XZd&B}Z)͋3+֞dbҼ}Y#oPDu4M ]E_d#⳧H+K"M8OH`LH_#u5n2Q/'3, [+ @n.Ł)H!YrТH Fm \dAqWBdU"(JIpUX "ZUE0v5tVO׹ ?K"=/"[;K%+ G1(nݒϑosTVSD$7 L8/ˍ uύ[.cbAG]t`zKuLm)cܼm=$]]ݣKjǥZqv1#[`c[{0" Jda#BS66}c]i&1oW7-Ke__֡FhbcHR$B3Gnpu/H +mlڲ[+QE=B^KFjC|jkϪI'~hWca0/7]R~;}A7.ƷKDIeW>SY*LVBI7To¿%%8. n!icfjoG&ٶm(9%7i9E`T:5XN`>%=C'le7I -Y/)0듀\&"dO" ed!لmUvXqh,֞aм ƫ<?580ߘ:hv VN!E"3,4pU+\;{f!Dkd}(m Vde}qZ 9^#H y24{Yx8EPڋuA:OF@=Xq!)Oܬ%y*eknl%HC 1';z25[S~Ǭ%Xeɖ'BmxMW}3#\wٮyAX_t4?> ߠ$e3e}i2d&H=X}-^El5x qsfvd};^tA+AIhPu%owd&<nV$ ^ SXx~+!2] @59uQ O&qsofvU[K|0_,딘*Csd,ɻ|T+C &=}D'M\1 Xxd4=vi  Bwp$nDB HO1`3jmNW8D@GX;bj8hJW&-蜶MxQGĄ(aI >6.˷ɽ(% n{xwO|~:~<&\?~=5kv.3MRacc*ΖC~b%''۷"ooLֵM?B!8a uѣrHtz.', VV,`{E\婭7hZ?#GC|eЂЪ#Ԍ;ԈRmr * bc$!I]2U4Q׮hY/LJK)pMqvv!xG~.[9Ϛf@<2fat9ىwɼb"Ayk7Q]0A{{˸ JeJl0unH"zvI-e^cYD1-X)U5;"4>Hg#@ i\,>lhl! DF) 0RՄT~3'  6୒d4-m.%*hvrL샅Z^UKPs83U^M!MM!&&޼:r,[eOe=Jop X+,c5u:ؗ3VEt UcpF:@ vD/Ae  cwgЄ'isheI20#_`-3Ѻ"[[2~~n$^>H=3_Q L}Rc1*Fo:"BO _4'W1S7YL'1_+~qq˔\tt,jh lm*/ yvsNye7r޸?헩 gT]3fܰY̱7`3vBrQ˗[_f?)7#ٻaf&41='3cy͒wZ$7B^#g1iSo3 Ra ,ɃJ"]4"_B̷\'CbiRg}/L>HGljM>ߚ޺Fŵ>&5B=1 [󭄞}}h? w'|^IdFf{rCxbë)5c(;E a$G7}Rs /4M7TOic47 iwqF/j&{olE;_D$4wgfy}F߲>i[7-xE,Q),}ggA l_%{%SaS׈w/ΕQ@1Ek&d`Q`ĎNLuVk=k52]gIP"%uF=JdUk&_/cug^%r[pwve̘kD;E`L* IkN2_ݐ mOn;sU]lW bb_&e6<\qK?1.cLI] -= /iGY<nb>t{Ʀr8C-;&>NžDy?ۼE${2d N@zb;[U2,[K;nrd JyB&jDW9Ւw-yh.ZM@]AHE$$:~sH)Cyu_^y 3EPP 1} .1ū'v ,تl d!0rt 4)m+PɭKZiGq9oW]I"E~c[.RF8:M$NtQn+n4~|gڸQ&w=t CX-q}L i4-HC{Ɛp:&/Gy^7#_ڵ'4,JذY~=t b &zXkracU3:=w-#^#e6WX^D;e\$]TsdχղY(Ce& !+$oۖڸR #'{0y*gO:MzUΚ$yL2` ˫Sv5yQI=O$' 5b3br Qے(E@ {D#҃BÙT3JXz )S.mpyfNn&V2ˋTH 7MRoGZH'P;N|"Ñ[)LI/#Sd8ؙN SRV 0o|&h"P߮ALSweoR+0ƀqbm0?r,J{]0VSЌZPbt;rW })Je8D@3Ո][U_$~Y%v;fRrN5A#ʁ֊b=1%"&߶a$8cV6'm%eES1hE Am%+pi(}#?E>)kFB,t[;n 2SÛgUm- ^ax^~hSBƑV@?oFoP R\l%JJk#1 ?A8ְ珌bV GAm"HzX61AD=W%Ӌs?=\'|{ OЮё=H%`gsKaYzp;1ߖke\8Y0ܶ(WdM9{[hX,/+-WP=5CUV"NYWY/]&/!@sP۳U޹8؈CHsjITN65}͸'E_^ڊ kc S3ԦEV"Y_+LJi{T14'>!L{]gj]p!d )Byxo.V54q7t GIp$i)֍FD-!㇁27Edu=V!N̞ : tw. Ť{eŲdІIJ;]9 uzI竖OOeLrOJLsai+ϥ 3zy$xdpA`Rlyf'Vͧ‘-jgŭΕ"@MtF@? F+Y-_ߏ,ܭ~PmZMԣcr\F9OI$4o;dR );TzVYRUepO{$?Tjg֋a>̆G v`qHR5’5:eU4Qn5ށciDX'p̳1 gYq7(rs|d,0tυ19>"l´.oCrRB;b8=&"78 p.$_ (O' |i`˅MνrB9S~R4E`Ӱ)NIi6_tMqβ\xx5N;M-`hMkzrNjNrL@d l؍=υwmPucRqIإTQƨsϦ X!𠺇lM|B9t! "o3c?oSR}>-~7\"۶sf_sОr ~mEx++ Z~7!N2%<≱uA#@J0&muWh#<ۗL}I5/~&po!o a?a}B}F? /ipN H?Bˊ2cƛGOݾFVfVv4 b}+/r"+XILoh->_5(;k) xx0ې8&)juЄ8;O]hhepH1 gHWx ?3}^y>(_1pg6P^O7q<tGG}Ѭ4Q <떲wsF 1d`b9)Nɀ)B{3/#SX8⣾$>b_˪}ww)êoŤpeVG~4&b L8$"yl!/gv\A]fDW5pϧI@ 77O ѭ]%J_ Chv‘rW~4^UjPKeXfPK9-5CPictures/image6.pngYPNG  IHDR Z@2 IDATx]Qoוs^I [I7`ǀ7ܴZ +CMg)4y %*p(A~@u"Udm *!k T#6s 9Es=ot=ܙ؃Z r #\8vF]; @m '1mEyA6PhCboy]y C2Uq݊۶LW5B4ZVa4.kզ b(9Kg=O$tl;G\qH`+nLJ- ?TR~9db2_y|˪ R-""ybfr+L!:XK^Ϣ!= &" NZ+ n۳S֞U_uCu%%0"W)YyWPCY剱1#ͫSd*S(,#;0.=\:väC?|I/gez<~0%G;v?rKg/S+P44s-ӭThe2-F.^tԫKM57Vpx$KA$Fp bF˯ܮ̿P"fww+kKl#ģѡ kf LCi 32 gV-/LGv2~c;lPGv|fο4Z΁VF.TvE .OW6<? 0!Ϯ+-믟SW(Cg 34~t FHf~LJ M8%gD9:82pNF e,fC6 A+=6]쪵Y /F?g?H掏{1vT~Lw=13/ɸ7fjZ(Dg tNy\tN\bVI^|j#^Al?FϦ0R 'N3m6m kz[B d'$5 ngwR_/X m-luȳs& /DumrC:Z\][QXPmKA)NON+GF>j[I ?0^~k9|2>RskHEʻV4Ae+<V|v ,kὫidՃ+nzr'SdUoXa^ޟo/K'_+JKuzy~+t+a`<jQ,_MW+? W=()\ X'Y:>u7>h,%+]q@k:Ul]drnKx)u>K1U) Cr܎Q˜eAhP.S3nJW8WgO:ǖ&( <׻_HruY+ Q4fDh}$P4 =b@hm8P{f ! nJf}# I A-df[>vQZhx Жh.J C /1mEiA b(%Ԃ@[" -(-DC@ E4ZhKPchP m|좴  1jA-Cі]! "^B-%j? A e(V,շG |͍;H'kׂ  @B-Y:Z1 EA`PG`/Wpw cw+7 xOU w*W/:**FTه38l olZ1oԞrC=Ox8Qox-|%k󶫳ٿ/>d)y7ׁϼ25yIbr>~c7wU ,Vub-գr (nxܺWpǻ"ֱ^Oci83c(W[ZMn? =>O%Wڕ~{c%Omy 2^}7۸NnZƇO7N7awae{hW/zd\gm|wm~b֩3fxb3WQk| Wk},-7q~ǗZWk(֮y ym\DZx|Ǯ0 |W~oR8t 2PVsg>^迂5ʼn șCoFu]P#~ <σ8xBQ>pe# +>3^YLgٯ9+ud~,Hdprv3GͰnР<5/>]!<(~Pq# 7A @B| ' x-q7kFn y 2vmVJ#61K\3/ךQ%?矺ETlG_B;x>q;n62T6UkW%WOp >oy EܼesZCqΞƋ_,ai]kk_?{f{qx=?=xǏaYBP }hEaĮ}< ?cnKcVxa+33xOs$0\c0Âa`*VGLNGEZOV*z i= -x2(&ty?( Ndd'6o 6d-+μ@Z&~pr>xFp{_@j:[P$`9 X&-+h7O{>|C س5y8W_ه1G 4=J> /~0 ? =,s:93ڕczw+vϭՑ0X>( Lm Dg!D7.yq )La}3VG*cT-c0cf ^4L=OM|E>xFI\ZbJΞ'#bFҳ*ٮ=E=xC^;O3*+(.s}Fkfxa^2n̮Q}Si#v`oK3q2 蝋XSazqYf5NN'LuhcT>o%:PB!"MTJzy# y˳A40g[ G> k¦nQ'1o:Ĭ[miI;@B*(O_p q T+O_pV[@IQp#Bq'kக (JҮ$|_5"ۍ)v$ ND@ N|*" PMbCc(KRV}in Uj m@mBD2łwlMRfc4f%0ҕc_SiĴrC Z I>(/dwy<ILf(SHf|H$l' p "ʦ`'<*䇂]|'`hZjR& zTc1 F.x!Nj)1duӇgː WtH,0,Pg+MrmN12A~" Џy,jKaG'\&/#g m-5i >y@vuy +փՏ=sd)9 LaH"\i>edxփC"㗖}jihlWUc]~|! P ˩, ;N<+AČ:I>T>c :4 =tpf~(%0`xy&љ1Bޓ}EaBnƗ{PND 9:mLL:&:VM*&*-FlޅڻP]rhWMz7+v 3iV4=< zufo$~C\=У,jQ|Bȳ9&Z/>aJQEzA`'"PPhq2Cgӆj{,!c0de:Xt E/n:+g']5RrNjW~ #(B*<:Q1a0JhY0CzS{mn9 xUjB!>p:.Aa4ףhHf-} -}p" L* Z[}Bib`dܥeumDzev@s4v+#j4ô>\Mh")zU4G6qDQ ڤf* *ױQBywon5Me6kmw[roFDi+l#>(mt?Q6jɮv`o5w (Dqm*I4jxf7%"V@ PӪޝ*:,5lR/SiC,7tch2=*]Sb(C1WP;TݫV@ PWq6߅7Ao!l7"mlS&"Z*l8ZlN&?QLEgcjBHpM8?A ꆂFisޥ>x+SrpNڛRp6&RYժrcښ)wM yj2U\2CF7qy|^G략 mPCIb(Uec-%+ٚitUf%"4^7ٸ F״7ޢ вzz" 4z4݋"IqIENDB`PKE^YPK9-5CPictures/image7.pngmyuXT_0"H* ))-0CCHPCttww3<9g~9kj*rX/[yi (pmphJKjydBhf{cŏ<徐Ul2Ga/b!` HHwlkgMZ .Xb. Iɗթ6Of A& }_Rۏ6hii=/ F[&Dv\w)z0ok{_'4=(xi Yր=}-r6!+S2JB@jQDXİ{R1vz0C۝a-ZO#xl$$@5~a2W/؇^g_cJPG-ZmĨff%Xaϒh1J*g^TN/#bZ_&*`+cyK-͍Ӧjr^l$"> aj8Tj v&d#lMJD8/Վ÷^f׾nݗa⽯L,3.s~UQbW4 ZB>|wN*Iz箧buog 3YnBR2QSv>A݉Rj+鿼[kА>/jLf#JTMg77:|9PwCƛ|)Z`x:f0[r4UɫT(WP5ti`_%D:yxH3} A{@#n]qI>5×àRiC]i$XvOݯa29푐cͮ>'2PFwb*KXY־+3} y0 n~Z< k6etᜟ^H| %/DK<z&(ܸ}"·&FV(*۩~*+t {P7ѩ AknbyO,G'`X9^=a:(M8~ F0@dx^Ha/w\LF=NGsLYsnU~Ep=E>EKUAYo$ML@t/Puf۶hconC$Q݄'ڜ)6 ~Yl5p^ƩCkp9*]|3C]ݥxG ı:wr$9fyMG7h@Oʇw%p9jrζxzq5nLbh5+>[F OOIEyHQRȀ fc45,봗*^>8Zcs{T`<=hP=|qfW?y4HU &eX/dE-f _C$?ý{&⌝M!;)_Ea~G#g(*Ii!!-p>8´ !G+AyB@#hLhU\- ] tl ; A*"@-/Q=<_w nmH_f*U(w.oYMFZ(j1w',ߘ5^F^;[X߁A(A9}]ڴh?L ?mq^{ 7 ̗7^XM1ƻ5ρ*%_R[ɐߋlnh/t75 ڕ\*`n)֘U:6#uy[jvswMR7T9&mVf7ז, 3_~p)ڠ{_jv:0 5k=g6jqI}wt[RHQ<[Ч-gFU{ތ '+biqD"phx7٩wpS}R)풧;K\Ŵ 2z0MNm#\؄R%)s6:Y7BlP}`x\5G!36%Med!^q>eؙR\Zf}iٛ7qTYk#ބs(; h}$m.#-R =G ŏ-:hs2bM=U™.+Gw :Sg9ȕRI:ʛ-qM f<*f/T[c&>_%S"r6 G>"&;N]WG˽E+Nm L0f% B̿R_9ȟZ6x-ɐGfdo"p@r ~YLS &TvSƳ&IwǸḚ0zfd6o(n(Ԣf=u;E ^>P6?IoI^2aՉ疑ܺ@Yg11PYGO[\-fKzιaʟkv sr|V7;_mSJ7 h[:\4$:-Gk ~r9,zqz7;LF(-@z_mAbse{$RfbVDW,^O+U%jT%;Cl U *2 ʙxNTvi L<) ?TMd`E'yqY-mt4^NÝPWo^Lޗʉ L"+_ww{ǭ'D!RhY0#z RKV5b݄2D6;)\{֍W곞ys0#,ض3O _A{ƥJ7|cSF3!iЍ{ս\ӪdiDHH6 M’t˃>j}k69vQ/cyuDkgsr5#QO5gpr]9s~%bq AZ&:m~q`~RN ~<"P2-XyHrԖjPrН?l*l}\-$uT"hx<* Poe^Qg^N ma,:m cHwQX?س>?.|2=W A3ͦVopqPhMdS\ݖ;]m]Y|wGfiyK-,}SGJL>XJYsG2$lUFaA4gF$o.>)yBy}>ӓ?R~+v:CbVKO]|ͥ>yV0:<|dkQʢ94GG2CoYIu>xBGqrV/Dz-~-֩C*5oM/rΛ#T\L7Gj1uU $-O)myC_%ݵ֩`z<&]GkɨmVvv`+} DE(m׬vÀ`u+ѿ3Rw# ?o #wQzB BP%w (*! /(Ja4z,Y3Ցlə(G+1 I^ ~9#d' T!Vdab<@>`50IHu|q\#XC0m A7XMe1 ֥+EȄzj#XDXWsXhb?\:3V %i[Տ̓T9]+ 9 [C%ȁe:m X&UOxR&yt4KtөWlUXDDn"΋4XsCD'UxvvT%ո08BPCi6;:'ûDHFeΆkPhJnĪ y"}gjm R#a_CNn-C9 "r1d,7Q7v]^e Ѭw3X`xcSg%:ZF 0|}f:mu CTwEG"x7m <,+*y LR%S|3ܿ]^'JIvNtf{Y^PVч_=so5S5(jޛL6u[:~9W GZj2j]K٘׌쉌ū{M-Oƣ1X'+2bUSZxd4k4!+I v$wV jݪ]Y%|,EDڽo_ک{^āmJ>}0K5.ƲN+LnO|:idk z^,{ՔѽPB \͟= )V*hCUX+wfoOn(?"{}ZL ^Ur*7 f8 3+waqV6< X۝?12a͔5&u+5WrjJ׎LbˋZ#JXs^A"'4hr%=35NU&Uun'bä  ljme4kxwI(%J@uGz@J`KhZ">?Ou>>|>[^G-B&]yKb焧\u0PbtM$K,U'AA聁XG[Dl[c;WEga0>[uZ@ԇ!gB63/ڡ̀ogrd+"xϭλ xUokDW+ge5T,kWFԾѩJ-N?t:BuC5s}m)8[i!vI<|iBJ}v#knDTMG[7=d in@&C2;>!k]O[#YY8QJV͋m '__cuca6c A_Pe-턵1 9l?7=m>"9t&.m C*t;9?8l e= Q TzI3B|֏4@sAPN۵ 2f*Ʝy5\P#7sBzWcVSCr EJx߻Hj;nɖ؂獓B!~. \Z&xIO˕ޗ}-$IzGsu@/+5\ˊ6L8:eyNxpRjÌi0rxRmhݗǨEd}tw #eb% wm ~t}[5NӸ"ǟp"3$'M:ꦏ_2 nf]!11H/0S>*4  Gul1FN϶A'MMɳs)?Ɖ+Jf栙e;kz'Q=#tjRɨ$NioA.آ"QךHZβ 3fv_4ΤBѱ[=gR.I| E&tbfwUtk~ ~6/"l#?pSMu&P~L4wHyUH.S8CH]Z|~V1t>Z克Sœăva-R6>OG$ʰN l-  ,̕˒֒4y?IHY'봗UQxxMZ3sqDO5f='wæ)rƮOw=#jG'?wevH~RͳBk'ž b՝}$)UBL#a}c6h5uF rԣaD]T{CD >kptC=ڤsî1TV-I칆kl"pp坫ޔV.#5i)8K< {Eظ=|WJ eY9pYp)r'/}П!.l.kI"ƽԇTd'T'~@}3Ht͓j;]=0E#Zn߰In~LnQ(˧"FΆED#RV{(k[n2&$Bw@gՉئ\7XWu4P~Dnґ飒8m唷8a>X'fZɶ!/VI? .Ѓ6l"B)-n`ۺ'[>K3qqm쿍ϰx`~!5 בJW=pQ.{cPK(\PK 9-5C^2 ''mimetypePK9-5C>|SǓx Mcontent.xmlPK9-5C TMMETA-INF/manifest.xmlPK9-5COmeta.xmlPK9-5CePM5q settings.xmlPK9-5Cø^:! {styles.xmlPK9-5CfR3Pictures/image1.pngPK9-5C{ƾPictures/image2.pngPK9-5Cwd25 Pictures/image3.pngPK9-5Ce Pictures/image4.pngPK9-5CeXfPictures/image5.pngPK9-5CE^Y=2Pictures/image6.pngPK9-5C(\GPictures/image7.pngPK !flz4-0.0~r114/Makefile000066400000000000000000000112051231007221700143220ustar00rootroot00000000000000# ################################################################ # LZ4 library - Makefile # Copyright (C) Yann Collet 2011-2014 # All rights reserved. # # BSD license # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above copyright notice, this # list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # You can contact the author at : # - LZ4 source repository : http://code.google.com/p/lz4/ # - LZ4 forum froup : https://groups.google.com/forum/#!forum/lz4c # ################################################################ export RELEASE=r114 LIBVER_MAJOR=1 LIBVER_MINOR=0 LIBVER_PATCH=0 LIBVER=$(LIBVER_MAJOR).$(LIBVER_MINOR).$(LIBVER_PATCH) DESTDIR= PREFIX=/usr CC:=$(CC) CFLAGS+= -I. -std=c99 -O3 -Wall -W -Wundef -DLZ4_VERSION=\"$(RELEASE)\" LIBDIR=$(PREFIX)/lib INCLUDEDIR=$(PREFIX)/include PRGDIR=programs DISTRIBNAME=lz4-$(RELEASE).tar.gz # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) EXT =.exe else EXT = endif TEXT = lz4.c lz4.h lz4hc.c lz4hc.h \ lz4_format_description.txt Makefile NEWS LICENSE \ cmake_unofficial/CMakeLists.txt \ $(PRGDIR)/fullbench.c $(PRGDIR)/fuzzer.c $(PRGDIR)/lz4cli.c \ $(PRGDIR)/lz4io.c $(PRGDIR)/lz4io.h \ $(PRGDIR)/bench.c $(PRGDIR)/bench.h \ $(PRGDIR)/xxhash.c $(PRGDIR)/xxhash.h \ $(PRGDIR)/lz4.1 $(PRGDIR)/Makefile $(PRGDIR)/COPYING NONTEXT = LZ4_Streaming_Format.odt SOURCES = $(TEXT) $(NONTEXT) default: liblz4 @cd $(PRGDIR); $(MAKE) -e all: liblz4 lz4programs liblz4: liblz4.a liblz4.so lz4programs: lz4.c lz4hc.c @cd $(PRGDIR); $(MAKE) -e all liblz4.a: lz4.c lz4hc.c $(CC) $(CFLAGS) -c $^ ar rcs liblz4.a lz4.o lz4hc.o liblz4.so: lz4.c lz4hc.c $(CC) $(CFLAGS) -shared $^ -fPIC -Wl,-soname=liblz4.so.$(LIBVER_MAJOR) -o $@.$(LIBVER) @ln -s $@.$(LIBVER) $@.$(LIBVER_MAJOR) @ln -s $@.$(LIBVER) $@ clean: @rm -f core *.o *.a *.so *.so.* $(DISTRIBNAME) @cd $(PRGDIR); make clean @echo Cleaning completed #make install option is reserved to Linux & OSX targets ifneq (,$(filter $(shell uname),Linux Darwin)) install: liblz4 @install -d -m 755 $(DESTDIR)$(LIBDIR)/ $(DESTDIR)$(INCLUDEDIR)/ @install -m 755 liblz4.a $(DESTDIR)$(LIBDIR)/liblz4.a @install -m 755 liblz4.so.$(LIBVER) $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER) @install -m 755 liblz4.so.$(LIBVER_MAJOR) $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER_MAJOR) @install -m 755 liblz4.so $(DESTDIR)$(LIBDIR)/liblz4.so @install -m 755 lz4.h $(DESTDIR)$(INCLUDEDIR)/lz4.h @install -m 755 lz4hc.h $(DESTDIR)$(INCLUDEDIR)/lz4hc.h @echo lz4 static and shared library installed @cd $(PRGDIR); make install uninstall: [ -x $(DESTDIR)$(LIBDIR)/liblz4.a ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.a [ -x $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER) ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER) [ -x $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER_MAJOR) ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.so.$(LIBVER_MAJOR) [ -x $(DESTDIR)$(LIBDIR)/liblz4.so ] && rm -f $(DESTDIR)$(LIBDIR)/liblz4.so [ -f $(DESTDIR)$(INCLUDEDIR)/lz4.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/lz4.h [ -f $(DESTDIR)$(INCLUDEDIR)/lz4hc.h ] && rm -f $(DESTDIR)$(INCLUDEDIR)/lz4hc.h @echo lz4 libraries successfully uninstalled @cd $(PRGDIR); make uninstall dist: clean @install -dD -m 700 lz4-$(RELEASE)/programs/ @install -dD -m 700 lz4-$(RELEASE)/cmake_unofficial/ @for f in $(TEXT); do \ tr -d '\r' < $$f > .tmp; \ install -m 600 .tmp lz4-$(RELEASE)/$$f; \ done @rm .tmp @for f in $(NONTEXT); do \ install -m 600 $$f lz4-$(RELEASE)/$$f; \ done @tar -czf $(DISTRIBNAME) lz4-$(RELEASE)/ @rm -rf lz4-$(RELEASE) @echo Distribution $(DISTRIBNAME) built endif lz4-0.0~r114/NEWS000066400000000000000000000050511231007221700133630ustar00rootroot00000000000000r114: Makefile : library correctly compiled with -O3 switch (issue 114) Makefile : library compilation compatible with clang Makefile : library is versioned and linked (issue 119) lz4.h : no more static inline prototypes (issue 116) man : improved header/footer (issue 111) Makefile : Use system default $(CC) & $(MAKE) variables (issue 112) xxhash : updated to r34 r113: Large decompression speed improvement for GCC 32-bits. Thanks to Valery Croizier ! LZ4HC : Compression Level is now a programmable parameter (CLI from 4 to 9) Separated IO routines from command line (lz4io.c) Version number into lz4.h (suggested by Francesc Alted) r112: quickfix r111 : Makefile : added capability to install libraries Modified Directory tree, to better separate libraries from programs. r110 : lz4 & lz4hc : added capability to allocate state & stream state with custom allocator (issue 99) fuzzer & fullbench : updated to test new functions man : documented -l command (Legacy format, for Linux kernel compression) (issue 102) cmake : improved version by Mika Attila, building programs and libraries (issue 100) xxHash : updated to r33 Makefile : clean also delete local package .tar.gz r109 : lz4.c : corrected issue 98 (LZ4_compress_limitedOutput()) Makefile : can specify version number from makefile r108 : lz4.c : corrected compression efficiency issue 97 in 64-bits chained mode (-BD) for streams > 4 GB (thanks Roman Strashkin for reporting) r107 : Makefile : support DESTDIR for staged installs. Thanks Jorge Aparicio. Makefile : make install installs both lz4 and lz4c (Jorge Aparicio) Makefile : removed -Wno-implicit-declaration compilation switch lz4cli.c : include for isatty() (Luca Barbato) lz4.h : introduced LZ4_MAX_INPUT_SIZE constant (Shay Green) lz4.h : LZ4_compressBound() : unified macro and inline definitions (Shay Green) lz4.h : LZ4_decompressSafe_partial() : clarify comments (Shay Green) lz4.c : LZ4_compress() verify input size condition (Shay Green) bench.c : corrected a bug in free memory size evaluation cmake : install into bin/ directory (Richard Yao) cmake : check for just C compiler (Elan Ruusamae) r106 : Makefile : make dist modify text files in the package to respect Unix EoL convention lz4cli.c : corrected small display bug in HC mode r105 : Makefile : New install script and man page, contributed by Prasad Pandit lz4cli.c : Minor modifications, for easier extensibility COPYING : added license file LZ4_Streaming_Format.odt : modified file name to remove white space characters Makefile : .exe suffix now properly added only for Windows target lz4-0.0~r114/cmake_unofficial/000077500000000000000000000000001231007221700161425ustar00rootroot00000000000000lz4-0.0~r114/cmake_unofficial/CMakeLists.txt000066400000000000000000000044571231007221700207140ustar00rootroot00000000000000PROJECT(LZ4 C) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "LZ4 compression library") set(CPACK_PACKAGE_VERSION_MAJOR 0) set(CPACK_PACKAGE_VERSION_MINOR 0) set(CPACK_PACKAGE_VERSION_PATCH r111) #set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/COPYING_LGPL) set(VERSION_STRING " \"${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}\" ") include(CPack) cmake_minimum_required (VERSION 2.6) INCLUDE (CheckTypeSize) check_type_size("void *" SIZEOF_VOID_P) IF( ${SIZEOF_VOID_P} STREQUAL "8" ) set (CMAKE_SYSTEM_PROCESSOR "64bit") MESSAGE( STATUS "64 bit architecture detected size of void * is " ${SIZEOF_VOID_P}) ENDIF() option(BUILD_TOOLS "Build the command line tools" ON) option(BUILD_LIBS "Build the libraries in addition to the tools" OFF) if(UNIX AND BUILD_LIBS) if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") add_definitions(-fPIC) endif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") endif() set(LZ4_DIR ../) set(PRG_DIR ../programs/) set(LZ4_SRCS_LIB ${LZ4_DIR}lz4.c ${LZ4_DIR}lz4hc.c ${LZ4_DIR}lz4.h ${LZ4_DIR}lz4hc.h) set(LZ4_SRCS ${PRG_DIR}xxhash.c ${PRG_DIR}bench.c ${PRG_DIR}lz4cli.c ${PRG_DIR}lz4io.c) if(BUILD_TOOLS AND NOT BUILD_LIBS) set(LZ4_SRCS ${LZ4_SRCS} ${LZ4_SRCS_LIB}) endif() if(BUILD_TOOLS) add_executable(lz4 ${LZ4_SRCS}) set_target_properties(lz4 PROPERTIES COMPILE_DEFINITIONS DISABLE_LZ4C_LEGACY_OPTIONS) install(TARGETS lz4 RUNTIME DESTINATION "bin/") add_executable(lz4c ${LZ4_SRCS}) install(TARGETS lz4c RUNTIME DESTINATION "bin/") endif() if(BUILD_LIBS) add_library(liblz4 ${LZ4_SRCS_LIB}) set_target_properties(liblz4 PROPERTIES OUTPUT_NAME lz4 SOVERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}" ) install(TARGETS liblz4 LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) install(FILES ${LZ4_DIR}/lz4.h ${LZ4_DIR}/lz4hc.h DESTINATION include ) if(BUILD_TOOLS) target_link_libraries(lz4 liblz4) target_link_libraries(lz4c liblz4) endif() endif() #warnings ADD_DEFINITIONS("-Wall") ADD_DEFINITIONS("-W") ADD_DEFINITIONS("-Wundef") ADD_DEFINITIONS("-Wcast-align") ADD_DEFINITIONS("-std=c99") ADD_DEFINITIONS("-DLZ4_VERSION=\"${CPACK_PACKAGE_VERSION_PATCH}\"") INCLUDE_DIRECTORIES (${LZ4_DIR}) lz4-0.0~r114/lz4.c000066400000000000000000000765671231007221700135650ustar00rootroot00000000000000/* LZ4 - Fast LZ compression algorithm Copyright (C) 2011-2014, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4/ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /************************************** Tuning parameters **************************************/ /* * MEMORY_USAGE : * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) * Increasing memory usage improves compression ratio * Reduced memory usage can improve speed, due to cache effect * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */ #define MEMORY_USAGE 14 /* * HEAPMODE : * Select how default compression functions will allocate memory for their hash table, * in memory stack (0:default, fastest), or in memory heap (1:requires memory allocation (malloc)). */ #define HEAPMODE 0 /************************************** CPU Feature Detection **************************************/ /* 32 or 64 bits ? */ #if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \ || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) /* Detects 64 bits mode */ # define LZ4_ARCH64 1 #else # define LZ4_ARCH64 0 #endif /* * Little Endian or Big Endian ? * Overwrite the #define below if you know your architecture endianess */ #if defined (__GLIBC__) # include # if (__BYTE_ORDER == __BIG_ENDIAN) # define LZ4_BIG_ENDIAN 1 # endif #elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) # define LZ4_BIG_ENDIAN 1 #elif defined(__sparc) || defined(__sparc__) \ || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ || defined(__hpux) || defined(__hppa) \ || defined(_MIPSEB) || defined(__s390__) # define LZ4_BIG_ENDIAN 1 #else /* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */ #endif /* * Unaligned memory access is automatically enabled for "common" CPU, such as x86. * For others CPU, such as ARM, the compiler may be more cautious, inserting unnecessary extra code to ensure aligned access property * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance */ #if defined(__ARM_FEATURE_UNALIGNED) # define LZ4_FORCE_UNALIGNED_ACCESS 1 #endif /* Define this parameter if your target system or compiler does not support hardware bit count */ #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ # define LZ4_FORCE_SW_BITCOUNT #endif /* * BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE : * This option may provide a small boost to performance for some big endian cpu, although probably modest. * You may set this option to 1 if data will remain within closed environment. * This option is useless on Little_Endian CPU (such as x86) */ /* #define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1 */ /************************************** Compiler Options **************************************/ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ /* "restrict" is a known keyword */ #else # define restrict /* Disable restrict */ #endif #ifdef _MSC_VER /* Visual Studio */ # define FORCE_INLINE static __forceinline # include /* For Visual 2005 */ # if LZ4_ARCH64 /* 64-bits */ # pragma intrinsic(_BitScanForward64) /* For Visual 2005 */ # pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */ # else /* 32-bits */ # pragma intrinsic(_BitScanForward) /* For Visual 2005 */ # pragma intrinsic(_BitScanReverse) /* For Visual 2005 */ # endif # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ #else # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif #endif #ifdef _MSC_VER /* Visual Studio */ # define lz4_bswap16(x) _byteswap_ushort(x) #else # define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) #endif #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) # define expect(expr,value) (__builtin_expect ((expr),(value)) ) #else # define expect(expr,value) (expr) #endif #define likely(expr) expect((expr) != 0, 1) #define unlikely(expr) expect((expr) != 0, 0) /************************************** Memory routines **************************************/ #include /* malloc, calloc, free */ #define ALLOCATOR(n,s) calloc(n,s) #define FREEMEM free #include /* memset, memcpy */ #define MEM_INIT memset /************************************** Includes **************************************/ #include "lz4.h" /************************************** Basic Types **************************************/ #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif #if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) # define _PACKED __attribute__ ((packed)) #else # define _PACKED #endif #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) # if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) # pragma pack(1) # else # pragma pack(push, 1) # endif #endif typedef struct { U16 v; } _PACKED U16_S; typedef struct { U32 v; } _PACKED U32_S; typedef struct { U64 v; } _PACKED U64_S; typedef struct {size_t v;} _PACKED size_t_S; #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) # if defined(__SUNPRO_C) || defined(__SUNPRO_CC) # pragma pack(0) # else # pragma pack(pop) # endif #endif #define A16(x) (((U16_S *)(x))->v) #define A32(x) (((U32_S *)(x))->v) #define A64(x) (((U64_S *)(x))->v) #define AARCH(x) (((size_t_S *)(x))->v) /************************************** Constants **************************************/ #define LZ4_HASHLOG (MEMORY_USAGE-2) #define HASHTABLESIZE (1 << MEMORY_USAGE) #define HASHNBCELLS4 (1 << LZ4_HASHLOG) #define MINMATCH 4 #define COPYLENGTH 8 #define LASTLITERALS 5 #define MFLIMIT (COPYLENGTH+MINMATCH) static const int LZ4_minLength = (MFLIMIT+1); #define KB *(1U<<10) #define MB *(1U<<20) #define GB *(1U<<30) #define LZ4_64KLIMIT ((64 KB) + (MFLIMIT-1)) #define SKIPSTRENGTH 6 /* Increasing this value will make the compression run slower on incompressible data */ #define MAXD_LOG 16 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1) #define ML_BITS 4 #define ML_MASK ((1U<=e; */ #else # define LZ4_WILDCOPY(d,s,e) { if (likely(e-d <= 8)) LZ4_COPY8(d,s) else do { LZ4_COPY8(d,s) } while (d>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll(val) >> 3); # else int r; if (!(val>>32)) { r=4; } else { r=0; val>>=32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; # endif # else # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanForward64( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll(val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; # endif # endif } #else FORCE_INLINE int LZ4_NbCommonBytes (register U32 val) { # if defined(LZ4_BIG_ENDIAN) # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz(val) >> 3); # else int r; if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } r += (!val); return r; # endif # else # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz(val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif # endif } #endif /**************************** Compression functions ****************************/ int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } FORCE_INLINE int LZ4_hashSequence(U32 sequence, tableType_t tableType) { if (tableType == byU16) return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); else return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); } FORCE_INLINE int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(A32(p), tableType); } FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { switch (tableType) { case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; hashTable[h] = p; break; } case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); break; } case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); break; } } } FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); } FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) { if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ } FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) { U32 h = LZ4_hashPosition(p, tableType); return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); } FORCE_INLINE int LZ4_compress_generic( void* ctx, const char* source, char* dest, int inputSize, int maxOutputSize, limitedOutput_directive limitedOutput, tableType_t tableType, prefix64k_directive prefix) { const BYTE* ip = (const BYTE*) source; const BYTE* const base = (prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->base : (const BYTE*) source; const BYTE* const lowLimit = ((prefix==withPrefix) ? ((LZ4_Data_Structure*)ctx)->bufferStart : (const BYTE*)source); const BYTE* anchor = (const BYTE*) source; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = iend - LASTLITERALS; BYTE* op = (BYTE*) dest; BYTE* const oend = op + maxOutputSize; int length; const int skipStrength = SKIPSTRENGTH; U32 forwardH; /* Init conditions */ if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ if ((prefix==withPrefix) && (ip != ((LZ4_Data_Structure*)ctx)->nextBlock)) return 0; /* must continue from end of previous block */ if (prefix==withPrefix) ((LZ4_Data_Structure*)ctx)->nextBlock=iend; /* do it now, due to potential early exit */ if ((tableType == byU16) && (inputSize>=(int)LZ4_64KLIMIT)) return 0; /* Size too large (not within 64K limit) */ if (inputSize> skipStrength; ip = forwardIp; forwardIp = ip + step; if (unlikely(forwardIp > mflimit)) { goto _last_literals; } forwardH = LZ4_hashPosition(forwardIp, tableType); ref = LZ4_getPositionOnHash(h, ctx, tableType, base); LZ4_putPositionOnHash(ip, h, ctx, tableType, base); } while ((ref + MAX_DISTANCE < ip) || (A32(ref) != A32(ip))); /* Catch up */ while ((ip>anchor) && (ref > lowLimit) && (unlikely(ip[-1]==ref[-1]))) { ip--; ref--; } /* Encode Literal length */ length = (int)(ip - anchor); token = op++; if ((limitedOutput) && (unlikely(op + length + (2 + 1 + LASTLITERALS) + (length/255) > oend))) return 0; /* Check output limit */ if (length>=(int)RUN_MASK) { int len = length-RUN_MASK; *token=(RUN_MASK<= 255 ; len-=255) *op++ = 255; *op++ = (BYTE)len; } else *token = (BYTE)(length<>8) > oend))) return 0; /* Check output limit */ if (length>=(int)ML_MASK) { *token += ML_MASK; length -= ML_MASK; for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; } if (length >= 255) { length-=255; *op++ = 255; } *op++ = (BYTE)length; } else *token += (BYTE)(length); /* Test end of chunk */ if (ip > mflimit) { anchor = ip; break; } /* Fill table */ LZ4_putPosition(ip-2, ctx, tableType, base); /* Test next position */ ref = LZ4_getPosition(ip, ctx, tableType, base); LZ4_putPosition(ip, ctx, tableType, base); if ((ref + MAX_DISTANCE >= ip) && (A32(ref) == A32(ip))) { token = op++; *token=0; goto _next_match; } /* Prepare next loop */ anchor = ip++; forwardH = LZ4_hashPosition(ip, tableType); } _last_literals: /* Encode Last Literals */ { int lastRun = (int)(iend - anchor); if ((limitedOutput) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } else *op++ = (BYTE)(lastRun<hashTable, 0, sizeof(lz4ds->hashTable)); lz4ds->bufferStart = base; lz4ds->base = base; lz4ds->nextBlock = base; } int LZ4_resetStreamState(void* state, const char* inputBuffer) { if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ LZ4_init((LZ4_Data_Structure*)state, (const BYTE*)inputBuffer); return 0; } void* LZ4_create (const char* inputBuffer) { void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure)); LZ4_init ((LZ4_Data_Structure*)lz4ds, (const BYTE*)inputBuffer); return lz4ds; } int LZ4_free (void* LZ4_Data) { FREEMEM(LZ4_Data); return (0); } char* LZ4_slideInputBuffer (void* LZ4_Data) { LZ4_Data_Structure* lz4ds = (LZ4_Data_Structure*)LZ4_Data; size_t delta = lz4ds->nextBlock - (lz4ds->bufferStart + 64 KB); if ( (lz4ds->base - delta > lz4ds->base) /* underflow control */ || ((size_t)(lz4ds->nextBlock - lz4ds->base) > 0xE0000000) ) /* close to 32-bits limit */ { size_t deltaLimit = (lz4ds->nextBlock - 64 KB) - lz4ds->base; int nH; for (nH=0; nH < HASHNBCELLS4; nH++) { if ((size_t)(lz4ds->hashTable[nH]) < deltaLimit) lz4ds->hashTable[nH] = 0; else lz4ds->hashTable[nH] -= (U32)deltaLimit; } memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); lz4ds->base = lz4ds->bufferStart; lz4ds->nextBlock = lz4ds->base + 64 KB; } else { memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 64 KB), 64 KB); lz4ds->nextBlock -= delta; lz4ds->base -= delta; } return (char*)(lz4ds->nextBlock); } int LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize) { return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, 0, notLimited, byU32, withPrefix); } int LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, maxOutputSize, limited, byU32, withPrefix); } /**************************** Decompression functions ****************************/ /* * This generic decompression function cover all use cases. * It shall be instanciated several times, using different sets of directives * Note that it is essential this generic function is really inlined, * in order to remove useless branches during compilation optimisation. */ FORCE_INLINE int LZ4_decompress_generic( const char* source, char* dest, int inputSize, int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ int endOnInput, /* endOnOutputSize, endOnInputSize */ int prefix64k, /* noPrefix, withPrefix */ int partialDecoding, /* full, partial */ int targetOutputSize /* only used if partialDecoding==partial */ ) { /* Local Variables */ const BYTE* restrict ip = (const BYTE*) source; const BYTE* ref; const BYTE* const iend = ip + inputSize; BYTE* op = (BYTE*) dest; BYTE* const oend = op + outputSize; BYTE* cpy; BYTE* oexit = op + targetOutputSize; /*const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; / static reduces speed for LZ4_decompress_safe() on GCC64 */ const size_t dec32table[] = {4-0, 4-3, 4-2, 4-3, 4-0, 4-0, 4-0, 4-0}; /* static reduces speed for LZ4_decompress_safe() on GCC64 */ static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; /* Special cases */ if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */ if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */ if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1); /* Main Loop */ while (1) { unsigned token; size_t length; /* get runlength */ token = *ip++; if ((length=(token>>ML_BITS)) == RUN_MASK) { unsigned s=255; while (((endOnInput)?ip(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) || ((!endOnInput) && (cpy>oend-COPYLENGTH))) { if (partialDecoding) { if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ } else { if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ } memcpy(op, ip, length); ip += length; op += length; break; /* Necessarily EOF, due to parsing restrictions */ } LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy; /* get offset */ LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2; if ((prefix64k==noPrefix) && (unlikely(ref < (BYTE* const)dest))) goto _output_error; /* Error : offset outside destination buffer */ /* get matchlength */ if ((length=(token&ML_MASK)) == ML_MASK) { while ((!endOnInput) || (ipoend-COPYLENGTH-(STEPSIZE-4))) { if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last 5 bytes must be literals */ LZ4_SECURECOPY(op, ref, (oend-COPYLENGTH)); while(op (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) /* LZ4_compressBound() : Provides the maximum size that LZ4 may output in a "worst case" scenario (input data not compressible) primarily useful for memory allocation of output buffer. inline function is recommended for the general case, macro is also provided when result needs to be evaluated at compilation (such as stack memory allocation). isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ int LZ4_compressBound(int isize); /* LZ4_compress_limitedOutput() : Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. If it cannot achieve it, compression will stop, and result of the function will be zero. This function never writes outside of provided output buffer. inputSize : Max supported value is LZ4_MAX_INPUT_VALUE maxOutputSize : is the size of the destination buffer (which must be already allocated) return : the number of bytes written in buffer 'dest' or 0 if the compression fails */ int LZ4_compress_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); /* LZ4_decompress_fast() : originalSize : is the original and therefore uncompressed size return : the number of bytes read from the source buffer (in other words, the compressed size) If the source stream is malformed, the function will stop decoding and return a negative result. note : This function is a bit faster than LZ4_decompress_safe() This function never writes outside of output buffers, but may read beyond input buffer in case of malicious data packet. Use this function preferably into a trusted environment (data to decode comes from a trusted source). Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. */ int LZ4_decompress_fast (const char* source, char* dest, int originalSize); /* LZ4_decompress_safe_partial() : This function decompress a compressed block of size 'inputSize' at position 'source' into output buffer 'dest' of size 'maxOutputSize'. The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, reducing decompression time. return : the number of bytes decoded in the destination buffer (necessarily <= maxOutputSize) Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. Always control how many bytes were decoded. If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ int LZ4_decompress_safe_partial (const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); /* These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. To know how much memory must be allocated for the compression tables, use : int LZ4_sizeofState(); Note that tables must be aligned on 4-bytes boundaries, otherwise compression will fail (return code 0). The allocated memory can be provided to the compressions functions using 'void* state' parameter. LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). */ int LZ4_sizeofState(void); int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); /************************************** Streaming Functions **************************************/ void* LZ4_create (const char* inputBuffer); int LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, int inputSize); int LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); char* LZ4_slideInputBuffer (void* LZ4_Data); int LZ4_free (void* LZ4_Data); /* These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. In order to achieve this, it is necessary to start creating the LZ4 Data Structure, thanks to the function : void* LZ4_create (const char* inputBuffer); The result of the function is the (void*) pointer on the LZ4 Data Structure. This pointer will be needed in all other functions. If the pointer returned is NULL, then the allocation has failed, and compression must be aborted. The only parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. The input buffer must be already allocated, and size at least 192KB. 'inputBuffer' will also be the 'const char* source' of the first block. All blocks are expected to lay next to each other within the input buffer, starting from 'inputBuffer'. To compress each block, use either LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(). Their behavior are identical to LZ4_compress() or LZ4_compress_limitedOutput(), but require the LZ4 Data Structure as their first argument, and check that each block starts right after the previous one. If next block does not begin immediately after the previous one, the compression will fail (return 0). When it's no longer possible to lay the next block after the previous one (not enough space left into input buffer), a call to : char* LZ4_slideInputBuffer(void* LZ4_Data); must be performed. It will typically copy the latest 64KB of input at the beginning of input buffer. Note that, for this function to work properly, minimum size of an input buffer must be 192KB. ==> The memory position where the next input data block must start is provided as the result of the function. Compression can then resume, using LZ4_compress_continue() or LZ4_compress_limitedOutput_continue(), as usual. When compression is completed, a call to LZ4_free() will release the memory used by the LZ4 Data Structure. */ int LZ4_sizeofStreamState(void); int LZ4_resetStreamState(void* state, const char* inputBuffer); /* These functions achieve the same result as : void* LZ4_create (const char* inputBuffer); They are provided here to allow the user program to allocate memory using its own routines. To know how much space must be allocated, use LZ4_sizeofStreamState(); Note also that space must be 4-bytes aligned. Once space is allocated, you must initialize it using : LZ4_resetStreamState(void* state, const char* inputBuffer); void* state is a pointer to the space allocated. It must be aligned on 4-bytes boundaries, and be large enough. The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. The input buffer must be already allocated, and size at least 192KB. 'inputBuffer' will also be the 'const char* source' of the first block. The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). return value of LZ4_resetStreamState() must be 0 is OK. Any other value means there was an error (typically, pointer is not aligned on 4-bytes boundaries). */ int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int inputSize, int maxOutputSize); int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int outputSize); /* *_withPrefix64k() : These decoding functions work the same as their "normal name" versions, but can use up to 64KB of data in front of 'char* dest'. These functions are necessary to decode inter-dependant blocks. */ /************************************** Obsolete Functions **************************************/ /* These functions are deprecated and should no longer be used. They are provided here for compatibility with existing user programs. */ int LZ4_uncompress (const char* source, char* dest, int outputSize); int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); #if defined (__cplusplus) } #endif lz4-0.0~r114/lz4_format_description.txt000066400000000000000000000113301231007221700201060ustar00rootroot00000000000000LZ4 Format Description Last revised: 2012-02-27 Author : Y. Collet This small specification intents to provide enough information to anyone willing to produce LZ4-compatible compressed data blocks using any programming language. LZ4 is an LZ77-type compressor with a fixed, byte-oriented encoding. The most important design principle behind LZ4 is simplicity. It helps to create an easy to read and maintain source code. It also helps later on for optimisations, compactness, and speed. There is no entropy encoder backend nor framing layer. The latter is assumed to be handled by other parts of the system. This document only describes the format, not how the LZ4 compressor nor decompressor actually work. The correctness of the decompressor should not depend on implementation details of the compressor, and vice versa. -- Compressed block format -- An LZ4 compressed block is composed of sequences. Schematically, a sequence is a suite of literals, followed by a match copy. Each sequence starts with a token. The token is a one byte value, separated into two 4-bits fields. Therefore each field ranges from 0 to 15. The first field uses the 4 high-bits of the token. It provides the length of literals to follow. (Note : a literal is a not-compressed byte). If the field value is 0, then there is no literal. If it is 15, then we need to add some more bytes to indicate the full length. Each additionnal byte then represent a value from 0 to 255, which is added to the previous value to produce a total length. When the byte value is 255, another byte is output. There can be any number of bytes following the token. There is no "size limit". (Sidenote this is why a not-compressible input block is expanded by 0.4%). Example 1 : A length of 48 will be represented as : - 15 : value for the 4-bits High field - 33 : (=48-15) remaining length to reach 48 Example 2 : A length of 280 will be represented as : - 15 : value for the 4-bits High field - 255 : following byte is maxed, since 280-15 >= 255 - 10 : (=280 - 15 - 255) ) remaining length to reach 280 Example 3 : A length of 15 will be represented as : - 15 : value for the 4-bits High field - 0 : (=15-15) yes, the zero must be output Following the token and optional length bytes, are the literals themselves. They are exactly as numerous as previously decoded (length of literals). It's possible that there are zero literal. Following the literals is the match copy operation. It starts by the offset. This is a 2 bytes value, in little endian format. The offset represents the position of the match to be copied from. 1 means "current position - 1 byte". The maximum offset value is 65535, 65536 cannot be coded. Note that 0 is an invalid value, not used. Then we need to extract the match length. For this, we use the second token field, the low 4-bits. Value, obviously, ranges from 0 to 15. However here, 0 means that the copy operation will be minimal. The minimum length of a match, called minmatch, is 4. As a consequence, a 0 value means 4 bytes, and a value of 15 means 19+ bytes. Similar to literal length, on reaching the highest possible value (15), we output additional bytes, one at a time, with values ranging from 0 to 255. They are added to total to provide the final match length. A 255 value means there is another byte to read and add. There is no limit to the number of optional bytes that can be output this way. (This points towards a maximum achievable compression ratio of ~250). With the offset and the matchlength, the decoder can now proceed to copy the data from the already decoded buffer. On decoding the matchlength, we reach the end of the compressed sequence, and therefore start another one. -- Parsing restrictions -- There are specific parsing rules to respect in order to remain compatible with assumptions made by the decoder : 1) The last 5 bytes are always literals 2) The last match must start at least 12 bytes before end of block Consequently, a block with less than 13 bytes cannot be compressed. These rules are in place to ensure that the decoder will never read beyond the input buffer, nor write beyond the output buffer. Note that the last sequence is also incomplete, and stops right after literals. -- Additional notes -- There is no assumption nor limits to the way the compressor searches and selects matches within the source data block. It could be a fast scan, a multi-probe, a full search using BST, standard hash chains or MMC, well whatever. Advanced parsing strategies can also be implemented, such as lazy match, or full optimal parsing. All these trade-off offer distinctive speed/memory/compression advantages. Whatever the method used by the compressor, its result will be decodable by any LZ4 decoder if it follows the format specification described above. lz4-0.0~r114/lz4hc.c000066400000000000000000000717211231007221700140630ustar00rootroot00000000000000/* LZ4 HC - High Compression Mode of LZ4 Copyright (C) 2011-2014, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ */ /************************************** Tuning Parameter **************************************/ #define LZ4HC_DEFAULT_COMPRESSIONLEVEL 8 /************************************** Memory routines **************************************/ #include /* calloc, free */ #define ALLOCATOR(s) calloc(1,s) #define FREEMEM free #include /* memset, memcpy */ #define MEM_INIT memset /************************************** CPU Feature Detection **************************************/ /* 32 or 64 bits ? */ #if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \ || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \ || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \ || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) ) /* Detects 64 bits mode */ # define LZ4_ARCH64 1 #else # define LZ4_ARCH64 0 #endif /* * Little Endian or Big Endian ? * Overwrite the #define below if you know your architecture endianess */ #if defined (__GLIBC__) # include # if (__BYTE_ORDER == __BIG_ENDIAN) # define LZ4_BIG_ENDIAN 1 # endif #elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) # define LZ4_BIG_ENDIAN 1 #elif defined(__sparc) || defined(__sparc__) \ || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \ || defined(__hpux) || defined(__hppa) \ || defined(_MIPSEB) || defined(__s390__) # define LZ4_BIG_ENDIAN 1 #else /* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */ #endif /* * Unaligned memory access is automatically enabled for "common" CPU, such as x86. * For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected * If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance */ #if defined(__ARM_FEATURE_UNALIGNED) # define LZ4_FORCE_UNALIGNED_ACCESS 1 #endif /* Define this parameter if your target system or compiler does not support hardware bit count */ #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ # define LZ4_FORCE_SW_BITCOUNT #endif /************************************** Compiler Options **************************************/ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ /* "restrict" is a known keyword */ #else # define restrict /* Disable restrict */ #endif #ifdef _MSC_VER /* Visual Studio */ # define FORCE_INLINE static __forceinline # include /* For Visual 2005 */ # if LZ4_ARCH64 /* 64-bits */ # pragma intrinsic(_BitScanForward64) /* For Visual 2005 */ # pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */ # else /* 32-bits */ # pragma intrinsic(_BitScanForward) /* For Visual 2005 */ # pragma intrinsic(_BitScanReverse) /* For Visual 2005 */ # endif # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ # pragma warning(disable : 4701) /* disable: C4701: potentially uninitialized local variable used */ #else # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif #endif #ifdef _MSC_VER /* Visual Studio */ # define lz4_bswap16(x) _byteswap_ushort(x) #else # define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8))) #endif /************************************** Includes **************************************/ #include "lz4hc.h" #include "lz4.h" /************************************** Basic Types **************************************/ #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif #if defined(__GNUC__) && !defined(LZ4_FORCE_UNALIGNED_ACCESS) # define _PACKED __attribute__ ((packed)) #else # define _PACKED #endif #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) # ifdef __IBMC__ # pragma pack(1) # else # pragma pack(push, 1) # endif #endif typedef struct _U16_S { U16 v; } _PACKED U16_S; typedef struct _U32_S { U32 v; } _PACKED U32_S; typedef struct _U64_S { U64 v; } _PACKED U64_S; #if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__) # pragma pack(pop) #endif #define A64(x) (((U64_S *)(x))->v) #define A32(x) (((U32_S *)(x))->v) #define A16(x) (((U16_S *)(x))->v) /************************************** Constants **************************************/ #define MINMATCH 4 #define DICTIONARY_LOGSIZE 16 #define MAXD (1<> ((MINMATCH*8)-HASH_LOG)) #define HASH_VALUE(p) HASH_FUNCTION(A32(p)) #define HASH_POINTER(p) (HashTable[HASH_VALUE(p)] + base) #define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK] #define GETNEXT(p) ((p) - (size_t)DELTANEXT(p)) /************************************** Private functions **************************************/ #if LZ4_ARCH64 FORCE_INLINE int LZ4_NbCommonBytes (register U64 val) { #if defined(LZ4_BIG_ENDIAN) # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanReverse64( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clzll(val) >> 3); # else int r; if (!(val>>32)) { r=4; } else { r=0; val>>=32; } if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } r += (!val); return r; # endif #else # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r = 0; _BitScanForward64( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctzll(val) >> 3); # else static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 }; return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58]; # endif #endif } #else FORCE_INLINE int LZ4_NbCommonBytes (register U32 val) { #if defined(LZ4_BIG_ENDIAN) # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanReverse( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_clz(val) >> 3); # else int r; if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; } r += (!val); return r; # endif #else # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) unsigned long r; _BitScanForward( &r, val ); return (int)(r>>3); # elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT) return (__builtin_ctz(val) >> 3); # else static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 }; return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; # endif #endif } #endif int LZ4_sizeofStreamStateHC() { return sizeof(LZ4HC_Data_Structure); } FORCE_INLINE void LZ4_initHC (LZ4HC_Data_Structure* hc4, const BYTE* base) { MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable)); MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable)); hc4->nextToUpdate = base + 1; hc4->base = base; hc4->inputBuffer = base; hc4->end = base; } int LZ4_resetStreamStateHC(void* state, const char* inputBuffer) { if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1; /* Error : pointer is not aligned for pointer (32 or 64 bits) */ LZ4_initHC((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer); return 0; } void* LZ4_createHC (const char* inputBuffer) { void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure)); LZ4_initHC ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer); return hc4; } int LZ4_freeHC (void* LZ4HC_Data) { FREEMEM(LZ4HC_Data); return (0); } /* Update chains up to ip (excluded) */ FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip) { U16* chainTable = hc4->chainTable; HTYPE* HashTable = hc4->hashTable; INITBASE(base,hc4->base); while(hc4->nextToUpdate < ip) { const BYTE* const p = hc4->nextToUpdate; size_t delta = (p) - HASH_POINTER(p); if (delta>MAX_DISTANCE) delta = MAX_DISTANCE; DELTANEXT(p) = (U16)delta; HashTable[HASH_VALUE(p)] = (HTYPE)((p) - base); hc4->nextToUpdate++; } } char* LZ4_slideInputBufferHC(void* LZ4HC_Data) { LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data; U32 distance = (U32)(hc4->end - hc4->inputBuffer) - 64 KB; distance = (distance >> 16) << 16; /* Must be a multiple of 64 KB */ LZ4HC_Insert(hc4, hc4->end - MINMATCH); memcpy((void*)(hc4->end - 64 KB - distance), (const void*)(hc4->end - 64 KB), 64 KB); hc4->nextToUpdate -= distance; hc4->base -= distance; if ((U32)(hc4->inputBuffer - hc4->base) > 1 GB + 64 KB) /* Avoid overflow */ { int i; hc4->base += 1 GB; for (i=0; ihashTable[i] -= 1 GB; } hc4->end -= distance; return (char*)(hc4->end); } FORCE_INLINE size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const matchlimit) { const BYTE* p1t = p1; while (p1tchainTable; HTYPE* const HashTable = hc4->hashTable; const BYTE* ref; INITBASE(base,hc4->base); int nbAttempts=maxNbAttempts; size_t repl=0, ml=0; U16 delta=0; /* useless assignment, to remove an uninitialization warning */ /* HC4 match finder */ LZ4HC_Insert(hc4, ip); ref = HASH_POINTER(ip); #define REPEAT_OPTIMIZATION #ifdef REPEAT_OPTIMIZATION /* Detect repetitive sequences of length <= 4 */ if ((U32)(ip-ref) <= 4) /* potential repetition */ { if (A32(ref) == A32(ip)) /* confirmed */ { delta = (U16)(ip-ref); repl = ml = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH; *matchpos = ref; } ref = GETNEXT(ref); } #endif while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts)) { nbAttempts--; if (*(ref+ml) == *(ip+ml)) if (A32(ref) == A32(ip)) { size_t mlt = LZ4HC_CommonLength(ip+MINMATCH, ref+MINMATCH, matchlimit) + MINMATCH; if (mlt > ml) { ml = mlt; *matchpos = ref; } } ref = GETNEXT(ref); } #ifdef REPEAT_OPTIMIZATION /* Complete table */ if (repl) { const BYTE* ptr = ip; const BYTE* end; end = ip + repl - (MINMATCH-1); while(ptr < end-delta) { DELTANEXT(ptr) = delta; /* Pre-Load */ ptr++; } do { DELTANEXT(ptr) = delta; HashTable[HASH_VALUE(ptr)] = (HTYPE)((ptr) - base); /* Head of chain */ ptr++; } while(ptr < end); hc4->nextToUpdate = end; } #endif return (int)ml; } FORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (LZ4HC_Data_Structure* hc4, const BYTE* ip, const BYTE* startLimit, const BYTE* matchlimit, int longest, const BYTE** matchpos, const BYTE** startpos, const int maxNbAttempts) { U16* const chainTable = hc4->chainTable; HTYPE* const HashTable = hc4->hashTable; INITBASE(base,hc4->base); const BYTE* ref; int nbAttempts = maxNbAttempts; int delta = (int)(ip-startLimit); /* First Match */ LZ4HC_Insert(hc4, ip); ref = HASH_POINTER(ip); while (((U32)(ip-ref) <= MAX_DISTANCE) && (nbAttempts)) { nbAttempts--; if (*(startLimit + longest) == *(ref - delta + longest)) if (A32(ref) == A32(ip)) { #if 1 const BYTE* reft = ref+MINMATCH; const BYTE* ipt = ip+MINMATCH; const BYTE* startt = ip; while (iptstartLimit) && (reft > hc4->inputBuffer) && (startt[-1] == reft[-1])) {startt--; reft--;} if ((ipt-startt) > longest) { longest = (int)(ipt-startt); *matchpos = reft; *startpos = startt; } } ref = GETNEXT(ref); } return longest; } typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive; FORCE_INLINE int LZ4HC_encodeSequence ( const BYTE** ip, BYTE** op, const BYTE** anchor, int matchLength, const BYTE* ref, limitedOutput_directive limitedOutputBuffer, BYTE* oend) { int length; BYTE* token; /* Encode Literal length */ length = (int)(*ip - *anchor); token = (*op)++; if ((limitedOutputBuffer) && ((*op + length + (2 + 1 + LASTLITERALS) + (length>>8)) > oend)) return 1; /* Check output limit */ if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK< 254 ; len-=255) *(*op)++ = 255; *(*op)++ = (BYTE)len; } else *token = (BYTE)(length<>8) > oend)) return 1; /* Check output limit */ if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; } else *token += (BYTE)(length); /* Prepare next loop */ *ip += matchLength; *anchor = *ip; return 0; } #define MAX_COMPRESSION_LEVEL 16 static int LZ4HC_compress_generic ( void* ctxvoid, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel, limitedOutput_directive limit ) { LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid; const BYTE* ip = (const BYTE*) source; const BYTE* anchor = ip; const BYTE* const iend = ip + inputSize; const BYTE* const mflimit = iend - MFLIMIT; const BYTE* const matchlimit = (iend - LASTLITERALS); BYTE* op = (BYTE*) dest; BYTE* const oend = op + maxOutputSize; const int maxNbAttempts = compressionLevel > MAX_COMPRESSION_LEVEL ? 1 << MAX_COMPRESSION_LEVEL : compressionLevel ? 1<<(compressionLevel-1) : 1<end) return 0; ctx->end += inputSize; ip++; /* Main Loop */ while (ip < mflimit) { ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts); if (!ml) { ip++; continue; } /* saved, in case we would skip too much */ start0 = ip; ref0 = ref; ml0 = ml; _Search2: if (ip+ml < mflimit) ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts); else ml2 = ml; if (ml2 == ml) /* No better match */ { if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; continue; } if (start0 < ip) { if (start2 < ip + ml0) /* empirical */ { ip = start0; ref = ref0; ml = ml0; } } /* Here, start0==ip */ if ((start2 - ip) < 3) /* First Match too small : removed */ { ml = ml2; ip = start2; ref =ref2; goto _Search2; } _Search3: /* * Currently we have : * ml2 > ml1, and * ip1+3 <= ip2 (usually < ip1+ml1) */ if ((start2 - ip) < OPTIMAL_ML) { int correction; int new_ml = ml; if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML; if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH; correction = new_ml - (int)(start2 - ip); if (correction > 0) { start2 += correction; ref2 += correction; ml2 -= correction; } } /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */ if (start2 + ml2 < mflimit) ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts); else ml3 = ml2; if (ml3 == ml2) /* No better match : 2 sequences to encode */ { /* ip & ref are known; Now for ml */ if (start2 < ip+ml) ml = (int)(start2 - ip); /* Now, encode 2 sequences */ if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; ip = start2; if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0; continue; } if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */ { if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */ { if (start2 < ip+ml) { int correction = (int)(ip+ml - start2); start2 += correction; ref2 += correction; ml2 -= correction; if (ml2 < MINMATCH) { start2 = start3; ref2 = ref3; ml2 = ml3; } } if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; ip = start3; ref = ref3; ml = ml3; start0 = start2; ref0 = ref2; ml0 = ml2; goto _Search2; } start2 = start3; ref2 = ref3; ml2 = ml3; goto _Search3; } /* * OK, now we have 3 ascending matches; let's write at least the first one * ip & ref are known; Now for ml */ if (start2 < ip+ml) { if ((start2 - ip) < (int)ML_MASK) { int correction; if (ml > OPTIMAL_ML) ml = OPTIMAL_ML; if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH; correction = ml - (int)(start2 - ip); if (correction > 0) { start2 += correction; ref2 += correction; ml2 -= correction; } } else { ml = (int)(start2 - ip); } } if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0; ip = start2; ref = ref2; ml = ml2; start2 = start3; ref2 = ref3; ml2 = ml3; goto _Search3; } /* Encode Last Literals */ { int lastRun = (int)(iend - anchor); if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0; /* Check output limit */ if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK< 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; } else *op++ = (BYTE)(lastRun< The memory position where the next input data block must start is provided as the result of the function. Compression can then resume, using LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue(), as usual. When compression is completed, a call to LZ4_freeHC() will release the memory used by the LZ4HC Data Structure. */ int LZ4_sizeofStreamStateHC(void); int LZ4_resetStreamStateHC(void* state, const char* inputBuffer); /* These functions achieve the same result as : void* LZ4_createHC (const char* inputBuffer); They are provided here to allow the user program to allocate memory using its own routines. To know how much space must be allocated, use LZ4_sizeofStreamStateHC(); Note also that space must be aligned for pointers (32 or 64 bits). Once space is allocated, you must initialize it using : LZ4_resetStreamStateHC(void* state, const char* inputBuffer); void* state is a pointer to the space allocated. It must be aligned for pointers (32 or 64 bits), and be large enough. The parameter 'const char* inputBuffer' must, obviously, point at the beginning of input buffer. The input buffer must be already allocated, and size at least 192KB. 'inputBuffer' will also be the 'const char* source' of the first block. The same space can be re-used multiple times, just by initializing it each time with LZ4_resetStreamState(). return value of LZ4_resetStreamStateHC() must be 0 is OK. Any other value means there was an error (typically, state is not aligned for pointers (32 or 64 bits)). */ #if defined (__cplusplus) } #endif lz4-0.0~r114/programs/000077500000000000000000000000001231007221700145155ustar00rootroot00000000000000lz4-0.0~r114/programs/COPYING000066400000000000000000000432541231007221700155600ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. lz4-0.0~r114/programs/Makefile000066400000000000000000000066161231007221700161660ustar00rootroot00000000000000# ################################################################ # LZ4 programs - Makefile # Copyright (C) Yann Collet 2011-2014 # GPL v2 License # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # # You can contact the author at : # - LZ4 source repository : http://code.google.com/p/lz4/ # - LZ4 forum froup : https://groups.google.com/forum/#!forum/lz4c # ################################################################ # lz4 : Command Line Utility, supporting gzip-like arguments # lz4c : CLU, supporting also legacy lz4demo arguments # lz4c32: Same as lz4c, but forced to compile in 32-bits mode # fuzzer : Test tool, to check lz4 integrity on target platform # fuzzer32: Same as fuzzer, but forced to compile in 32-bits mode # fullbench : Precisely measure speed for each LZ4 function variant # fullbench32: Same as fullbench, but forced to compile in 32-bits mode # ################################################################ RELEASE=r114 DESTDIR= PREFIX=/usr CC:=$(CC) CFLAGS+= -I.. -std=c99 -O3 -Wall -W -Wundef -DLZ4_VERSION=\"$(RELEASE)\" BINDIR=$(PREFIX)/bin MANDIR=$(PREFIX)/share/man/man1 LZ4DIR=.. # Define *.exe as extension for Windows systems ifneq (,$(filter Windows%,$(OS))) EXT =.exe else EXT = endif default: lz4 lz4c all: lz4 lz4c lz4c32 fuzzer fuzzer32 fullbench fullbench32 lz4: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c bench.c xxhash.c lz4io.c lz4cli.c $(CC) $(CFLAGS) -DDISABLE_LZ4C_LEGACY_OPTIONS $^ -o $@$(EXT) lz4c : $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c bench.c xxhash.c lz4io.c lz4cli.c $(CC) $(CFLAGS) $^ -o $@$(EXT) lz4c32: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c bench.c xxhash.c lz4io.c lz4cli.c $(CC) -m32 $(CFLAGS) $^ -o $@$(EXT) fuzzer : $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c fuzzer.c $(CC) $(CFLAGS) $^ -o $@$(EXT) fuzzer32: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c fuzzer.c $(CC) -m32 $(CFLAGS) $^ -o $@$(EXT) fullbench : $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c xxhash.c fullbench.c $(CC) $(CFLAGS) $^ -o $@$(EXT) fullbench32: $(LZ4DIR)/lz4.c $(LZ4DIR)/lz4hc.c xxhash.c fullbench.c $(CC) -m32 $(CFLAGS) $^ -o $@$(EXT) clean: @rm -f core *.o \ lz4$(EXT) lz4c$(EXT) lz4c32$(EXT) \ fuzzer$(EXT) fuzzer32$(EXT) fullbench$(EXT) fullbench32$(EXT) @echo Cleaning completed ifneq (,$(filter $(shell uname),Linux Darwin)) install: lz4 lz4c @install -d -m 755 $(DESTDIR)$(BINDIR)/ $(DESTDIR)$(MANDIR)/ @install -m 755 lz4 $(DESTDIR)$(BINDIR)/lz4 @install -m 755 lz4c $(DESTDIR)$(BINDIR)/lz4c @install -m 644 lz4.1 $(DESTDIR)$(MANDIR)/lz4.1 @echo lz4 installation completed uninstall: [ -x $(DESTDIR)$(BINDIR)/lz4 ] && rm -f $(DESTDIR)$(BINDIR)/lz4 [ -x $(DESTDIR)$(BINDIR)/lz4c ] && rm -f $(DESTDIR)$(BINDIR)/lz4c [ -f $(DESTDIR)$(MANDIR)/lz4.1 ] && rm -f $(DESTDIR)$(MANDIR)/lz4.1 @echo lz4 successfully uninstalled endif lz4-0.0~r114/programs/bench.c000066400000000000000000000324231231007221700157440ustar00rootroot00000000000000/* bench.c - Demo program to benchmark open-source compression algorithm Copyright (C) Yann Collet 2012-2013 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ */ //************************************** // Compiler Options //************************************** // Disable some Visual warning messages #define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_DEPRECATE // VS2005 // Unix Large Files support (>4GB) #define _FILE_OFFSET_BITS 64 #if (defined(__sun__) && (!defined(__LP64__))) // Sun Solaris 32-bits requires specific definitions # define _LARGEFILE_SOURCE #elif ! defined(__LP64__) // No point defining Large file for 64 bit # define _LARGEFILE64_SOURCE #endif // S_ISREG & gettimeofday() are not supported by MSVC #if defined(_MSC_VER) || defined(_WIN32) # define BMK_LEGACY_TIMER 1 #endif //************************************** // Includes //************************************** #include // malloc #include // fprintf, fopen, ftello64 #include // stat64 #include // stat64 // Use ftime() if gettimeofday() is not available on your target #if defined(BMK_LEGACY_TIMER) # include // timeb, ftime #else # include // gettimeofday #endif #include "lz4.h" #define COMPRESSOR0 LZ4_compress_local static int LZ4_compress_local(const char* src, char* dst, int size, int clevel) { (void)clevel; return LZ4_compress(src, dst, size); } #include "lz4hc.h" #define COMPRESSOR1 LZ4_compressHC2 #define DEFAULTCOMPRESSOR COMPRESSOR0 #include "xxhash.h" //************************************** // Compiler specifics //************************************** #if !defined(S_ISREG) # define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) #endif // GCC does not support _rotl outside of Windows #if !defined(_WIN32) # define _rotl(x,r) ((x << r) | (x >> (32 - r))) #endif //************************************** // Basic Types //************************************** #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif //************************************** // Constants //************************************** #define NBLOOPS 3 #define TIMELOOP 2000 #define KB *(1U<<10) #define MB *(1U<<20) #define GB *(1U<<30) #define KNUTH 2654435761U #define MAX_MEM (2 GB - 64 MB) #define DEFAULT_CHUNKSIZE (4 MB) //************************************** // Local structures //************************************** struct chunkParameters { U32 id; char* origBuffer; char* compressedBuffer; int origSize; int compressedSize; }; struct compressionParameters { int (*compressionFunction)(const char*, char*, int, int); int (*decompressionFunction)(const char*, char*, int); }; //************************************** // MACRO //************************************** #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) //************************************** // Benchmark Parameters //************************************** static int chunkSize = DEFAULT_CHUNKSIZE; static int nbIterations = NBLOOPS; static int BMK_pause = 0; void BMK_SetBlocksize(int bsize) { chunkSize = bsize; } void BMK_SetNbIterations(int nbLoops) { nbIterations = nbLoops; DISPLAY("- %i iterations -\n", nbIterations); } void BMK_SetPause() { BMK_pause = 1; } //********************************************************* // Private functions //********************************************************* #if defined(BMK_LEGACY_TIMER) static int BMK_GetMilliStart() { // Based on Legacy ftime() // Rolls over every ~ 12.1 days (0x100000/24/60/60) // Use GetMilliSpan to correct for rollover struct timeb tb; int nCount; ftime( &tb ); nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000); return nCount; } #else static int BMK_GetMilliStart() { // Based on newer gettimeofday() // Use GetMilliSpan to correct for rollover struct timeval tv; int nCount; gettimeofday(&tv, NULL); nCount = (int) (tv.tv_usec/1000 + (tv.tv_sec & 0xfffff) * 1000); return nCount; } #endif static int BMK_GetMilliSpan( int nTimeStart ) { int nSpan = BMK_GetMilliStart() - nTimeStart; if ( nSpan < 0 ) nSpan += 0x100000 * 1000; return nSpan; } static size_t BMK_findMaxMem(U64 requiredMem) { size_t step = (64 MB); BYTE* testmem=NULL; requiredMem = (((requiredMem >> 26) + 1) << 26); requiredMem += 2*step; if (requiredMem > MAX_MEM) requiredMem = MAX_MEM; while (!testmem) { requiredMem -= step; testmem = (BYTE*) malloc ((size_t)requiredMem); } free (testmem); return (size_t) (requiredMem - step); } static U64 BMK_GetFileSize(char* infilename) { int r; #if defined(_MSC_VER) struct _stat64 statbuf; r = _stat64(infilename, &statbuf); #else struct stat statbuf; r = stat(infilename, &statbuf); #endif if (r || !S_ISREG(statbuf.st_mode)) return 0; // No good... return (U64)statbuf.st_size; } //********************************************************* // Public function //********************************************************* int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel) { int fileIdx=0; char* orig_buff; struct compressionParameters compP; int cfunctionId; U64 totals = 0; U64 totalz = 0; double totalc = 0.; double totald = 0.; // Init if (cLevel <= 3) cfunctionId = 0; else cfunctionId = 1; switch (cfunctionId) { #ifdef COMPRESSOR0 case 0 : compP.compressionFunction = COMPRESSOR0; break; #endif #ifdef COMPRESSOR1 case 1 : compP.compressionFunction = COMPRESSOR1; break; #endif default : compP.compressionFunction = DEFAULTCOMPRESSOR; } compP.decompressionFunction = LZ4_decompress_fast; // Loop for each file while (fileIdx inFileSize) benchedSize = (size_t)inFileSize; if (benchedSize < inFileSize) { DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize>>20)); } // Alloc chunkP = (struct chunkParameters*) malloc(((benchedSize / (size_t)chunkSize)+1) * sizeof(struct chunkParameters)); orig_buff = (char*)malloc((size_t )benchedSize); nbChunks = (int) ((int)benchedSize / chunkSize) + 1; maxCompressedChunkSize = LZ4_compressBound(chunkSize); compressedBuffSize = nbChunks * maxCompressedChunkSize; compressedBuffer = (char*)malloc((size_t )compressedBuffSize); if (!orig_buff || !compressedBuffer) { DISPLAY("\nError: not enough memory!\n"); free(orig_buff); free(compressedBuffer); free(chunkP); fclose(inFile); return 12; } // Init chunks data { int i; size_t remaining = benchedSize; char* in = orig_buff; char* out = compressedBuffer; for (i=0; i chunkSize) { chunkP[i].origSize = chunkSize; remaining -= chunkSize; } else { chunkP[i].origSize = (int)remaining; remaining = 0; } chunkP[i].compressedBuffer = out; out += maxCompressedChunkSize; chunkP[i].compressedSize = 0; } } // Fill input buffer DISPLAY("Loading %s... \r", inFileName); readSize = fread(orig_buff, 1, benchedSize, inFile); fclose(inFile); if (readSize != benchedSize) { DISPLAY("\nError: problem reading file '%s' !! \n", inFileName); free(orig_buff); free(compressedBuffer); free(chunkP); return 13; } // Calculating input Checksum crcOrig = XXH32(orig_buff, (unsigned int)benchedSize,0); // Bench { int loopNb, chunkNb; size_t cSize=0; double fastestC = 100000000., fastestD = 100000000.; double ratio=0.; U32 crcCheck=0; DISPLAY("\r%79s\r", ""); for (loopNb = 1; loopNb <= nbIterations; loopNb++) { int nbLoops; int milliTime; // Compression DISPLAY("%1i-%-14.14s : %9i ->\r", loopNb, inFileName, (int)benchedSize); { size_t i; for (i=0; i %9i (%5.2f%%),%7.1f MB/s\r", loopNb, inFileName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / fastestC / 1000.); // Decompression { size_t i; for (i=0; i %9i (%5.2f%%),%7.1f MB/s ,%7.1f MB/s\r", loopNb, inFileName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / fastestC / 1000., (double)benchedSize / fastestD / 1000.); // CRC Checking crcCheck = XXH32(orig_buff, (unsigned int)benchedSize,0); if (crcOrig!=crcCheck) { DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", inFileName, (unsigned)crcOrig, (unsigned)crcCheck); break; } } if (crcOrig==crcCheck) { if (ratio<100.) DISPLAY("%-16.16s : %9i -> %9i (%5.2f%%),%7.1f MB/s ,%7.1f MB/s\n", inFileName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / fastestC / 1000., (double)benchedSize / fastestD / 1000.); else DISPLAY("%-16.16s : %9i -> %9i (%5.1f%%),%7.1f MB/s ,%7.1f MB/s \n", inFileName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / fastestC / 1000., (double)benchedSize / fastestD / 1000.); } totals += benchedSize; totalz += cSize; totalc += fastestC; totald += fastestD; } free(orig_buff); free(compressedBuffer); free(chunkP); } if (nbFiles > 1) DISPLAY("%-16.16s :%10llu ->%10llu (%5.2f%%), %6.1f MB/s , %6.1f MB/s\n", " TOTAL", (long long unsigned int)totals, (long long unsigned int)totalz, (double)totalz/(double)totals*100., (double)totals/totalc/1000., (double)totals/totald/1000.); if (BMK_pause) { DISPLAY("\npress enter...\n"); getchar(); } return 0; } lz4-0.0~r114/programs/bench.h000066400000000000000000000024061231007221700157470ustar00rootroot00000000000000/* bench.h - Demo program to benchmark open-source compression algorithm Copyright (C) Yann Collet 2012-2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ */ #pragma once #if defined (__cplusplus) extern "C" { #endif int BMK_benchFile(char** fileNamesTable, int nbFiles, int cLevel); // Parameters void BMK_SetBlocksize(int bsize); void BMK_SetNbIterations(int nbLoops); void BMK_SetPause(); #if defined (__cplusplus) } #endif lz4-0.0~r114/programs/fullbench.c000066400000000000000000000623451231007221700166350ustar00rootroot00000000000000/* bench.c - Demo program to benchmark open-source compression algorithm Copyright (C) Yann Collet 2012-2013 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ */ //************************************** // Compiler Options //************************************** // Disable some Visual warning messages #define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_DEPRECATE // VS2005 // Unix Large Files support (>4GB) #if (defined(__sun__) && (!defined(__LP64__))) // Sun Solaris 32-bits requires specific definitions # define _LARGEFILE_SOURCE # define _FILE_OFFSET_BITS 64 #elif ! defined(__LP64__) // No point defining Large file for 64 bit # define _LARGEFILE64_SOURCE #endif // S_ISREG & gettimeofday() are not supported by MSVC #if defined(_MSC_VER) || defined(_WIN32) # define BMK_LEGACY_TIMER 1 #endif //************************************** // Includes //************************************** #include // malloc #include // fprintf, fopen, ftello64 #include // stat64 #include // stat64 // Use ftime() if gettimeofday() is not available on your target #if defined(BMK_LEGACY_TIMER) # include // timeb, ftime #else # include // gettimeofday #endif #include "lz4.h" #define COMPRESSOR0 LZ4_compress #include "lz4hc.h" #define COMPRESSOR1 LZ4_compressHC #define DEFAULTCOMPRESSOR COMPRESSOR0 #include "xxhash.h" //************************************** // Compiler Options //************************************** // S_ISREG & gettimeofday() are not supported by MSVC #if !defined(S_ISREG) # define S_ISREG(x) (((x) & S_IFMT) == S_IFREG) #endif // GCC does not support _rotl outside of Windows #if !defined(_WIN32) # define _rotl(x,r) ((x << r) | (x >> (32 - r))) #endif //************************************** // Basic Types //************************************** #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif //**************************** // Constants //**************************** #define PROGRAM_DESCRIPTION "LZ4 speed analyzer" #ifndef LZ4_VERSION # define LZ4_VERSION "" #endif #define AUTHOR "Yann Collet" #define WELCOME_MESSAGE "*** %s %s %i-bits, by %s (%s) ***\n", PROGRAM_DESCRIPTION, LZ4_VERSION, (int)(sizeof(void*)*8), AUTHOR, __DATE__ #define NBLOOPS 6 #define TIMELOOP 2500 #define KNUTH 2654435761U #define MAX_MEM (1984<<20) #define DEFAULT_CHUNKSIZE (4<<20) #define ALL_COMPRESSORS -1 #define ALL_DECOMPRESSORS -1 //************************************** // Local structures //************************************** struct chunkParameters { U32 id; char* origBuffer; char* compressedBuffer; int origSize; int compressedSize; }; //************************************** // MACRO //************************************** #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) //************************************** // Benchmark Parameters //************************************** static int chunkSize = DEFAULT_CHUNKSIZE; static int nbIterations = NBLOOPS; static int BMK_pause = 0; static int compressionTest = 1; static int decompressionTest = 1; static int compressionAlgo = ALL_COMPRESSORS; static int decompressionAlgo = ALL_DECOMPRESSORS; void BMK_SetBlocksize(int bsize) { chunkSize = bsize; DISPLAY("-Using Block Size of %i KB-\n", chunkSize>>10); } void BMK_SetNbIterations(int nbLoops) { nbIterations = nbLoops; DISPLAY("- %i iterations -\n", nbIterations); } void BMK_SetPause() { BMK_pause = 1; } //********************************************************* // Private functions //********************************************************* #if defined(BMK_LEGACY_TIMER) static int BMK_GetMilliStart() { // Based on Legacy ftime() // Rolls over every ~ 12.1 days (0x100000/24/60/60) // Use GetMilliSpan to correct for rollover struct timeb tb; int nCount; ftime( &tb ); nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000); return nCount; } #else static int BMK_GetMilliStart() { // Based on newer gettimeofday() // Use GetMilliSpan to correct for rollover struct timeval tv; int nCount; gettimeofday(&tv, NULL); nCount = (int) (tv.tv_usec/1000 + (tv.tv_sec & 0xfffff) * 1000); return nCount; } #endif static int BMK_GetMilliSpan( int nTimeStart ) { int nSpan = BMK_GetMilliStart() - nTimeStart; if ( nSpan < 0 ) nSpan += 0x100000 * 1000; return nSpan; } static size_t BMK_findMaxMem(U64 requiredMem) { size_t step = (64U<<20); // 64 MB BYTE* testmem=NULL; requiredMem = (((requiredMem >> 25) + 1) << 26); if (requiredMem > MAX_MEM) requiredMem = MAX_MEM; requiredMem += 2*step; while (!testmem) { requiredMem -= step; testmem = (BYTE*) malloc ((size_t)requiredMem); } free (testmem); return (size_t) (requiredMem - step); } static U64 BMK_GetFileSize(char* infilename) { int r; #if defined(_MSC_VER) struct _stat64 statbuf; r = _stat64(infilename, &statbuf); #else struct stat statbuf; r = stat(infilename, &statbuf); #endif if (r || !S_ISREG(statbuf.st_mode)) return 0; // No good... return (U64)statbuf.st_size; } //********************************************************* // Public function //********************************************************* static inline int local_LZ4_compress_limitedOutput(const char* in, char* out, int inSize) { return LZ4_compress_limitedOutput(in, out, inSize, LZ4_compressBound(inSize)); } static void* stateLZ4; static inline int local_LZ4_compress_withState(const char* in, char* out, int inSize) { return LZ4_compress_withState(stateLZ4, in, out, inSize); } static inline int local_LZ4_compress_limitedOutput_withState(const char* in, char* out, int inSize) { return LZ4_compress_limitedOutput_withState(stateLZ4, in, out, inSize, LZ4_compressBound(inSize)); } static void* ctx; static inline int local_LZ4_compress_continue(const char* in, char* out, int inSize) { return LZ4_compress_continue(ctx, in, out, inSize); } static inline int local_LZ4_compress_limitedOutput_continue(const char* in, char* out, int inSize) { return LZ4_compress_limitedOutput_continue(ctx, in, out, inSize, LZ4_compressBound(inSize)); } static void* stateLZ4HC; static inline int local_LZ4_compressHC_withStateHC(const char* in, char* out, int inSize) { return LZ4_compress_withState(stateLZ4HC, in, out, inSize); } static inline int local_LZ4_compressHC_limitedOutput_withStateHC(const char* in, char* out, int inSize) { return LZ4_compress_limitedOutput_withState(stateLZ4HC, in, out, inSize, LZ4_compressBound(inSize)); } static inline int local_LZ4_compressHC_limitedOutput(const char* in, char* out, int inSize) { return LZ4_compressHC_limitedOutput(in, out, inSize, LZ4_compressBound(inSize)); } static inline int local_LZ4_compressHC_continue(const char* in, char* out, int inSize) { return LZ4_compressHC_continue(ctx, in, out, inSize); } static inline int local_LZ4_compressHC_limitedOutput_continue(const char* in, char* out, int inSize) { return LZ4_compressHC_limitedOutput_continue(ctx, in, out, inSize, LZ4_compressBound(inSize)); } static inline int local_LZ4_decompress_fast(const char* in, char* out, int inSize, int outSize) { (void)inSize; LZ4_decompress_fast(in, out, outSize); return outSize; } static inline int local_LZ4_decompress_fast_withPrefix64k(const char* in, char* out, int inSize, int outSize) { (void)inSize; LZ4_decompress_fast_withPrefix64k(in, out, outSize); return outSize; } static inline int local_LZ4_decompress_safe_partial(const char* in, char* out, int inSize, int outSize) { return LZ4_decompress_safe_partial(in, out, inSize, outSize - 5, outSize); } int fullSpeedBench(char** fileNamesTable, int nbFiles) { int fileIdx=0; char* orig_buff; # define NB_COMPRESSION_ALGORITHMS 12 # define MINCOMPRESSIONCHAR '0' # define MAXCOMPRESSIONCHAR (MINCOMPRESSIONCHAR + NB_COMPRESSION_ALGORITHMS) static char* compressionNames[] = { "LZ4_compress", "LZ4_compress_limitedOutput", "LZ4_compress_withState", "LZ4_compress_limitedOutput_withState", "LZ4_compress_continue", "LZ4_compress_limitedOutput_continue", "LZ4_compressHC", "LZ4_compressHC_limitedOutput", "LZ4_compressHC_withStateHC", "LZ4_compressHC_limitedOutput_withStateHC", "LZ4_compressHC_continue", "LZ4_compressHC_limitedOutput_continue" }; double totalCTime[NB_COMPRESSION_ALGORITHMS] = {0}; double totalCSize[NB_COMPRESSION_ALGORITHMS] = {0}; # define NB_DECOMPRESSION_ALGORITHMS 5 # define MINDECOMPRESSIONCHAR '0' # define MAXDECOMPRESSIONCHAR (MINDECOMPRESSIONCHAR + NB_DECOMPRESSION_ALGORITHMS) static char* decompressionNames[] = { "LZ4_decompress_fast", "LZ4_decompress_fast_withPrefix64k", "LZ4_decompress_safe", "LZ4_decompress_safe_withPrefix64k", "LZ4_decompress_safe_partial" }; double totalDTime[NB_DECOMPRESSION_ALGORITHMS] = {0}; U64 totals = 0; // Loop for each file while (fileIdx inFileSize) benchedSize = (size_t)inFileSize; if (benchedSize < inFileSize) { DISPLAY("Not enough memory for '%s' full size; testing %i MB only...\n", inFileName, (int)(benchedSize>>20)); } // Alloc chunkP = (struct chunkParameters*) malloc(((benchedSize / (size_t)chunkSize)+1) * sizeof(struct chunkParameters)); orig_buff = (char*) malloc((size_t)benchedSize); nbChunks = (int) ((int)benchedSize / chunkSize) + 1; maxCompressedChunkSize = LZ4_compressBound(chunkSize); compressedBuffSize = nbChunks * maxCompressedChunkSize; compressed_buff = (char*)malloc((size_t)compressedBuffSize); if(!orig_buff || !compressed_buff) { DISPLAY("\nError: not enough memory!\n"); free(orig_buff); free(compressed_buff); free(chunkP); fclose(inFile); return 12; } // Init chunks data { int i; size_t remaining = benchedSize; char* in = orig_buff; char* out = compressed_buff; for (i=0; i chunkSize) { chunkP[i].origSize = chunkSize; remaining -= chunkSize; } else { chunkP[i].origSize = (int)remaining; remaining = 0; } chunkP[i].compressedBuffer = out; out += maxCompressedChunkSize; chunkP[i].compressedSize = 0; } } // Fill input buffer DISPLAY("Loading %s... \r", inFileName); readSize = fread(orig_buff, 1, benchedSize, inFile); fclose(inFile); if(readSize != benchedSize) { DISPLAY("\nError: problem reading file '%s' !! \n", inFileName); free(orig_buff); free(compressed_buff); free(chunkP); return 13; } // Calculating input Checksum crcOriginal = XXH32(orig_buff, (unsigned int)benchedSize,0); // Bench { int loopNb, nb_loops, chunkNb, cAlgNb, dAlgNb; size_t cSize=0; double ratio=0.; DISPLAY("\r%79s\r", ""); DISPLAY(" %s : \n", inFileName); // Compression Algorithms for (cAlgNb=0; (cAlgNb < NB_COMPRESSION_ALGORITHMS) && (compressionTest); cAlgNb++) { char* cName = compressionNames[cAlgNb]; int (*compressionFunction)(const char*, char*, int); void* (*initFunction)(const char*) = NULL; double bestTime = 100000000.; if ((compressionAlgo != ALL_COMPRESSORS) && (compressionAlgo != cAlgNb)) continue; switch(cAlgNb) { case 0 : compressionFunction = LZ4_compress; break; case 1 : compressionFunction = local_LZ4_compress_limitedOutput; break; case 2 : compressionFunction = local_LZ4_compress_withState; break; case 3 : compressionFunction = local_LZ4_compress_limitedOutput_withState; break; case 4 : compressionFunction = local_LZ4_compress_continue; initFunction = LZ4_create; break; case 5 : compressionFunction = local_LZ4_compress_limitedOutput_continue; initFunction = LZ4_create; break; case 6 : compressionFunction = LZ4_compressHC; break; case 7 : compressionFunction = local_LZ4_compressHC_limitedOutput; break; case 8 : compressionFunction = local_LZ4_compressHC_withStateHC; break; case 9 : compressionFunction = local_LZ4_compressHC_limitedOutput_withStateHC; break; case 10: compressionFunction = local_LZ4_compressHC_continue; initFunction = LZ4_createHC; break; case 11: compressionFunction = local_LZ4_compressHC_limitedOutput_continue; initFunction = LZ4_createHC; break; default : DISPLAY("ERROR ! Bad algorithm Id !! \n"); free(chunkP); return 1; } for (loopNb = 1; loopNb <= nbIterations; loopNb++) { double averageTime; int milliTime; DISPLAY("%1i-%-19.19s : %9i ->\r", loopNb, cName, (int)benchedSize); { size_t i; for (i=0; i %9i (%5.2f%%),%7.1f MB/s\r", loopNb, cName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.); } if (ratio<100.) DISPLAY("%-21.21s : %9i -> %9i (%5.2f%%),%7.1f MB/s\n", cName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.); else DISPLAY("%-21.21s : %9i -> %9i (%5.1f%%),%7.1f MB/s\n", cName, (int)benchedSize, (int)cSize, ratio, (double)benchedSize / bestTime / 1000.); totalCTime[cAlgNb] += bestTime; totalCSize[cAlgNb] += cSize; } // Prepare layout for decompression for (chunkNb=0; chunkNb\r", loopNb, dName, (int)benchedSize); nb_loops = 0; milliTime = BMK_GetMilliStart(); while(BMK_GetMilliStart() == milliTime); milliTime = BMK_GetMilliStart(); while(BMK_GetMilliSpan(milliTime) < TIMELOOP) { for (chunkNb=0; chunkNb %7.1f MB/s\r", loopNb, dName, (int)benchedSize, (double)benchedSize / bestTime / 1000.); // CRC Checking crcDecoded = XXH32(orig_buff, (int)benchedSize, 0); if (crcOriginal!=crcDecoded) { DISPLAY("\n!!! WARNING !!! %14s : Invalid Checksum : %x != %x\n", inFileName, (unsigned)crcOriginal, (unsigned)crcDecoded); exit(1); } } DISPLAY("%-26.26s :%10i -> %7.1f MB/s\n", dName, (int)benchedSize, (double)benchedSize / bestTime / 1000.); totalDTime[dAlgNb] += bestTime; } totals += benchedSize; } free(orig_buff); free(compressed_buff); free(chunkP); } if (nbFiles > 1) { int AlgNb; DISPLAY(" ** TOTAL ** : \n"); for (AlgNb = 0; (AlgNb < NB_COMPRESSION_ALGORITHMS) && (compressionTest); AlgNb ++) { char* cName = compressionNames[AlgNb]; if ((compressionAlgo != ALL_COMPRESSORS) && (compressionAlgo != AlgNb)) continue; DISPLAY("%-21.21s :%10llu ->%10llu (%5.2f%%), %6.1f MB/s\n", cName, (long long unsigned int)totals, (long long unsigned int)totalCSize[AlgNb], (double)totalCSize[AlgNb]/(double)totals*100., (double)totals/totalCTime[AlgNb]/1000.); } for (AlgNb = 0; (AlgNb < NB_DECOMPRESSION_ALGORITHMS) && (decompressionTest); AlgNb ++) { char* dName = decompressionNames[AlgNb]; if ((decompressionAlgo != ALL_DECOMPRESSORS) && (decompressionAlgo != AlgNb)) continue; DISPLAY("%-21.21s :%10llu -> %6.1f MB/s\n", dName, (long long unsigned int)totals, (double)totals/totalDTime[AlgNb]/1000.); } } if (BMK_pause) { printf("press enter...\n"); getchar(); } return 0; } int usage(char* exename) { DISPLAY( "Usage :\n"); DISPLAY( " %s [arg] file1 file2 ... fileX\n", exename); DISPLAY( "Arguments :\n"); DISPLAY( " -c : compression tests only\n"); DISPLAY( " -d : decompression tests only\n"); DISPLAY( " -H/-h : Help (this text + advanced options)\n"); return 0; } int usage_advanced() { DISPLAY( "\nAdvanced options :\n"); DISPLAY( " -c# : test only compression function # [%c-%c]\n", MINCOMPRESSIONCHAR, MAXCOMPRESSIONCHAR); DISPLAY( " -d# : test only compression function # [%c-%c]\n", MINDECOMPRESSIONCHAR, MAXDECOMPRESSIONCHAR); DISPLAY( " -i# : iteration loops [1-9](default : %i)\n", NBLOOPS); DISPLAY( " -B# : Block size [4-7](default : 7)\n"); //DISPLAY( " -BD : Block dependency (improve compression ratio)\n"); return 0; } int badusage(char* exename) { DISPLAY("Wrong parameters\n"); usage(exename); return 0; } int main(int argc, char** argv) { int i, filenamesStart=2; char* exename=argv[0]; char* input_filename=0; // Welcome message DISPLAY( WELCOME_MESSAGE); if (argc<2) { badusage(exename); return 1; } for(i=1; i= MINCOMPRESSIONCHAR) && (argument[1]<= MAXCOMPRESSIONCHAR)) compressionAlgo = argument[1] - '0', argument++; break; // Select decompression algorithm only case 'd': compressionTest = 0; if ((argument[1]>= MINDECOMPRESSIONCHAR) && (argument[1]<= MAXDECOMPRESSIONCHAR)) decompressionAlgo = argument[1] - '0', argument++; break; // Display help on usage case 'h' : case 'H': usage(exename); usage_advanced(); return 0; // Modify Block Properties case 'B': while (argument[1]!=0) switch(argument[1]) { case '4': case '5': case '6': case '7': { int B = argument[1] - '0'; int S = 1 << (8 + 2*B); BMK_SetBlocksize(S); argument++; break; } case 'D': argument++; break; default : goto _exit_blockProperties; } _exit_blockProperties: break; // Modify Nb Iterations case 'i': if ((argument[1] >='1') && (argument[1] <='9')) { int iters = argument[1] - '0'; BMK_SetNbIterations(iters); argument++; } break; // Pause at the end (hidden option) case 'p': BMK_SetPause(); break; // Unrecognised command default : badusage(exename); return 1; } } continue; } // first provided filename is input if (!input_filename) { input_filename=argument; filenamesStart=i; continue; } } // No input filename ==> Error if(!input_filename) { badusage(exename); return 1; } return fullSpeedBench(argv+filenamesStart, argc-filenamesStart); } lz4-0.0~r114/programs/fuzzer.c000066400000000000000000000305731231007221700162160ustar00rootroot00000000000000/* fuzzer.c - Fuzzer test tool for LZ4 Copyright (C) Yann Collet - Andrew Mahone 2012-2014 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html - LZ4 source repository : http://code.google.com/p/lz4/ */ //************************************** // Remove Visual warning messages //************************************** #define _CRT_SECURE_NO_WARNINGS // fgets //************************************** // Includes //************************************** #include #include // fgets, sscanf #include // timeb #include "lz4.h" #include "lz4hc.h" //************************************** // Constants //************************************** #ifndef LZ4_VERSION # define LZ4_VERSION "" #endif #define NB_ATTEMPTS (1<<17) #define LEN ((1<<15)) #define SEQ_POW 2 #define NUM_SEQ (1 << SEQ_POW) #define SEQ_MSK ((NUM_SEQ) - 1) #define MOD_SEQ(x) ((((x) >> 8) & 255) == 0) #define NEW_SEQ(x) ((((x) >> 10) %10) == 0) #define PAGE_SIZE 4096 #define ROUND_PAGE(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) #define PRIME1 2654435761U #define PRIME2 2246822519U #define PRIME3 3266489917U //********************************************************* // Functions //********************************************************* static int FUZ_GetMilliStart() { struct timeb tb; int nCount; ftime( &tb ); nCount = (int) (tb.millitm + (tb.time & 0xfffff) * 1000); return nCount; } static int FUZ_GetMilliSpan( int nTimeStart ) { int nSpan = FUZ_GetMilliStart() - nTimeStart; if ( nSpan < 0 ) nSpan += 0x100000 * 1000; return nSpan; } unsigned int FUZ_rand(unsigned int* src) { *src = ((*src) * PRIME1) + PRIME2; return *src; } int test_canary(unsigned char *buf) { int i; for (i = 0; i < 2048; i++) if (buf[i] != buf[i + 2048]) return 0; return 1; } int FUZ_SecurityTest() { char* output; char* input; int i, r; printf("Overflow test (issue 52)...\n"); input = (char*) malloc (20<<20); output = (char*) malloc (20<<20); input[0] = 0x0F; input[1] = 0x00; input[2] = 0x00; for(i = 3; i < 16840000; i++) input[i] = 0xff; r = LZ4_decompress_fast(input, output, 20<<20); free(input); free(output); printf(" Passed (return = %i < 0)\n",r); return 0; } //int main(int argc, char *argv[]) { int main() { unsigned long long bytes = 0; unsigned long long cbytes = 0; unsigned long long hcbytes = 0; unsigned char buf[LEN]; unsigned char testOut[LEN+1]; # define FUZ_max LZ4_COMPRESSBOUND(LEN) # define FUZ_avail ROUND_PAGE(FUZ_max) const int off_full = FUZ_avail - FUZ_max; unsigned char cbuf[FUZ_avail + PAGE_SIZE]; unsigned int seed, randState, cur_seq=PRIME3, seeds[NUM_SEQ], timestamp=FUZ_GetMilliStart(); int i, j, k, ret, len, lenHC, attemptNb; char userInput[30] = {0}; # define FUZ_CHECKTEST(cond, message) if (cond) { printf("Test %i : %s : seed %u, cycle %i \n", testNb, message, seed, attemptNb); goto _output_error; } # define FUZ_DISPLAYTEST testNb++; printf("%2i\b\b", testNb); void* stateLZ4 = malloc(LZ4_sizeofState()); void* stateLZ4HC = malloc(LZ4_sizeofStateHC()); printf("starting LZ4 fuzzer (%s)\n", LZ4_VERSION); printf("Select an Initialisation number (default : random) : "); fflush(stdout); if ( fgets(userInput, sizeof userInput, stdin) ) { if ( sscanf(userInput, "%u", &seed) == 1 ) {} else seed = FUZ_GetMilliSpan(timestamp); } printf("Seed = %u\n", seed); randState = seed; //FUZ_SecurityTest(); for (i = 0; i < 2048; i++) cbuf[FUZ_avail + i] = cbuf[FUZ_avail + 2048 + i] = FUZ_rand(&randState) >> 16; for (attemptNb = 0; attemptNb < NB_ATTEMPTS; attemptNb++) { int testNb = 0; printf("\r%7i /%7i - ", attemptNb, NB_ATTEMPTS); for (j = 0; j < NUM_SEQ; j++) { seeds[j] = FUZ_rand(&randState) << 8; seeds[j] ^= (FUZ_rand(&randState) >> 8) & 65535; } for (j = 0; j < LEN; j++) { k = FUZ_rand(&randState); if (j == 0 || NEW_SEQ(k)) cur_seq = seeds[(FUZ_rand(&randState) >> 16) & SEQ_MSK]; if (MOD_SEQ(k)) { k = (FUZ_rand(&randState) >> 16) & SEQ_MSK; seeds[k] = FUZ_rand(&randState) << 8; seeds[k] ^= (FUZ_rand(&randState) >> 8) & 65535; } buf[j] = FUZ_rand(&cur_seq) >> 16; } // Test compression HC FUZ_DISPLAYTEST; // 1 ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput() failed despite sufficient space"); lenHC = ret; // Test compression HC using external state FUZ_DISPLAYTEST; // 1 ret = LZ4_compressHC_withStateHC(stateLZ4HC, (const char*)buf, (char*)&cbuf[off_full], LEN); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_withStateHC() failed"); // Test compression using external state FUZ_DISPLAYTEST; // 2 ret = LZ4_compress_withState(stateLZ4, (const char*)buf, (char*)&cbuf[off_full], LEN); FUZ_CHECKTEST(ret==0, "LZ4_compress_withState() failed"); // Test compression FUZ_DISPLAYTEST; // 2 ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[off_full], LEN, FUZ_max); FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput() failed despite sufficient space"); len = ret; // Test decoding with output size being exactly what's necessary => must work FUZ_DISPLAYTEST; // 3 ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN); FUZ_CHECKTEST(ret<0, "LZ4_decompress_fast failed despite correct space"); // Test decoding with one byte missing => must fail FUZ_DISPLAYTEST; // 4 ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN-1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too small"); // Test decoding with one byte too much => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_fast((char*)&cbuf[off_full], (char*)testOut, LEN+1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_fast should have failed, due to Output Size being too large"); // Test decoding with enough output size => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN+1); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite sufficient space"); // Test decoding with output size being exactly what's necessary => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe failed despite sufficient space"); // Test decoding with output size being one byte too short => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len, LEN-1); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to Output Size being one byte too short"); // Test decoding with input size being one byte too short => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len-1, LEN); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being one byte too short"); // Test decoding with input size being one byte too large => must fail FUZ_DISPLAYTEST; ret = LZ4_decompress_safe((char*)&cbuf[off_full], (char*)testOut, len+1, LEN); FUZ_CHECKTEST(ret>=0, "LZ4_decompress_safe should have failed, due to input size being too large"); //if (ret>=0) { printf("Test 10 : decompression should have failed, due to input size being too large : seed %u, len %d\n", seed, LEN); goto _output_error; } // Test partial decoding with target output size being max/2 => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe_partial((char*)&cbuf[off_full], (char*)testOut, len, LEN/2, LEN); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space"); // Test partial decoding with target output size being just below max => must work FUZ_DISPLAYTEST; ret = LZ4_decompress_safe_partial((char*)&cbuf[off_full], (char*)testOut, len, LEN-3, LEN); FUZ_CHECKTEST(ret<0, "LZ4_decompress_safe_partial failed despite sufficient space"); // Test compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, len); FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput() failed despite sufficient space"); FUZ_CHECKTEST(!test_canary(&cbuf[FUZ_avail]), "compression overran output buffer"); // Test compression with output size being exactly what's necessary and external state (should work) FUZ_DISPLAYTEST; // 2 ret = LZ4_compress_limitedOutput_withState(stateLZ4, (const char*)buf, (char*)&cbuf[off_full], LEN, len); FUZ_CHECKTEST(ret==0, "LZ4_compress_limitedOutput_withState() failed despite sufficient space"); FUZ_CHECKTEST(!test_canary(&cbuf[FUZ_avail]), "compression overran output buffer"); // Test HC compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, lenHC); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput() failed despite sufficient space"); // Test HC compression with output size being exactly what's necessary (should work) FUZ_DISPLAYTEST; ret = LZ4_compressHC_limitedOutput_withStateHC(stateLZ4HC, (const char*)buf, (char*)&cbuf[FUZ_avail-len], LEN, lenHC); FUZ_CHECKTEST(ret==0, "LZ4_compressHC_limitedOutput_withStateHC() failed despite sufficient space"); // Test compression with just one missing byte into output buffer => must fail FUZ_DISPLAYTEST; ret = LZ4_compress_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, len-1); FUZ_CHECKTEST(ret, "compression overran output buffer"); FUZ_CHECKTEST(!test_canary(&cbuf[FUZ_avail]), "compression overran output buffer"); // Test HC compression with just one missing byte into output buffer => must fail FUZ_DISPLAYTEST; ret = LZ4_compressHC_limitedOutput((const char*)buf, (char*)&cbuf[FUZ_avail-(len-1)], LEN, lenHC-1); FUZ_CHECKTEST(ret, "HC compression overran output buffer"); bytes += LEN; cbytes += len; hcbytes += lenHC; FUZ_rand(&randState); } printf("all tests completed successfully \n"); printf("compression ratio: %0.3f%%\n", (double)cbytes/bytes*100); printf("HC compression ratio: %0.3f%%\n", (double)hcbytes/bytes*100); getchar(); return 0; _output_error: getchar(); return 1; } lz4-0.0~r114/programs/lz4.1000066400000000000000000000032471231007221700153160ustar00rootroot00000000000000\" \" lz4.1: This is a manual page for 'lz4' program. This file is part of the \" lz4 project. \" \" No hyphenation .hy 0 .nr HY 0 .TH lz4 "1" "2014-02-27" "lz4" "User Commands" .SH NAME \fBlz4\fR - Extremely fast compression algorithm .SH SYNOPSIS .TP 5 \fBlz4\fR [\fBOPTIONS\fR] [-|INPUT-FILE] .SH DESCRIPTION .PP \fBlz4\fR is an extremely fast lossless compression algorithm. It is based on the \fBLZ77\fR family of compression scheme. At the compression speed of 400 MB/s per core, \fBlz4\fR is also scalable with multi-core CPUs. It features an extremely fast decoder, with speed in multiple GB/s per core, typically reaching the RAM speed limits on multi-core systems. \fBlz4\fR supports following options .SH OPTIONS .TP .B \-1 fast compression (default) .TP .B \-9 high compression .TP .B \-d decompression .TP .B \-f overwrite output without prompting .TP .B \-h/\-H display help/long help and exit .TP .B \-V display Version number and exit .TP .B \-v verbose mode .TP .B \-q suppress warnings; specify twice to suppress errors too .TP .B \-c force write to standard output, even if it is the console .TP .B \-t test compressed file integrity .TP .B \-z force compression .TP .B \-l use Legacy format (useful for Linux Kernel compression) .TP .B \-B# block size [4-7](default : 7) .TP .B \-BD block dependency (improve compression ratio) .TP .B \-BX enable block checksum (default:disabled) .TP .B \-Sx disable stream checksum (default:enabled) .TP .B \-b benchmark file(s) .TP .B \-i# iteration loops [1-9](default : 3), benchmark mode only .SH BUGS Report bugs at:- https://code.google.com/p/lz4/ .SH AUTHOR Yann Colletlz4-0.0~r114/programs/lz4cli.c000066400000000000000000000472211231007221700160700ustar00rootroot00000000000000/* LZ4cli.c - LZ4 Command Line Interface Copyright (C) Yann Collet 2011-2013 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4/ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /* Note : this is stand-alone program. It is not part of LZ4 compression library, it is a user program of the LZ4 library. The license of LZ4 library is BSD. The license of xxHash library is BSD. The license of this compression CLI program is GPLv2. */ //************************************** // Tuning parameters //************************************** // DISABLE_LZ4C_LEGACY_OPTIONS : // Control the availability of -c0, -c1 and -hc legacy arguments // Default : Legacy options are enabled // #define DISABLE_LZ4C_LEGACY_OPTIONS //************************************** // Compiler Options //************************************** // Disable some Visual warning messages #ifdef _MSC_VER // Visual Studio # define _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_DEPRECATE // VS2005 # pragma warning(disable : 4127) // disable: C4127: conditional expression is constant #endif #define _FILE_OFFSET_BITS 64 // Large file support on 32-bits unix #define _POSIX_SOURCE 1 // for fileno() within on unix //**************************** // Includes //**************************** #include // fprintf, fopen, fread, _fileno, stdin, stdout #include // malloc #include // strcmp, strlen #include // clock #include "lz4.h" #include "lz4hc.h" #include "xxhash.h" #include "bench.h" #include "lz4io.h" //**************************** // OS-specific Includes //**************************** #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include // _O_BINARY # include // _setmode, _isatty # ifdef __MINGW32__ int _fileno(FILE *stream); // MINGW somehow forgets to include this windows declaration into # endif # define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) #else # include // isatty # define SET_BINARY_MODE(file) # define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #endif //************************************** // Compiler-specific functions //************************************** #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #if defined(_MSC_VER) // Visual Studio # define swap32 _byteswap_ulong #elif GCC_VERSION >= 403 # define swap32 __builtin_bswap32 #else static inline unsigned int swap32(unsigned int x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00 ) | ((x >> 24) & 0x000000ff ); } #endif //**************************** // Constants //**************************** #define COMPRESSOR_NAME "LZ4 Compression CLI" #ifndef LZ4_VERSION # define LZ4_VERSION "v1.1.3" #endif #define AUTHOR "Yann Collet" #define WELCOME_MESSAGE "*** %s %i-bits %s, by %s (%s) ***\n", COMPRESSOR_NAME, (int)(sizeof(void*)*8), LZ4_VERSION, AUTHOR, __DATE__ #define LZ4_EXTENSION ".lz4" #define KB *(1U<<10) #define MB *(1U<<20) #define GB *(1U<<30) #define LZ4_BLOCKSIZEID_DEFAULT 7 //************************************** // Architecture Macros //************************************** static const int one = 1; #define CPU_LITTLE_ENDIAN (*(char*)(&one)) #define CPU_BIG_ENDIAN (!CPU_LITTLE_ENDIAN) #define LITTLE_ENDIAN_32(i) (CPU_LITTLE_ENDIAN?(i):swap32(i)) //************************************** // Macros //************************************** #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } //************************************** // Local Parameters //************************************** static char* programName; static int displayLevel = 2; // 0 : no display // 1: errors // 2 : + result + interaction + warnings ; // 3 : + progression; // 4 : + information //************************************** // Exceptions //************************************** #define DEBUG 0 #define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__); #define EXM_THROW(error, ...) \ { \ DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \ DISPLAYLEVEL(1, "Error %i : ", error); \ DISPLAYLEVEL(1, __VA_ARGS__); \ DISPLAYLEVEL(1, "\n"); \ exit(error); \ } //************************************** // Version modifiers //************************************** #define EXTENDED_ARGUMENTS #define EXTENDED_HELP #define EXTENDED_FORMAT #define DEFAULT_COMPRESSOR LZ4IO_compressFilename #define DEFAULT_DECOMPRESSOR LZ4IO_decompressFilename int LZ4IO_compressFilename_Legacy(char* input_filename, char* output_filename, int compressionlevel); //**************************** // Functions //**************************** int usage() { DISPLAY( "Usage :\n"); DISPLAY( " %s [arg] [input] [output]\n", programName); DISPLAY( "\n"); DISPLAY( "input : a filename\n"); DISPLAY( " with no FILE, or when FILE is - or %s, read standard input\n", stdinmark); DISPLAY( "Arguments :\n"); DISPLAY( " -1 : Fast compression (default) \n"); DISPLAY( " -9 : High compression \n"); DISPLAY( " -d : decompression (default for %s extension)\n", LZ4_EXTENSION); DISPLAY( " -z : force compression\n"); DISPLAY( " -f : overwrite output without prompting \n"); DISPLAY( " -h/-H : display help/long help and exit\n"); return 0; } int usage_advanced() { DISPLAY(WELCOME_MESSAGE); usage(); DISPLAY( "\n"); DISPLAY( "Advanced arguments :\n"); DISPLAY( " -V : display Version number and exit\n"); DISPLAY( " -v : verbose mode\n"); DISPLAY( " -q : suppress warnings; specify twice to suppress errors too\n"); DISPLAY( " -c : force write to standard output, even if it is the console\n"); DISPLAY( " -t : test compressed file integrity\n"); DISPLAY( " -l : compress using Legacy format (Linux kernel compression)\n"); DISPLAY( " -B# : Block size [4-7](default : 7)\n"); DISPLAY( " -BD : Block dependency (improve compression ratio)\n"); DISPLAY( " -BX : enable block checksum (default:disabled)\n"); DISPLAY( " -Sx : disable stream checksum (default:enabled)\n"); DISPLAY( "Benchmark arguments :\n"); DISPLAY( " -b : benchmark file(s)\n"); DISPLAY( " -i# : iteration loops [1-9](default : 3), benchmark mode only\n"); #if !defined(DISABLE_LZ4C_LEGACY_OPTIONS) DISPLAY( "Legacy arguments :\n"); DISPLAY( " -c0 : fast compression\n"); DISPLAY( " -c1 : high compression\n"); DISPLAY( " -hc : high compression\n"); DISPLAY( " -y : overwrite output without prompting \n"); DISPLAY( " -s : suppress warnings \n"); #endif // DISABLE_LZ4C_LEGACY_OPTIONS EXTENDED_HELP; return 0; } int usage_longhelp() { DISPLAY( "\n"); DISPLAY( "Which values can get [output] ? \n"); DISPLAY( "[output] : a filename\n"); DISPLAY( " '%s', or '-' for standard output (pipe mode)\n", stdoutmark); DISPLAY( " '%s' to discard output (test mode)\n", NULL_OUTPUT); DISPLAY( "[output] can be left empty. In this case, it receives the following value : \n"); DISPLAY( " - if stdout is not the console, then [output] = stdout \n"); DISPLAY( " - if stdout is console : \n"); DISPLAY( " + if compression selected, output to filename%s \n", LZ4_EXTENSION); DISPLAY( " + if decompression selected, output to filename without '%s'\n", LZ4_EXTENSION); DISPLAY( " > if input filename has no '%s' extension : error\n", LZ4_EXTENSION); DISPLAY( "\n"); DISPLAY( "Compression levels : \n"); DISPLAY( "There are technically 2 accessible compression levels.\n"); DISPLAY( "-0 ... -2 => Fast compression\n"); DISPLAY( "-3 ... -9 => High compression\n"); DISPLAY( "\n"); DISPLAY( "stdin, stdout and the console : \n"); DISPLAY( "To protect the console from binary flooding (bad argument mistake)\n"); DISPLAY( "%s will refuse to read from console, or write to console \n", programName); DISPLAY( "except if '-c' command is specified, to force output to console \n"); DISPLAY( "\n"); DISPLAY( "Simple example :\n"); DISPLAY( "1 : compress 'filename' fast, using default output name 'filename.lz4'\n"); DISPLAY( " %s filename\n", programName); DISPLAY( "\n"); DISPLAY( "Arguments can be appended together, or provided independently. For example :\n"); DISPLAY( "2 : compress 'filename' in high compression mode, overwrite output if exists\n"); DISPLAY( " %s -f9 filename \n", programName); DISPLAY( " is equivalent to :\n"); DISPLAY( " %s -f -9 filename \n", programName); DISPLAY( "\n"); DISPLAY( "%s can be used in 'pure pipe mode', for example :\n", programName); DISPLAY( "3 : compress data stream from 'generator', send result to 'consumer'\n"); DISPLAY( " generator | %s | consumer \n", programName); #if !defined(DISABLE_LZ4C_LEGACY_OPTIONS) DISPLAY( "\n"); DISPLAY( "Warning :\n"); DISPLAY( "Legacy arguments take precedence. Therefore : \n"); DISPLAY( " %s -hc filename\n", programName); DISPLAY( "means 'compress filename in high compression mode'\n"); DISPLAY( "It is not equivalent to :\n"); DISPLAY( " %s -h -c filename\n", programName); DISPLAY( "which would display help text and exit\n"); #endif // DISABLE_LZ4C_LEGACY_OPTIONS return 0; } int badusage() { DISPLAYLEVEL(1, "Incorrect parameters\n"); if (displayLevel >= 1) usage(); exit(1); } void waitEnter() { DISPLAY("Press enter to continue...\n"); getchar(); } int main(int argc, char** argv) { int i, cLevel=0, decode=0, bench=0, filenamesStart=2, legacy_format=0, forceStdout=0, forceCompress=0, pause=0; char* input_filename=0; char* output_filename=0; char* dynNameSpace=0; char nullOutput[] = NULL_OUTPUT; char extension[] = LZ4_EXTENSION; int blockSize; // Init programName = argv[0]; LZ4IO_setOverwrite(0); blockSize = LZ4IO_setBlockSizeID(LZ4_BLOCKSIZEID_DEFAULT); for(i=1; i='1') && (argument[1] <='9')) { int iters = argument[1] - '0'; BMK_SetNbIterations(iters); argument++; } break; // Pause at the end (hidden option) case 'p': pause=1; BMK_SetPause(); break; EXTENDED_ARGUMENTS; // Unrecognised command default : badusage(); } } continue; } // first provided filename is input if (!input_filename) { input_filename=argument; filenamesStart=i; continue; } // second provided filename is output if (!output_filename) { output_filename=argument; if (!strcmp (output_filename, nullOutput)) output_filename = nulmark; continue; } } DISPLAYLEVEL(3, WELCOME_MESSAGE); DISPLAYLEVEL(4, "Blocks size : %i KB\n", blockSize>>10); // No input filename ==> use stdin if(!input_filename) { input_filename=stdinmark; } // Check if input or output are defined as console; trigger an error in this case if (!strcmp(input_filename, stdinmark) && IS_CONSOLE(stdin) ) badusage(); // Check if benchmark is selected if (bench) return BMK_benchFile(argv+filenamesStart, argc-filenamesStart, cLevel); // No output filename ==> try to select one automatically (when possible) while (!output_filename) { if (!IS_CONSOLE(stdout)) { output_filename=stdoutmark; break; } // Default to stdout whenever possible (i.e. not a console) if ((!decode) && !(forceCompress)) // auto-determine compression or decompression, based on file extension { size_t l = strlen(input_filename); if (!strcmp(input_filename+(l-4), LZ4_EXTENSION)) decode=1; } if (!decode) // compression to file { size_t l = strlen(input_filename); dynNameSpace = (char*)calloc(1,l+5); output_filename = dynNameSpace; strcpy(output_filename, input_filename); strcpy(output_filename+l, LZ4_EXTENSION); DISPLAYLEVEL(2, "Compressed filename will be : %s \n", output_filename); break; } // decompression to file (automatic name will work only if input filename has correct format extension) { size_t outl; size_t inl = strlen(input_filename); dynNameSpace = (char*)calloc(1,inl+1); output_filename = dynNameSpace; strcpy(output_filename, input_filename); outl = inl; if (inl>4) while ((outl >= inl-4) && (input_filename[outl] == extension[outl-inl+4])) output_filename[outl--]=0; if (outl != inl-5) { DISPLAYLEVEL(1, "Cannot determine an output filename\n"); badusage(); } DISPLAYLEVEL(2, "Decoding file %s \n", output_filename); } } // No warning message in pure pipe mode (stdin + stdout) if (!strcmp(input_filename, stdinmark) && !strcmp(output_filename,stdoutmark) && (displayLevel==2)) displayLevel=1; // Check if input or output are defined as console; trigger an error in this case if (!strcmp(input_filename, stdinmark) && IS_CONSOLE(stdin) ) badusage(); if (!strcmp(output_filename,stdoutmark) && IS_CONSOLE(stdout) && !forceStdout) badusage(); // IO Stream/File LZ4IO_setNotificationLevel(displayLevel); if (decode) DEFAULT_DECOMPRESSOR(input_filename, output_filename); else // compression is default action { if (legacy_format) { DISPLAYLEVEL(3, "! Generating compressed LZ4 using Legacy format (deprecated !) ! \n"); LZ4IO_compressFilename_Legacy(input_filename, output_filename, cLevel); } else { DEFAULT_COMPRESSOR(input_filename, output_filename, cLevel); } } if (pause) waitEnter(); free(dynNameSpace); return 0; } lz4-0.0~r114/programs/lz4io.c000066400000000000000000001047301231007221700157270ustar00rootroot00000000000000/* LZ4io.c - LZ4 File/Stream Interface Copyright (C) Yann Collet 2011-2013 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4/ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /* Note : this is stand-alone program. It is not part of LZ4 compression library, it is a user code of the LZ4 library. - The license of LZ4 library is BSD. - The license of xxHash library is BSD. - The license of this source file is GPLv2. */ //************************************** // Compiler Options //************************************** #ifdef _MSC_VER /* Visual Studio */ # define FORCE_INLINE static __forceinline # define _CRT_SECURE_NO_WARNINGS # define _CRT_SECURE_NO_DEPRECATE // VS2005 # pragma warning(disable : 4127) // disable: C4127: conditional expression is constant #else # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif #endif #define _FILE_OFFSET_BITS 64 // Large file support on 32-bits unix #define _POSIX_SOURCE 1 // for fileno() within on unix //**************************** // Includes //**************************** #include // fprintf, fopen, fread, _fileno, stdin, stdout #include // malloc #include // strcmp, strlen #include // clock #include "lz4io.h" #include "lz4.h" #include "lz4hc.h" #include "xxhash.h" //**************************** // OS-specific Includes //**************************** #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) # include // _O_BINARY # include // _setmode, _isatty # ifdef __MINGW32__ int _fileno(FILE *stream); // MINGW somehow forgets to include this windows declaration into # endif # define SET_BINARY_MODE(file) _setmode(_fileno(file), _O_BINARY) # define IS_CONSOLE(stdStream) _isatty(_fileno(stdStream)) #else # include // isatty # define SET_BINARY_MODE(file) # define IS_CONSOLE(stdStream) isatty(fileno(stdStream)) #endif //************************************** // Compiler-specific functions //************************************** #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #if defined(_MSC_VER) // Visual Studio # define swap32 _byteswap_ulong #elif GCC_VERSION >= 403 # define swap32 __builtin_bswap32 #else static inline unsigned int swap32(unsigned int x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00 ) | ((x >> 24) & 0x000000ff ); } #endif //**************************** // Constants //**************************** #define KB *(1U<<10) #define MB *(1U<<20) #define GB *(1U<<30) #define _1BIT 0x01 #define _2BITS 0x03 #define _3BITS 0x07 #define _4BITS 0x0F #define _8BITS 0xFF #define MAGICNUMBER_SIZE 4 #define LZ4S_MAGICNUMBER 0x184D2204 #define LZ4S_SKIPPABLE0 0x184D2A50 #define LZ4S_SKIPPABLEMASK 0xFFFFFFF0 #define LEGACY_MAGICNUMBER 0x184C2102 #define CACHELINE 64 #define LEGACY_BLOCKSIZE (8 MB) #define MIN_STREAM_BUFSIZE (1 MB + 64 KB) #define LZ4S_BLOCKSIZEID_DEFAULT 7 #define LZ4S_CHECKSUM_SEED 0 #define LZ4S_EOS 0 #define LZ4S_MAXHEADERSIZE (MAGICNUMBER_SIZE+2+8+4+1) //************************************** // Architecture Macros //************************************** static const int one = 1; #define CPU_LITTLE_ENDIAN (*(char*)(&one)) #define CPU_BIG_ENDIAN (!CPU_LITTLE_ENDIAN) #define LITTLE_ENDIAN_32(i) (CPU_LITTLE_ENDIAN?(i):swap32(i)) //************************************** // Macros //************************************** #define DISPLAY(...) fprintf(stderr, __VA_ARGS__) #define DISPLAYLEVEL(l, ...) if (displayLevel>=l) { DISPLAY(__VA_ARGS__); } //************************************** // Local Parameters //************************************** static int displayLevel = 0; // 0 : no display // 1: errors // 2 : + result + interaction + warnings ; // 3 : + progression; // 4 : + information static int overwrite = 1; static int blockSizeId = LZ4S_BLOCKSIZEID_DEFAULT; static int blockChecksum = 0; static int streamChecksum = 1; static int blockIndependence = 1; static const int minBlockSizeID = 4; static const int maxBlockSizeID = 7; //************************************** // Exceptions //************************************** #define DEBUG 0 #define DEBUGOUTPUT(...) if (DEBUG) DISPLAY(__VA_ARGS__); #define EXM_THROW(error, ...) \ { \ DEBUGOUTPUT("Error defined at %s, line %i : \n", __FILE__, __LINE__); \ DISPLAYLEVEL(1, "Error %i : ", error); \ DISPLAYLEVEL(1, __VA_ARGS__); \ DISPLAYLEVEL(1, "\n"); \ exit(error); \ } //************************************** // Version modifiers //************************************** #define EXTENDED_ARGUMENTS #define EXTENDED_HELP #define EXTENDED_FORMAT #define DEFAULT_COMPRESSOR compress_file #define DEFAULT_DECOMPRESSOR decodeLZ4S /* ************************************************** */ /* ****************** Parameters ******************** */ /* ************************************************** */ /* Default setting : overwrite = 1; return : overwrite mode (0/1) */ int LZ4IO_setOverwrite(int yes) { overwrite = (yes!=0); return overwrite; } /* blockSizeID : valid values : 4-5-6-7 */ int LZ4IO_setBlockSizeID(int bsid) { static const int blockSizeTable[] = { 64 KB, 256 KB, 1 MB, 4 MB }; if ((bsid < minBlockSizeID) || (bsid > maxBlockSizeID)) return -1; blockSizeId = bsid; return blockSizeTable[blockSizeId-minBlockSizeID]; } int LZ4IO_setBlockMode(blockMode_t blockMode) { blockIndependence = (blockMode == independentBlocks); return blockIndependence; } /* Default setting : no checksum */ int LZ4IO_setBlockChecksumMode(int xxhash) { blockChecksum = (xxhash != 0); return blockChecksum; } /* Default setting : checksum enabled */ int LZ4IO_setStreamChecksumMode(int xxhash) { streamChecksum = (xxhash != 0); return streamChecksum; } /* Default setting : 0 (no notification) */ int LZ4IO_setNotificationLevel(int level) { displayLevel = level; return displayLevel; } /* ************************************************************************ */ /* ********************** LZ4 File / Stream compression ******************* */ /* ************************************************************************ */ static int LZ4S_GetBlockSize_FromBlockId (int id) { return (1 << (8 + (2 * id))); } static unsigned int LZ4S_GetCheckBits_FromXXH (unsigned int xxh) { return (xxh >> 8) & _8BITS; } static int LZ4S_isSkippableMagicNumber(unsigned int magic) { return (magic & LZ4S_SKIPPABLEMASK) == LZ4S_SKIPPABLE0; } static int get_fileHandle(char* input_filename, char* output_filename, FILE** pfinput, FILE** pfoutput) { if (!strcmp (input_filename, stdinmark)) { DISPLAYLEVEL(4,"Using stdin for input\n"); *pfinput = stdin; SET_BINARY_MODE(stdin); } else { *pfinput = fopen(input_filename, "rb"); } if (!strcmp (output_filename, stdoutmark)) { DISPLAYLEVEL(4,"Using stdout for output\n"); *pfoutput = stdout; SET_BINARY_MODE(stdout); } else { // Check if destination file already exists *pfoutput=0; if (output_filename != nulmark) *pfoutput = fopen( output_filename, "rb" ); if (*pfoutput!=0) { fclose(*pfoutput); if (!overwrite) { char ch; DISPLAYLEVEL(2, "Warning : %s already exists\n", output_filename); DISPLAYLEVEL(2, "Overwrite ? (Y/N) : "); if (displayLevel <= 1) EXM_THROW(11, "Operation aborted : %s already exists", output_filename); // No interaction possible ch = (char)getchar(); if ((ch!='Y') && (ch!='y')) EXM_THROW(11, "Operation aborted : %s already exists", output_filename); } } *pfoutput = fopen( output_filename, "wb" ); } if ( *pfinput==0 ) EXM_THROW(12, "Pb opening %s", input_filename); if ( *pfoutput==0) EXM_THROW(13, "Pb opening %s", output_filename); return 0; } // LZ4IO_compressFilename_Legacy : This function is "hidden" (not published in .h) // Its purpose is to generate compressed streams using the old 'legacy' format int LZ4IO_compressFilename_Legacy(char* input_filename, char* output_filename, int compressionlevel) { int (*compressionFunction)(const char*, char*, int); unsigned long long filesize = 0; unsigned long long compressedfilesize = MAGICNUMBER_SIZE; char* in_buff; char* out_buff; FILE* finput; FILE* foutput; int displayLevel = (compressionlevel>0); clock_t start, end; size_t sizeCheck; // Init if (compressionlevel < 3) compressionFunction = LZ4_compress; else compressionFunction = LZ4_compressHC; start = clock(); get_fileHandle(input_filename, output_filename, &finput, &foutput); if ((displayLevel==2) && (compressionlevel==1)) displayLevel=3; // Allocate Memory in_buff = (char*)malloc(LEGACY_BLOCKSIZE); out_buff = (char*)malloc(LZ4_compressBound(LEGACY_BLOCKSIZE)); if (!in_buff || !out_buff) EXM_THROW(21, "Allocation error : not enough memory"); // Write Archive Header *(unsigned int*)out_buff = LITTLE_ENDIAN_32(LEGACY_MAGICNUMBER); sizeCheck = fwrite(out_buff, 1, MAGICNUMBER_SIZE, foutput); if (sizeCheck!=MAGICNUMBER_SIZE) EXM_THROW(22, "Write error : cannot write header"); // Main Loop while (1) { unsigned int outSize; // Read Block int inSize = (int) fread(in_buff, (size_t)1, (size_t)LEGACY_BLOCKSIZE, finput); if( inSize<=0 ) break; filesize += inSize; DISPLAYLEVEL(3, "\rRead : %i MB ", (int)(filesize>>20)); // Compress Block outSize = compressionFunction(in_buff, out_buff+4, inSize); compressedfilesize += outSize+4; DISPLAYLEVEL(3, "\rRead : %i MB ==> %.2f%% ", (int)(filesize>>20), (double)compressedfilesize/filesize*100); // Write Block * (unsigned int*) out_buff = LITTLE_ENDIAN_32(outSize); sizeCheck = fwrite(out_buff, 1, outSize+4, foutput); if (sizeCheck!=(size_t)(outSize+4)) EXM_THROW(23, "Write error : cannot write compressed block"); } // Status end = clock(); DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2,"Compressed %llu bytes into %llu bytes ==> %.2f%%\n", (unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100); { double seconds = (double)(end - start)/CLOCKS_PER_SEC; DISPLAYLEVEL(4,"Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024); } // Close & Free free(in_buff); free(out_buff); fclose(finput); fclose(foutput); return 0; } static int compress_file_blockDependency(char* input_filename, char* output_filename, int compressionlevel) { void* (*initFunction) (const char*); int (*compressionFunction)(void*, const char*, char*, int, int); char* (*translateFunction) (void*); int (*freeFunction) (void*); void* ctx; unsigned long long filesize = 0; unsigned long long compressedfilesize = 0; unsigned int checkbits; char* in_buff, *in_start, *in_end; char* out_buff; FILE* finput; FILE* foutput; clock_t start, end; unsigned int blockSize, inputBufferSize; size_t sizeCheck, header_size; void* streamChecksumState=NULL; // Init start = clock(); if ((displayLevel==2) && (compressionlevel>=3)) displayLevel=3; if (compressionlevel>=3) { initFunction = LZ4_createHC; compressionFunction = LZ4_compressHC_limitedOutput_continue; translateFunction = LZ4_slideInputBufferHC; freeFunction = LZ4_freeHC; } else { initFunction = LZ4_create; compressionFunction = LZ4_compress_limitedOutput_continue; translateFunction = LZ4_slideInputBuffer; freeFunction = LZ4_free; } get_fileHandle(input_filename, output_filename, &finput, &foutput); blockSize = LZ4S_GetBlockSize_FromBlockId (blockSizeId); // Allocate Memory inputBufferSize = blockSize + 64 KB; if (inputBufferSize < MIN_STREAM_BUFSIZE) inputBufferSize = MIN_STREAM_BUFSIZE; in_buff = (char*)malloc(inputBufferSize); out_buff = (char*)malloc(blockSize+CACHELINE); if (!in_buff || !out_buff) EXM_THROW(31, "Allocation error : not enough memory"); in_start = in_buff; in_end = in_buff + inputBufferSize; if (streamChecksum) streamChecksumState = XXH32_init(LZ4S_CHECKSUM_SEED); ctx = initFunction(in_buff); // Write Archive Header *(unsigned int*)out_buff = LITTLE_ENDIAN_32(LZ4S_MAGICNUMBER); // Magic Number, in Little Endian convention *(out_buff+4) = (1 & _2BITS) << 6 ; // Version('01') *(out_buff+4) |= (blockIndependence & _1BIT) << 5; *(out_buff+4) |= (blockChecksum & _1BIT) << 4; *(out_buff+4) |= (streamChecksum & _1BIT) << 2; *(out_buff+5) = (char)((blockSizeId & _3BITS) << 4); checkbits = XXH32((out_buff+4), 2, LZ4S_CHECKSUM_SEED); checkbits = LZ4S_GetCheckBits_FromXXH(checkbits); *(out_buff+6) = (unsigned char) checkbits; header_size = 7; sizeCheck = fwrite(out_buff, 1, header_size, foutput); if (sizeCheck!=header_size) EXM_THROW(32, "Write error : cannot write header"); compressedfilesize += header_size; // Main Loop while (1) { unsigned int outSize; unsigned int inSize; // Read Block if ((in_start+blockSize) > in_end) in_start = translateFunction(ctx); inSize = (unsigned int) fread(in_start, (size_t)1, (size_t)blockSize, finput); if( inSize==0 ) break; // No more input : end of compression filesize += inSize; DISPLAYLEVEL(3, "\rRead : %i MB ", (int)(filesize>>20)); if (streamChecksum) XXH32_update(streamChecksumState, in_start, inSize); // Compress Block outSize = compressionFunction(ctx, in_start, out_buff+4, inSize, inSize-1); if (outSize > 0) compressedfilesize += outSize+4; else compressedfilesize += inSize+4; if (blockChecksum) compressedfilesize+=4; DISPLAYLEVEL(3, "\rRead : %i MB ==> %.2f%% ", (int)(filesize>>20), (double)compressedfilesize/filesize*100); // Write Block if (outSize > 0) { int sizeToWrite; * (unsigned int*) out_buff = LITTLE_ENDIAN_32(outSize); if (blockChecksum) { unsigned int checksum = XXH32(out_buff+4, outSize, LZ4S_CHECKSUM_SEED); * (unsigned int*) (out_buff+4+outSize) = LITTLE_ENDIAN_32(checksum); } sizeToWrite = 4 + outSize + (4*blockChecksum); sizeCheck = fwrite(out_buff, 1, sizeToWrite, foutput); if (sizeCheck!=(size_t)(sizeToWrite)) EXM_THROW(33, "Write error : cannot write compressed block"); } else // Copy Original { * (unsigned int*) out_buff = LITTLE_ENDIAN_32(inSize|0x80000000); // Add Uncompressed flag sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(34, "Write error : cannot write block header"); sizeCheck = fwrite(in_start, 1, inSize, foutput); if (sizeCheck!=(size_t)(inSize)) EXM_THROW(35, "Write error : cannot write block"); if (blockChecksum) { unsigned int checksum = XXH32(in_start, inSize, LZ4S_CHECKSUM_SEED); * (unsigned int*) out_buff = LITTLE_ENDIAN_32(checksum); sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(36, "Write error : cannot write block checksum"); } } in_start += inSize; } // End of Stream mark * (unsigned int*) out_buff = LZ4S_EOS; sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(37, "Write error : cannot write end of stream"); compressedfilesize += 4; if (streamChecksum) { unsigned int checksum = XXH32_digest(streamChecksumState); * (unsigned int*) out_buff = LITTLE_ENDIAN_32(checksum); sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(37, "Write error : cannot write stream checksum"); compressedfilesize += 4; } // Status end = clock(); DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "Compressed %llu bytes into %llu bytes ==> %.2f%%\n", (unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100); { double seconds = (double)(end - start)/CLOCKS_PER_SEC; DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024); } // Close & Free freeFunction(ctx); free(in_buff); free(out_buff); fclose(finput); fclose(foutput); return 0; } FORCE_INLINE int LZ4_compress_limitedOutput_local(const char* src, char* dst, int size, int maxOut, int clevel) { (void)clevel; return LZ4_compress_limitedOutput(src, dst, size, maxOut); } int LZ4IO_compressFilename(char* input_filename, char* output_filename, int compressionLevel) { int (*compressionFunction)(const char*, char*, int, int, int); unsigned long long filesize = 0; unsigned long long compressedfilesize = 0; unsigned int checkbits; char* in_buff; char* out_buff; char* headerBuffer; FILE* finput; FILE* foutput; clock_t start, end; int blockSize; size_t sizeCheck, header_size, readSize; void* streamChecksumState=NULL; // Branch out if (blockIndependence==0) return compress_file_blockDependency(input_filename, output_filename, compressionLevel); // Init start = clock(); if ((displayLevel==2) && (compressionLevel>=3)) displayLevel=3; if (compressionLevel <= 3) compressionFunction = LZ4_compress_limitedOutput_local; else { compressionFunction = LZ4_compressHC2_limitedOutput; } get_fileHandle(input_filename, output_filename, &finput, &foutput); blockSize = LZ4S_GetBlockSize_FromBlockId (blockSizeId); // Allocate Memory in_buff = (char*)malloc(blockSize); out_buff = (char*)malloc(blockSize+CACHELINE); headerBuffer = (char*)malloc(LZ4S_MAXHEADERSIZE); if (!in_buff || !out_buff || !(headerBuffer)) EXM_THROW(31, "Allocation error : not enough memory"); if (streamChecksum) streamChecksumState = XXH32_init(LZ4S_CHECKSUM_SEED); // Write Archive Header *(unsigned int*)headerBuffer = LITTLE_ENDIAN_32(LZ4S_MAGICNUMBER); // Magic Number, in Little Endian convention *(headerBuffer+4) = (1 & _2BITS) << 6 ; // Version('01') *(headerBuffer+4) |= (blockIndependence & _1BIT) << 5; *(headerBuffer+4) |= (blockChecksum & _1BIT) << 4; *(headerBuffer+4) |= (streamChecksum & _1BIT) << 2; *(headerBuffer+5) = (char)((blockSizeId & _3BITS) << 4); checkbits = XXH32((headerBuffer+4), 2, LZ4S_CHECKSUM_SEED); checkbits = LZ4S_GetCheckBits_FromXXH(checkbits); *(headerBuffer+6) = (unsigned char) checkbits; header_size = 7; // Write header sizeCheck = fwrite(headerBuffer, 1, header_size, foutput); if (sizeCheck!=header_size) EXM_THROW(32, "Write error : cannot write header"); compressedfilesize += header_size; // read first block readSize = fread(in_buff, (size_t)1, (size_t)blockSize, finput); // Main Loop while (readSize>0) { unsigned int outSize; filesize += readSize; DISPLAYLEVEL(3, "\rRead : %i MB ", (int)(filesize>>20)); if (streamChecksum) XXH32_update(streamChecksumState, in_buff, (int)readSize); // Compress Block outSize = compressionFunction(in_buff, out_buff+4, (int)readSize, (int)readSize-1, compressionLevel); if (outSize > 0) compressedfilesize += outSize+4; else compressedfilesize += readSize+4; if (blockChecksum) compressedfilesize+=4; DISPLAYLEVEL(3, "\rRead : %i MB ==> %.2f%% ", (int)(filesize>>20), (double)compressedfilesize/filesize*100); // Write Block if (outSize > 0) { int sizeToWrite; * (unsigned int*) out_buff = LITTLE_ENDIAN_32(outSize); if (blockChecksum) { unsigned int checksum = XXH32(out_buff+4, outSize, LZ4S_CHECKSUM_SEED); * (unsigned int*) (out_buff+4+outSize) = LITTLE_ENDIAN_32(checksum); } sizeToWrite = 4 + outSize + (4*blockChecksum); sizeCheck = fwrite(out_buff, 1, sizeToWrite, foutput); if (sizeCheck!=(size_t)(sizeToWrite)) EXM_THROW(33, "Write error : cannot write compressed block"); } else // Copy Original Uncompressed { * (unsigned int*) out_buff = LITTLE_ENDIAN_32(((unsigned long)readSize)|0x80000000); // Add Uncompressed flag sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(34, "Write error : cannot write block header"); sizeCheck = fwrite(in_buff, 1, readSize, foutput); if (sizeCheck!=readSize) EXM_THROW(35, "Write error : cannot write block"); if (blockChecksum) { unsigned int checksum = XXH32(in_buff, (int)readSize, LZ4S_CHECKSUM_SEED); * (unsigned int*) out_buff = LITTLE_ENDIAN_32(checksum); sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(36, "Write error : cannot write block checksum"); } } // Read next block readSize = fread(in_buff, (size_t)1, (size_t)blockSize, finput); } // End of Stream mark * (unsigned int*) out_buff = LZ4S_EOS; sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(37, "Write error : cannot write end of stream"); compressedfilesize += 4; if (streamChecksum) { unsigned int checksum = XXH32_digest(streamChecksumState); * (unsigned int*) out_buff = LITTLE_ENDIAN_32(checksum); sizeCheck = fwrite(out_buff, 1, 4, foutput); if (sizeCheck!=(size_t)(4)) EXM_THROW(37, "Write error : cannot write stream checksum"); compressedfilesize += 4; } // Close & Free free(in_buff); free(out_buff); free(headerBuffer); fclose(finput); fclose(foutput); // Final Status end = clock(); DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "Compressed %llu bytes into %llu bytes ==> %.2f%%\n", (unsigned long long) filesize, (unsigned long long) compressedfilesize, (double)compressedfilesize/filesize*100); { double seconds = (double)(end - start)/CLOCKS_PER_SEC; DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024); } return 0; } /* ********************************************************************* */ /* ********************** LZ4 File / Stream decoding ******************* */ /* ********************************************************************* */ static unsigned long long decodeLegacyStream(FILE* finput, FILE* foutput) { unsigned long long filesize = 0; char* in_buff; char* out_buff; unsigned int blockSize; // Allocate Memory in_buff = (char*)malloc(LZ4_compressBound(LEGACY_BLOCKSIZE)); out_buff = (char*)malloc(LEGACY_BLOCKSIZE); if (!in_buff || !out_buff) EXM_THROW(51, "Allocation error : not enough memory"); // Main Loop while (1) { int decodeSize; size_t sizeCheck; // Block Size sizeCheck = fread(&blockSize, 1, 4, finput); if (sizeCheck==0) break; // Nothing to read : file read is completed blockSize = LITTLE_ENDIAN_32(blockSize); // Convert to Little Endian if (blockSize > LZ4_COMPRESSBOUND(LEGACY_BLOCKSIZE)) { // Cannot read next block : maybe new stream ? fseek(finput, -4, SEEK_CUR); break; } // Read Block sizeCheck = fread(in_buff, 1, blockSize, finput); // Decode Block decodeSize = LZ4_decompress_safe(in_buff, out_buff, blockSize, LEGACY_BLOCKSIZE); if (decodeSize < 0) EXM_THROW(52, "Decoding Failed ! Corrupted input detected !"); filesize += decodeSize; // Write Block sizeCheck = fwrite(out_buff, 1, decodeSize, foutput); if (sizeCheck != (size_t)decodeSize) EXM_THROW(53, "Write error : cannot write decoded block into output\n"); } // Free free(in_buff); free(out_buff); return filesize; } static unsigned long long decodeLZ4S(FILE* finput, FILE* foutput) { unsigned long long filesize = 0; char* in_buff; char* out_buff, *out_start, *out_end; unsigned char descriptor[LZ4S_MAXHEADERSIZE]; size_t nbReadBytes; int decodedBytes=0; unsigned int maxBlockSize; size_t sizeCheck; int blockChecksumFlag, streamChecksumFlag, blockIndependenceFlag; void* streamChecksumState=NULL; int (*decompressionFunction)(const char*, char*, int, int) = LZ4_decompress_safe; unsigned int prefix64k = 0; // Decode stream descriptor nbReadBytes = fread(descriptor, 1, 3, finput); if (nbReadBytes != 3) EXM_THROW(61, "Unreadable header"); { int version = (descriptor[0] >> 6) & _2BITS; int streamSize = (descriptor[0] >> 3) & _1BIT; int reserved1 = (descriptor[0] >> 1) & _1BIT; int dictionary = (descriptor[0] >> 0) & _1BIT; int reserved2 = (descriptor[1] >> 7) & _1BIT; int blockSizeId = (descriptor[1] >> 4) & _3BITS; int reserved3 = (descriptor[1] >> 0) & _4BITS; int checkBits = (descriptor[2] >> 0) & _8BITS; int checkBits_xxh32; blockIndependenceFlag=(descriptor[0] >> 5) & _1BIT; blockChecksumFlag = (descriptor[0] >> 4) & _1BIT; streamChecksumFlag= (descriptor[0] >> 2) & _1BIT; if (version != 1) EXM_THROW(62, "Wrong version number"); if (streamSize == 1) EXM_THROW(64, "Does not support stream size"); if (reserved1 != 0) EXM_THROW(65, "Wrong value for reserved bits"); if (dictionary == 1) EXM_THROW(66, "Does not support dictionary"); if (reserved2 != 0) EXM_THROW(67, "Wrong value for reserved bits"); if (blockSizeId < 4) EXM_THROW(68, "Unsupported block size"); if (reserved3 != 0) EXM_THROW(67, "Wrong value for reserved bits"); maxBlockSize = LZ4S_GetBlockSize_FromBlockId(blockSizeId); // Checkbits verification descriptor[1] &= 0xF0; checkBits_xxh32 = XXH32(descriptor, 2, LZ4S_CHECKSUM_SEED); checkBits_xxh32 = LZ4S_GetCheckBits_FromXXH(checkBits_xxh32); if (checkBits != checkBits_xxh32) EXM_THROW(69, "Stream descriptor error detected"); } if (!blockIndependenceFlag) { decompressionFunction = LZ4_decompress_safe_withPrefix64k; prefix64k = 64 KB; } // Allocate Memory { unsigned int outbuffSize = prefix64k+maxBlockSize; in_buff = (char*)malloc(maxBlockSize); if (outbuffSize < MIN_STREAM_BUFSIZE) outbuffSize = MIN_STREAM_BUFSIZE; out_buff = (char*)malloc(outbuffSize); out_end = out_buff + outbuffSize; out_start = out_buff + prefix64k; if (!in_buff || !out_buff) EXM_THROW(70, "Allocation error : not enough memory"); } if (streamChecksumFlag) streamChecksumState = XXH32_init(LZ4S_CHECKSUM_SEED); // Main Loop while (1) { unsigned int blockSize, uncompressedFlag; // Block Size nbReadBytes = fread(&blockSize, 1, 4, finput); if( nbReadBytes != 4 ) EXM_THROW(71, "Read error : cannot read next block size"); if (blockSize == LZ4S_EOS) break; // End of Stream Mark : stream is completed blockSize = LITTLE_ENDIAN_32(blockSize); // Convert to little endian uncompressedFlag = blockSize >> 31; blockSize &= 0x7FFFFFFF; if (blockSize > maxBlockSize) EXM_THROW(72, "Error : invalid block size"); // Read Block nbReadBytes = fread(in_buff, 1, blockSize, finput); if( nbReadBytes != blockSize ) EXM_THROW(73, "Read error : cannot read data block" ); // Check Block if (blockChecksumFlag) { unsigned int checksum = XXH32(in_buff, blockSize, LZ4S_CHECKSUM_SEED); unsigned int readChecksum; sizeCheck = fread(&readChecksum, 1, 4, finput); if( sizeCheck != 4 ) EXM_THROW(74, "Read error : cannot read next block size"); readChecksum = LITTLE_ENDIAN_32(readChecksum); // Convert to little endian if (checksum != readChecksum) EXM_THROW(75, "Error : invalid block checksum detected"); } if (uncompressedFlag) { // Write uncompressed Block sizeCheck = fwrite(in_buff, 1, blockSize, foutput); if (sizeCheck != (size_t)blockSize) EXM_THROW(76, "Write error : cannot write data block"); filesize += blockSize; if (streamChecksumFlag) XXH32_update(streamChecksumState, in_buff, blockSize); if (!blockIndependenceFlag) { if (blockSize >= prefix64k) { memcpy(out_buff, in_buff + (blockSize - prefix64k), prefix64k); // Required for reference for next blocks out_start = out_buff + prefix64k; continue; } else { memcpy(out_start, in_buff, blockSize); decodedBytes = blockSize; } } } else { // Decode Block decodedBytes = decompressionFunction(in_buff, out_start, blockSize, maxBlockSize); if (decodedBytes < 0) EXM_THROW(77, "Decoding Failed ! Corrupted input detected !"); filesize += decodedBytes; if (streamChecksumFlag) XXH32_update(streamChecksumState, out_start, decodedBytes); // Write Block sizeCheck = fwrite(out_start, 1, decodedBytes, foutput); if (sizeCheck != (size_t)decodedBytes) EXM_THROW(78, "Write error : cannot write decoded block\n"); } if (!blockIndependenceFlag) { out_start += decodedBytes; if ((size_t)(out_end - out_start) < (size_t)maxBlockSize) { memcpy(out_buff, out_start - prefix64k, prefix64k); out_start = out_buff + prefix64k; } } } // Stream Checksum if (streamChecksumFlag) { unsigned int checksum = XXH32_digest(streamChecksumState); unsigned int readChecksum; sizeCheck = fread(&readChecksum, 1, 4, finput); if (sizeCheck != 4) EXM_THROW(74, "Read error : cannot read stream checksum"); readChecksum = LITTLE_ENDIAN_32(readChecksum); // Convert to little endian if (checksum != readChecksum) EXM_THROW(75, "Error : invalid stream checksum detected"); } // Free free(in_buff); free(out_buff); return filesize; } static unsigned long long selectDecoder( FILE* finput, FILE* foutput) { unsigned int magicNumber, size; int errorNb; size_t nbReadBytes; // Check Archive Header nbReadBytes = fread(&magicNumber, 1, MAGICNUMBER_SIZE, finput); if (nbReadBytes==0) return 0; // EOF if (nbReadBytes != MAGICNUMBER_SIZE) EXM_THROW(41, "Unrecognized header : Magic Number unreadable"); magicNumber = LITTLE_ENDIAN_32(magicNumber); // Convert to Little Endian format if (LZ4S_isSkippableMagicNumber(magicNumber)) magicNumber = LZ4S_SKIPPABLE0; // fold skippable magic numbers switch(magicNumber) { case LZ4S_MAGICNUMBER: return DEFAULT_DECOMPRESSOR(finput, foutput); case LEGACY_MAGICNUMBER: DISPLAYLEVEL(4, "Detected : Legacy format \n"); return decodeLegacyStream(finput, foutput); case LZ4S_SKIPPABLE0: DISPLAYLEVEL(4, "Skipping detected skippable area \n"); nbReadBytes = fread(&size, 1, 4, finput); if (nbReadBytes != 4) EXM_THROW(42, "Stream error : skippable size unreadable"); size = LITTLE_ENDIAN_32(size); // Convert to Little Endian format errorNb = fseek(finput, size, SEEK_CUR); if (errorNb != 0) EXM_THROW(43, "Stream error : cannot skip skippable area"); return selectDecoder(finput, foutput); EXTENDED_FORMAT; default: if (ftell(finput) == MAGICNUMBER_SIZE) EXM_THROW(44,"Unrecognized header : file cannot be decoded"); // Wrong magic number at the beginning of 1st stream DISPLAYLEVEL(2, "Stream followed by unrecognized data\n"); return 0; } } int LZ4IO_decompressFilename(char* input_filename, char* output_filename) { unsigned long long filesize = 0, decodedSize=0; FILE* finput; FILE* foutput; clock_t start, end; // Init start = clock(); get_fileHandle(input_filename, output_filename, &finput, &foutput); // Loop over multiple streams do { decodedSize = selectDecoder(finput, foutput); filesize += decodedSize; } while (decodedSize); // Final Status end = clock(); DISPLAYLEVEL(2, "\r%79s\r", ""); DISPLAYLEVEL(2, "Successfully decoded %llu bytes \n", filesize); { double seconds = (double)(end - start)/CLOCKS_PER_SEC; DISPLAYLEVEL(4, "Done in %.2f s ==> %.2f MB/s\n", seconds, (double)filesize / seconds / 1024 / 1024); } // Close fclose(finput); fclose(foutput); // Error status = OK return 0; } lz4-0.0~r114/programs/lz4io.h000066400000000000000000000052731231007221700157360ustar00rootroot00000000000000/* LZ4io.h - LZ4 File/Stream Interface Copyright (C) Yann Collet 2011-2013 GPL v2 License This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. You can contact the author at : - LZ4 source repository : http://code.google.com/p/lz4/ - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c */ /* Note : this is stand-alone program. It is not part of LZ4 compression library, it is a user code of the LZ4 library. - The license of LZ4 library is BSD. - The license of xxHash library is BSD. - The license of this source file is GPLv2. */ /* ************************************************** */ /* Special input/output values */ /* ************************************************** */ #define NULL_OUTPUT "null" static char stdinmark[] = "stdin"; static char stdoutmark[] = "stdout"; #ifdef _WIN32 static char nulmark[] = "nul"; #else static char nulmark[] = "/dev/null"; #endif /* ************************************************** */ /* ****************** Functions ********************* */ /* ************************************************** */ int LZ4IO_compressFilename (char* input_filename, char* output_filename, int compressionlevel); int LZ4IO_decompressFilename(char* input_filename, char* output_filename); /* ************************************************** */ /* ****************** Parameters ******************** */ /* ************************************************** */ /* Default setting : overwrite = 1; return : overwrite mode (0/1) */ int LZ4IO_setOverwrite(int yes); /* blockSizeID : valid values : 4-5-6-7 return : -1 if error, blockSize if OK */ int LZ4IO_setBlockSizeID(int blockSizeID); /* Default setting : independent blocks */ typedef enum { chainedBlocks, independentBlocks } blockMode_t; int LZ4IO_setBlockMode(blockMode_t blockMode); /* Default setting : no checksum */ int LZ4IO_setBlockChecksumMode(int xxhash); /* Default setting : checksum enabled */ int LZ4IO_setStreamChecksumMode(int xxhash); /* Default setting : 0 (no notification) */ int LZ4IO_setNotificationLevel(int level); lz4-0.0~r114/programs/xxhash.c000066400000000000000000000357751231007221700162050ustar00rootroot00000000000000/* xxHash - Fast Hash algorithm Copyright (C) 2012-2014, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - xxHash source repository : http://code.google.com/p/xxhash/ */ //************************************** // Tuning parameters //************************************** // Unaligned memory access is automatically enabled for "common" CPU, such as x86. // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected. // If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance. // You can also enable this parameter if you know your input data will always be aligned (boundaries of 4, for U32). #if defined(__ARM_FEATURE_UNALIGNED) || defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) # define XXH_USE_UNALIGNED_ACCESS 1 #endif // XXH_ACCEPT_NULL_INPUT_POINTER : // If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer. // When this option is enabled, xxHash output for null input pointers will be the same as a null-length input. // This option has a very small performance cost (only measurable on small inputs). // By default, this option is disabled. To enable it, uncomment below define : //#define XXH_ACCEPT_NULL_INPUT_POINTER 1 // XXH_FORCE_NATIVE_FORMAT : // By default, xxHash library provides endian-independant Hash values, based on little-endian convention. // Results are therefore identical for little-endian and big-endian CPU. // This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format. // Should endian-independance be of no importance for your application, you may set the #define below to 1. // It will improve speed for Big-endian CPU. // This option has no impact on Little_Endian CPU. #define XXH_FORCE_NATIVE_FORMAT 0 //************************************** // Compiler Specific Options //************************************** // Disable some Visual warning messages #ifdef _MSC_VER // Visual Studio # pragma warning(disable : 4127) // disable: C4127: conditional expression is constant #endif #ifdef _MSC_VER // Visual Studio # define FORCE_INLINE static __forceinline #else # ifdef __GNUC__ # define FORCE_INLINE static inline __attribute__((always_inline)) # else # define FORCE_INLINE static inline # endif #endif //************************************** // Includes & Memory related functions //************************************** #include "xxhash.h" // Modify the local functions below should you wish to use some other memory related routines // for malloc(), free() #include FORCE_INLINE void* XXH_malloc(size_t s) { return malloc(s); } FORCE_INLINE void XXH_free (void* p) { free(p); } // for memcpy() #include FORCE_INLINE void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); } //************************************** // Basic Types //************************************** #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L // C99 # include typedef uint8_t BYTE; typedef uint16_t U16; typedef uint32_t U32; typedef int32_t S32; typedef uint64_t U64; #else typedef unsigned char BYTE; typedef unsigned short U16; typedef unsigned int U32; typedef signed int S32; typedef unsigned long long U64; #endif #if defined(__GNUC__) && !defined(XXH_USE_UNALIGNED_ACCESS) # define _PACKED __attribute__ ((packed)) #else # define _PACKED #endif #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) # ifdef __IBMC__ # pragma pack(1) # else # pragma pack(push, 1) # endif #endif typedef struct _U32_S { U32 v; } _PACKED U32_S; #if !defined(XXH_USE_UNALIGNED_ACCESS) && !defined(__GNUC__) # pragma pack(pop) #endif #define A32(x) (((U32_S *)(x))->v) //*************************************** // Compiler-specific Functions and Macros //*************************************** #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) // Note : although _rotl exists for minGW (GCC under windows), performance seems poor #if defined(_MSC_VER) # define XXH_rotl32(x,r) _rotl(x,r) #else # define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r))) #endif #if defined(_MSC_VER) // Visual Studio # define XXH_swap32 _byteswap_ulong #elif GCC_VERSION >= 403 # define XXH_swap32 __builtin_bswap32 #else static inline U32 XXH_swap32 (U32 x) { return ((x << 24) & 0xff000000 ) | ((x << 8) & 0x00ff0000 ) | ((x >> 8) & 0x0000ff00 ) | ((x >> 24) & 0x000000ff );} #endif //************************************** // Constants //************************************** #define PRIME32_1 2654435761U #define PRIME32_2 2246822519U #define PRIME32_3 3266489917U #define PRIME32_4 668265263U #define PRIME32_5 374761393U //************************************** // Architecture Macros //************************************** typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess; #ifndef XXH_CPU_LITTLE_ENDIAN // It is possible to define XXH_CPU_LITTLE_ENDIAN externally, for example using a compiler switch static const int one = 1; # define XXH_CPU_LITTLE_ENDIAN (*(char*)(&one)) #endif //************************************** // Macros //************************************** #define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(!!(c)) }; } // use only *after* variable declarations //**************************** // Memory reads //**************************** typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment; FORCE_INLINE U32 XXH_readLE32_align(const U32* ptr, XXH_endianess endian, XXH_alignment align) { if (align==XXH_unaligned) return endian==XXH_littleEndian ? A32(ptr) : XXH_swap32(A32(ptr)); else return endian==XXH_littleEndian ? *ptr : XXH_swap32(*ptr); } FORCE_INLINE U32 XXH_readLE32(const U32* ptr, XXH_endianess endian) { return XXH_readLE32_align(ptr, endian, XXH_unaligned); } //**************************** // Simple Hash Functions //**************************** FORCE_INLINE U32 XXH32_endian_align(const void* input, int len, U32 seed, XXH_endianess endian, XXH_alignment align) { const BYTE* p = (const BYTE*)input; const BYTE* const bEnd = p + len; U32 h32; #ifdef XXH_ACCEPT_NULL_INPUT_POINTER if (p==NULL) { len=0; p=(const BYTE*)(size_t)16; } #endif if (len>=16) { const BYTE* const limit = bEnd - 16; U32 v1 = seed + PRIME32_1 + PRIME32_2; U32 v2 = seed + PRIME32_2; U32 v3 = seed + 0; U32 v4 = seed - PRIME32_1; do { v1 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; v2 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; v3 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; v4 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; } while (p<=limit); h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18); } else { h32 = seed + PRIME32_5; } h32 += (U32) len; while (p<=bEnd-4) { h32 += XXH_readLE32_align((const U32*)p, endian, align) * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4 ; p+=4; } while (p> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return h32; } U32 XXH32(const void* input, int len, U32 seed) { #if 0 // Simple version, good for code maintenance, but unfortunately slow for small inputs void* state = XXH32_init(seed); XXH32_update(state, input, len); return XXH32_digest(state); #else XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; # if !defined(XXH_USE_UNALIGNED_ACCESS) if ((((size_t)input) & 3)) // Input is aligned, let's leverage the speed advantage { if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned); } # endif if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned); else return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned); #endif } //**************************** // Advanced Hash Functions //**************************** struct XXH_state32_t { U64 total_len; U32 seed; U32 v1; U32 v2; U32 v3; U32 v4; int memsize; char memory[16]; }; int XXH32_sizeofState() { XXH_STATIC_ASSERT(XXH32_SIZEOFSTATE >= sizeof(struct XXH_state32_t)); // A compilation error here means XXH32_SIZEOFSTATE is not large enough return sizeof(struct XXH_state32_t); } XXH_errorcode XXH32_resetState(void* state_in, U32 seed) { struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; state->seed = seed; state->v1 = seed + PRIME32_1 + PRIME32_2; state->v2 = seed + PRIME32_2; state->v3 = seed + 0; state->v4 = seed - PRIME32_1; state->total_len = 0; state->memsize = 0; return XXH_OK; } void* XXH32_init (U32 seed) { void* state = XXH_malloc (sizeof(struct XXH_state32_t)); XXH32_resetState(state, seed); return state; } FORCE_INLINE XXH_errorcode XXH32_update_endian (void* state_in, const void* input, int len, XXH_endianess endian) { struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; const BYTE* p = (const BYTE*)input; const BYTE* const bEnd = p + len; #ifdef XXH_ACCEPT_NULL_INPUT_POINTER if (input==NULL) return XXH_ERROR; #endif state->total_len += len; if (state->memsize + len < 16) // fill in tmp buffer { XXH_memcpy(state->memory + state->memsize, input, len); state->memsize += len; return XXH_OK; } if (state->memsize) // some data left from previous update { XXH_memcpy(state->memory + state->memsize, input, 16-state->memsize); { const U32* p32 = (const U32*)state->memory; state->v1 += XXH_readLE32(p32, endian) * PRIME32_2; state->v1 = XXH_rotl32(state->v1, 13); state->v1 *= PRIME32_1; p32++; state->v2 += XXH_readLE32(p32, endian) * PRIME32_2; state->v2 = XXH_rotl32(state->v2, 13); state->v2 *= PRIME32_1; p32++; state->v3 += XXH_readLE32(p32, endian) * PRIME32_2; state->v3 = XXH_rotl32(state->v3, 13); state->v3 *= PRIME32_1; p32++; state->v4 += XXH_readLE32(p32, endian) * PRIME32_2; state->v4 = XXH_rotl32(state->v4, 13); state->v4 *= PRIME32_1; p32++; } p += 16-state->memsize; state->memsize = 0; } if (p <= bEnd-16) { const BYTE* const limit = bEnd - 16; U32 v1 = state->v1; U32 v2 = state->v2; U32 v3 = state->v3; U32 v4 = state->v4; do { v1 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v1 = XXH_rotl32(v1, 13); v1 *= PRIME32_1; p+=4; v2 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v2 = XXH_rotl32(v2, 13); v2 *= PRIME32_1; p+=4; v3 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v3 = XXH_rotl32(v3, 13); v3 *= PRIME32_1; p+=4; v4 += XXH_readLE32((const U32*)p, endian) * PRIME32_2; v4 = XXH_rotl32(v4, 13); v4 *= PRIME32_1; p+=4; } while (p<=limit); state->v1 = v1; state->v2 = v2; state->v3 = v3; state->v4 = v4; } if (p < bEnd) { XXH_memcpy(state->memory, p, bEnd-p); state->memsize = (int)(bEnd-p); } return XXH_OK; } XXH_errorcode XXH32_update (void* state_in, const void* input, int len) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_update_endian(state_in, input, len, XXH_littleEndian); else return XXH32_update_endian(state_in, input, len, XXH_bigEndian); } FORCE_INLINE U32 XXH32_intermediateDigest_endian (void* state_in, XXH_endianess endian) { struct XXH_state32_t * state = (struct XXH_state32_t *) state_in; const BYTE * p = (const BYTE*)state->memory; BYTE* bEnd = (BYTE*)state->memory + state->memsize; U32 h32; if (state->total_len >= 16) { h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18); } else { h32 = state->seed + PRIME32_5; } h32 += (U32) state->total_len; while (p<=bEnd-4) { h32 += XXH_readLE32((const U32*)p, endian) * PRIME32_3; h32 = XXH_rotl32(h32, 17) * PRIME32_4; p+=4; } while (p> 15; h32 *= PRIME32_2; h32 ^= h32 >> 13; h32 *= PRIME32_3; h32 ^= h32 >> 16; return h32; } U32 XXH32_intermediateDigest (void* state_in) { XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN; if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT) return XXH32_intermediateDigest_endian(state_in, XXH_littleEndian); else return XXH32_intermediateDigest_endian(state_in, XXH_bigEndian); } U32 XXH32_digest (void* state_in) { U32 h32 = XXH32_intermediateDigest(state_in); XXH_free(state_in); return h32; } lz4-0.0~r114/programs/xxhash.h000066400000000000000000000142551231007221700162000ustar00rootroot00000000000000/* xxHash - Fast Hash algorithm Header File Copyright (C) 2012-2014, Yann Collet. BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. You can contact the author at : - xxHash source repository : http://code.google.com/p/xxhash/ */ /* Notice extracted from xxHash homepage : xxHash is an extremely fast Hash algorithm, running at RAM speed limits. It also successfully passes all tests from the SMHasher suite. Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) Name Speed Q.Score Author xxHash 5.4 GB/s 10 CrapWow 3.2 GB/s 2 Andrew MumurHash 3a 2.7 GB/s 10 Austin Appleby SpookyHash 2.0 GB/s 10 Bob Jenkins SBox 1.4 GB/s 9 Bret Mulvey Lookup3 1.2 GB/s 9 Bob Jenkins SuperFastHash 1.2 GB/s 1 Paul Hsieh CityHash64 1.05 GB/s 10 Pike & Alakuijala FNV 0.55 GB/s 5 Fowler, Noll, Vo CRC32 0.43 GB/s 9 MD5-32 0.33 GB/s 10 Ronald L. Rivest SHA1-32 0.28 GB/s 10 Q.Score is a measure of quality of the hash function. It depends on successfully passing SMHasher test set. 10 is a perfect score. */ #pragma once #if defined (__cplusplus) extern "C" { #endif //**************************** // Type //**************************** typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; //**************************** // Simple Hash Functions //**************************** unsigned int XXH32 (const void* input, int len, unsigned int seed); /* XXH32() : Calculate the 32-bits hash of sequence of length "len" stored at memory address "input". The memory between input & input+len must be valid (allocated and read-accessible). "seed" can be used to alter the result predictably. This function successfully passes all SMHasher tests. Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s Note that "len" is type "int", which means it is limited to 2^31-1. If your data is larger, use the advanced functions below. */ //**************************** // Advanced Hash Functions //**************************** void* XXH32_init (unsigned int seed); XXH_errorcode XXH32_update (void* state, const void* input, int len); unsigned int XXH32_digest (void* state); /* These functions calculate the xxhash of an input provided in several small packets, as opposed to an input provided as a single block. It must be started with : void* XXH32_init() The function returns a pointer which holds the state of calculation. This pointer must be provided as "void* state" parameter for XXH32_update(). XXH32_update() can be called as many times as necessary. The user must provide a valid (allocated) input. The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. Note that "len" is type "int", which means it is limited to 2^31-1. If your data is larger, it is recommended to chunk your data into blocks of size for example 2^30 (1GB) to avoid any "int" overflow issue. Finally, you can end the calculation anytime, by using XXH32_digest(). This function returns the final 32-bits hash. You must provide the same "void* state" parameter created by XXH32_init(). Memory will be freed by XXH32_digest(). */ int XXH32_sizeofState(void); XXH_errorcode XXH32_resetState(void* state, unsigned int seed); #define XXH32_SIZEOFSTATE 48 typedef struct { long long ll[(XXH32_SIZEOFSTATE+(sizeof(long long)-1))/sizeof(long long)]; } XXH32_stateSpace_t; /* These functions allow user application to make its own allocation for state. XXH32_sizeofState() is used to know how much space must be allocated for the xxHash 32-bits state. Note that the state must be aligned to access 'long long' fields. Memory must be allocated and referenced by a pointer. This pointer must then be provided as 'state' into XXH32_resetState(), which initializes the state. For static allocation purposes (such as allocation on stack, or freestanding systems without malloc()), use the structure XXH32_stateSpace_t, which will ensure that memory space is large enough and correctly aligned to access 'long long' fields. */ unsigned int XXH32_intermediateDigest (void* state); /* This function does the same as XXH32_digest(), generating a 32-bit hash, but preserve memory context. This way, it becomes possible to generate intermediate hashes, and then continue feeding data with XXH32_update(). To free memory context, use XXH32_digest(), or free(). */ //**************************** // Deprecated function names //**************************** // The following translations are provided to ease code transition // You are encouraged to no longer this function names #define XXH32_feed XXH32_update #define XXH32_result XXH32_digest #define XXH32_getIntermediateResult XXH32_intermediateDigest #if defined (__cplusplus) } #endif