From 303ae446cf2ab1469d83e83f4cc5168c899c3cee Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 12 Sep 2005 17:03:48 +0000 Subject: [PATCH] Initial revision From-SVN: r104179 --- zlib/contrib/ada/buffer_demo.adb | 106 +++ zlib/contrib/dotzlib/DotZLib.build | 33 + zlib/contrib/dotzlib/DotZLib.chm | Bin 0 -> 72728 bytes zlib/contrib/dotzlib/DotZLib.sln | 21 + zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs | 58 ++ zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs | 202 ++++ zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs | 83 ++ zlib/contrib/dotzlib/DotZLib/CodecBase.cs | 198 ++++ zlib/contrib/dotzlib/DotZLib/Deflater.cs | 106 +++ zlib/contrib/dotzlib/DotZLib/DotZLib.cs | 288 ++++++ zlib/contrib/dotzlib/DotZLib/DotZLib.csproj | 141 +++ zlib/contrib/dotzlib/DotZLib/GZipStream.cs | 301 ++++++ zlib/contrib/dotzlib/DotZLib/Inflater.cs | 105 ++ zlib/contrib/dotzlib/DotZLib/UnitTests.cs | 274 ++++++ zlib/contrib/dotzlib/LICENSE_1_0.txt | 23 + zlib/contrib/dotzlib/readme.txt | 58 ++ zlib/contrib/masmx64/bld_ml64.bat | 2 + zlib/contrib/masmx64/gvmat64.asm | 513 ++++++++++ zlib/contrib/masmx64/gvmat64.obj | Bin 0 -> 4119 bytes zlib/contrib/masmx64/inffas8664.c | 186 ++++ zlib/contrib/masmx64/inffasx64.asm | 392 ++++++++ zlib/contrib/masmx64/inffasx64.obj | Bin 0 -> 5913 bytes zlib/contrib/masmx64/readme.txt | 28 + zlib/contrib/masmx86/bld_ml32.bat | 2 + zlib/contrib/masmx86/gvmat32.obj | Bin 0 -> 10241 bytes zlib/contrib/masmx86/inffas32.obj | Bin 0 -> 14893 bytes zlib/contrib/minizip/mztools.c | 281 ++++++ zlib/contrib/minizip/mztools.h | 31 + zlib/contrib/testzlib/testzlib.txt | 10 + zlib/contrib/vstudio/vc7/testzlib.vcproj | 126 +++ zlib/contrib/vstudio/vc8/miniunz.vcproj | 566 +++++++++++ zlib/contrib/vstudio/vc8/minizip.vcproj | 563 +++++++++++ zlib/contrib/vstudio/vc8/testzlib.vcproj | 948 ++++++++++++++++++ zlib/contrib/vstudio/vc8/testzlibdll.vcproj | 567 +++++++++++ zlib/contrib/vstudio/vc8/zlib.rc | 32 + zlib/contrib/vstudio/vc8/zlibstat.vcproj | 870 +++++++++++++++++ zlib/contrib/vstudio/vc8/zlibvc.def | 92 ++ zlib/contrib/vstudio/vc8/zlibvc.sln | 144 +++ zlib/contrib/vstudio/vc8/zlibvc.vcproj | 1219 ++++++++++++++++++++++++ zlib/examples/README.examples | 42 + zlib/examples/fitblk.c | 233 +++++ zlib/examples/gun.c | 693 ++++++++++++++ zlib/examples/gzappend.c | 500 ++++++++++ zlib/examples/gzjoin.c | 448 +++++++++ zlib/examples/gzlog.c | 413 ++++++++ zlib/examples/gzlog.h | 58 ++ zlib/examples/zlib_how.html | 523 ++++++++++ zlib/examples/zpipe.c | 191 ++++ zlib/examples/zran.c | 404 ++++++++ zlib/make_vms.com | 461 +++++++++ zlib/old/visual-basic.txt | 160 ++++ zlib/projects/README.projects | 41 + zlib/projects/visualc6/README.txt | 73 ++ zlib/projects/visualc6/example.dsp | 278 ++++++ zlib/projects/visualc6/minigzip.dsp | 278 ++++++ zlib/projects/visualc6/zlib.dsp | 609 ++++++++++++ zlib/projects/visualc6/zlib.dsw | 59 ++ zlib/win32/VisualC.txt | 3 + 58 files changed, 14036 insertions(+) create mode 100644 zlib/contrib/ada/buffer_demo.adb create mode 100644 zlib/contrib/dotzlib/DotZLib.build create mode 100644 zlib/contrib/dotzlib/DotZLib.chm create mode 100644 zlib/contrib/dotzlib/DotZLib.sln create mode 100644 zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/CodecBase.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/Deflater.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/DotZLib.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/DotZLib.csproj create mode 100644 zlib/contrib/dotzlib/DotZLib/GZipStream.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/Inflater.cs create mode 100644 zlib/contrib/dotzlib/DotZLib/UnitTests.cs create mode 100644 zlib/contrib/dotzlib/LICENSE_1_0.txt create mode 100644 zlib/contrib/dotzlib/readme.txt create mode 100644 zlib/contrib/masmx64/bld_ml64.bat create mode 100644 zlib/contrib/masmx64/gvmat64.asm create mode 100644 zlib/contrib/masmx64/gvmat64.obj create mode 100644 zlib/contrib/masmx64/inffas8664.c create mode 100644 zlib/contrib/masmx64/inffasx64.asm create mode 100644 zlib/contrib/masmx64/inffasx64.obj create mode 100644 zlib/contrib/masmx64/readme.txt create mode 100644 zlib/contrib/masmx86/bld_ml32.bat create mode 100644 zlib/contrib/masmx86/gvmat32.obj create mode 100644 zlib/contrib/masmx86/inffas32.obj create mode 100644 zlib/contrib/minizip/mztools.c create mode 100644 zlib/contrib/minizip/mztools.h create mode 100644 zlib/contrib/testzlib/testzlib.txt create mode 100644 zlib/contrib/vstudio/vc7/testzlib.vcproj create mode 100644 zlib/contrib/vstudio/vc8/miniunz.vcproj create mode 100644 zlib/contrib/vstudio/vc8/minizip.vcproj create mode 100644 zlib/contrib/vstudio/vc8/testzlib.vcproj create mode 100644 zlib/contrib/vstudio/vc8/testzlibdll.vcproj create mode 100644 zlib/contrib/vstudio/vc8/zlib.rc create mode 100644 zlib/contrib/vstudio/vc8/zlibstat.vcproj create mode 100644 zlib/contrib/vstudio/vc8/zlibvc.def create mode 100644 zlib/contrib/vstudio/vc8/zlibvc.sln create mode 100644 zlib/contrib/vstudio/vc8/zlibvc.vcproj create mode 100644 zlib/examples/README.examples create mode 100644 zlib/examples/fitblk.c create mode 100644 zlib/examples/gun.c create mode 100644 zlib/examples/gzappend.c create mode 100644 zlib/examples/gzjoin.c create mode 100644 zlib/examples/gzlog.c create mode 100644 zlib/examples/gzlog.h create mode 100644 zlib/examples/zlib_how.html create mode 100644 zlib/examples/zpipe.c create mode 100644 zlib/examples/zran.c create mode 100644 zlib/make_vms.com create mode 100644 zlib/old/visual-basic.txt create mode 100644 zlib/projects/README.projects create mode 100644 zlib/projects/visualc6/README.txt create mode 100644 zlib/projects/visualc6/example.dsp create mode 100644 zlib/projects/visualc6/minigzip.dsp create mode 100644 zlib/projects/visualc6/zlib.dsp create mode 100644 zlib/projects/visualc6/zlib.dsw create mode 100644 zlib/win32/VisualC.txt diff --git a/zlib/contrib/ada/buffer_demo.adb b/zlib/contrib/ada/buffer_demo.adb new file mode 100644 index 0000000..46b8638 --- /dev/null +++ b/zlib/contrib/ada/buffer_demo.adb @@ -0,0 +1,106 @@ +---------------------------------------------------------------- +-- ZLib for Ada thick binding. -- +-- -- +-- Copyright (C) 2002-2004 Dmitriy Anisimkov -- +-- -- +-- Open source license information is in the zlib.ads file. -- +---------------------------------------------------------------- +-- +-- $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $ + +-- This demo program provided by Dr Steve Sangwine +-- +-- Demonstration of a problem with Zlib-Ada (already fixed) when a buffer +-- of exactly the correct size is used for decompressed data, and the last +-- few bytes passed in to Zlib are checksum bytes. + +-- This program compresses a string of text, and then decompresses the +-- compressed text into a buffer of the same size as the original text. + +with Ada.Streams; use Ada.Streams; +with Ada.Text_IO; + +with ZLib; use ZLib; + +procedure Buffer_Demo is + EOL : Character renames ASCII.LF; + Text : constant String + := "Four score and seven years ago our fathers brought forth," & EOL & + "upon this continent, a new nation, conceived in liberty," & EOL & + "and dedicated to the proposition that `all men are created equal'."; + + Source : Stream_Element_Array (1 .. Text'Length); + for Source'Address use Text'Address; + +begin + Ada.Text_IO.Put (Text); + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes"); + + declare + Compressed_Data : Stream_Element_Array (1 .. Text'Length); + L : Stream_Element_Offset; + begin + Compress : declare + Compressor : Filter_Type; + I : Stream_Element_Offset; + begin + Deflate_Init (Compressor); + + -- Compress the whole of T at once. + + Translate (Compressor, Source, I, Compressed_Data, L, Finish); + pragma Assert (I = Source'Last); + + Close (Compressor); + + Ada.Text_IO.Put_Line + ("Compressed size : " + & Stream_Element_Offset'Image (L) & " bytes"); + end Compress; + + -- Now we decompress the data, passing short blocks of data to Zlib + -- (because this demonstrates the problem - the last block passed will + -- contain checksum information and there will be no output, only a + -- check inside Zlib that the checksum is correct). + + Decompress : declare + Decompressor : Filter_Type; + + Uncompressed_Data : Stream_Element_Array (1 .. Text'Length); + + Block_Size : constant := 4; + -- This makes sure that the last block contains + -- only Adler checksum data. + + P : Stream_Element_Offset := Compressed_Data'First - 1; + O : Stream_Element_Offset; + begin + Inflate_Init (Decompressor); + + loop + Translate + (Decompressor, + Compressed_Data + (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)), + P, + Uncompressed_Data + (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last), + O, + No_Flush); + + Ada.Text_IO.Put_Line + ("Total in : " & Count'Image (Total_In (Decompressor)) & + ", out : " & Count'Image (Total_Out (Decompressor))); + + exit when P = L; + end loop; + + Ada.Text_IO.New_Line; + Ada.Text_IO.Put_Line + ("Decompressed text matches original text : " + & Boolean'Image (Uncompressed_Data = Source)); + end Decompress; + end; +end Buffer_Demo; diff --git a/zlib/contrib/dotzlib/DotZLib.build b/zlib/contrib/dotzlib/DotZLib.build new file mode 100644 index 0000000..ed19cc9 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib.build @@ -0,0 +1,33 @@ + + + A .Net wrapper library around ZLib1.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/zlib/contrib/dotzlib/DotZLib.chm b/zlib/contrib/dotzlib/DotZLib.chm new file mode 100644 index 0000000000000000000000000000000000000000..0bc7df76e407dcc69094483a6e9507240fe257ab GIT binary patch literal 72728 zcmeGEby!tR_Xmt0Lb^-3ySqWUyF;2oNq0+kgMffYgLESxDJ4jYNJ^JTHv%sx-r#-v zJooqc<9Geu_qyC%`^?@mpEY~UXU(jcS?6pdRg}fR004mg^$Bu)%1mlyL4X4QNEaZU zg&sr5>2QFIcf>23$bY-P!QUL1KN5iJZK}ffiW3R5Bgdsi#SjndZHoZ7pFgTx{Kvz zl?C`=WYS*WsmLox3SSrcy2a>U->NFfT;oBWza%PF`f;lwBm?q1PBTK{x+--^IT3kv zWsrnPVqY0p22wFe6GwAd19NMT#CmhT0wib#Qh6aMNjYT|ki;D7XOGYsNY&K^9UN?o z%ncmPoq;mu)=wO6G{*aFfr7n_EzsW4?OK=|9Qg(!4Rmv{u{Zup4&xu0LMrw^AV|WL zwQsr1_s9JrB4XfZ0FoHNo#>AC4@p@ATad(TRwb-|l-$z;f)Is4#Ky?U3TW+k-2@wJ zdNVU4khpqL-+b49mOKH8pXU?Axt4I$k})@=7c{m6+6$Wjjh;9-S<#z0T3Lel_6kK{ z(ESI5s;#ksBT&!A8E9{5V_>Yu@xs_Wvg1a4XW~9`%&`_aeeJ)((#LPDYM4 z_P1bvf^b5Le+4t$qN5&#DE~W}`4*jo5@tpG`?_U;R)#?PTaA4`Y7~qAN1&sbjq%T> zWj@XEAo#1spY)0Yt%3FicWv5~3zH%HFDNCT1JLn@j{f;lA>2&=1^aiq+%n<6i4ckN zzsTKk;{Vw>0`q^7yX^=5y$_%1{V#H?x9w}T45wlIzqjv}X#aBXD6{`Yp_+lE6Y%yC zvAiK_cU|-!MiDY_0MhFjIoaD^52PO=0n>~j#w7n)tM4M;$Bh3eRfG)Hzaa0~Gw=m` zs1Vz~;Qxb71J`(?*#1}9Te}8M!9+6uud=tc4Qv-omi%93Z|xgc;}Ido`oFdJ*2aN( z^3k;aM(sU22kdBss?h)UNBzUU1eD1|h%o%0g>FYzz#EiM{{OqwtqlS?6~amWr9oom zK+B)rBw)xPoR9jy>-LME3J7$1rTMP{_xx4B8EuxqoyY&}(72s(%z?LN30Ou87rAra z|B(4bBfn$pD4YKZzNd|U3Q8pBf8povn)nAnhqK(dWnmj*pwacbW_&kE-I^B!eDF&e= zzkBj6o3~FM*9s%~T{Et&W?*UVerwo}d9M&^{NJ?pzHvh~C_>#H{s#2jz(Kp%;Y`0X z@Dm{?6BD4l@?Q@N9w7}8yj%Eu9}3^ukhlI#J3|f#Lu`Imul>!!L*B{pj=c-S5S`y4 zuW`RxEi}+F4Eb+k>_&rsc--J>v|t0ge>Pdv`Fi@j?J1$rUSY<+!QA(b!HrIlD!<|P z7ylFVO}b9F@p~coG=qg7vHB_q7h1r3{n#+fe>h8z0>mi+=#_ zX%duU7QywmcK=kGfX+b6A00F_2Rs_*9zsc&h52vBsv-z? zxaaqOLHvF7!SbWlux6I~D}CYrCUa}Xurk*BEB#+Y{?RW&zi8fH>HjD2txFF*a=X9M z|4-;!FBN(vbAP4(3;Gueg|?vFU+Mo1c+XN{VO%*LcisJ$K_+2feY3f`rELr zJe2%;+xxr25HSWJ1O5n30L~7!4rT+I2HFJ51=0yZ?STQf6qqY$0th@v6o4OK0=U`# z(?Z#%dGKq@!3>E)vb-&IgQ7?o;=7W_=qr> zNUgi+?Ow4A(Aw1TcD)h#nk|C;w;CzfIGF#4Gu%WAB0HW$-1E`*YP;h!s!S#M_hj8* zgxr3T71aY9N_}U>dv)CrA2rMt#dbI1e!)22Z$Q*%iwK9`QgzQfQJXr6F2AkqJLpce zXn&Px?7JE8?y>*quMx{0VfuHY_qWJf?-jA59i{Lu&|B9PaYYk}@H?aZG7ch=$@^7* zkGeM!B8TPM>3-Mfzt1s|5nQqE@PBor@4d&jfGZ37&XGx4{})FVlcay&k^L5X>&Rjv zaql~_zo5T3vY33K`;P1{(0xZ1Q|25>e&=)k!hBagI?g&=^sZC?Ec}NJqsO^|#qK)d zPuwqDN2jyg_c?c%drU{qJ}t$&v&S{YhF-$JK?G>%WcvN)yH>F=tRbQ|p}HR-xx0dx zdfYJazlq;0_T)|EO-%lZ4aFwAg(%#)nD630PzpBY);E*PkEdixhA8~fCL8)6FjdK) z0gu>1tPrWYF>|jfRT&#=)7y$FjY8z^hQfD{ssqsBI*NK7EwgmHS#{nb8<|3M?iM=V zk!siBwC_R68|M+*fe<3}t4{y0Ma&+4@T0rs)=ee9*dgYvQ7O;eChVsC@BKLDR3}mW zZY6XR_!M92`IrQfOLS5E*Rk&7G})H(ik4)Z7FlAp$%Y z4&gf2#?j;^r0_j6e%mn^_g0`xVT42e~2LWd0%_zvdF;1&76%6hF32tv=dGj!U z1uoUU;;%KbzUf2&LnwxS1*_N_SUZ^5*jq7tSD%+$?|%^S;1CmL=Hy~!q~j7{VWMMV z61lz-V&Jxr-`6Pf_{Lii%x zdZoL)i++*|5t=&fa-*N3>gCP@d3pHNAOm#Lr_Lg7m#Xz(9Ql|at87Hcm8)v z@Si*TA8W$9;J}}&KMed~;12_T82H1$9|ry~@P~mv4E$l>4+DP~_`|>-2L3c!ufYge={Z>GIXM`auggilzhiMD^ZmVvAHsn0 zKJ~2h7aczvcilR8z|YX(O$-PC20*yZxc3480OC5w_?Mgq0BC@$gR!*)(9#wFdHt+1 zD5GMy>-6Th<_bxLL|OI~aW%-zV}ict{&<7q_VSmvJZ^r~@%Q5f_m_%4h5n>}82H1$ z9|ry~@P~mv4E$l>4+DP~_`|>-2L3Schk-u~{J)9;#M@W^64Fidgau511pq))O(ryd z1lkJ<4U}b!vlFh=$D7i8MMuk2Nz7V{XY;j|=6tiZHcmtQJY)|M{NXWUF#tfqtS<@y zkOZWYRRSyJ)PzW-rIW-?Bok@f2oou!{V6E}wf86Bn|cRo9k!a1=<6%bC$jZADJ=&a z7pWfWw>tNp1R$Ovql(VwWf2_s5U3IgsvhL#TSH^So#=o{Uuy^+Qqys*;DvUL}rA?=4`lbR=jsW0?YvR*h$HnNhp= zC!izu;7A+DiZ@kulAlK{n{*^;+WBXnvVm^`j#IMvXU-V}_qao1<69ICjx z#>je?dOT5Wl|%`3vbEPHG~%aFZzYFws0JrvGib&2P+KG9gm@|Na;`dR;@hXdF0GoZ zA-H|QH*e*41=$Iq5bI%HN<7~G#@%@RB7i{JIIaZ}5Wwy4o<;eoy+hDvrhjIDL?wm@1uB1Q#CKL+EnX#od_o5Ll)IMaO z7NBj&@^Kd;)<%OES%^J;dru5(Byz|)wNe231+*1B;m&Izkxf{~q>@M^K5oRE!sTob zc|{J+dp9AWy9VYkT9+9Xs~h za7ux3s^H@U1XPuqE^Qhl@AX5bvU0-YlbYY7u#DLoD@_$+y~NzrtM0>7+1`o^!%<4#Gz6nx%!45)1j#*6H%w}%lL>bkPU;E?AJ8F+BF#1h*)IhVyMi_Ov zsP^M0U`mpo15%jKwLnIhv>I@EEM%1`z#gA-uZa|{w;0Fa<;p*AlslXpj&U`@7sC2t z^zDl(eNUPt;1!(3LTitPAQ;BOW~318lc{z8PH}Qizn}}TOCKI8urso=eH&5)*=8`` zp2~o#l&9$#hnp<9m0A6^0!0mYp=~A0p6kv&f``RmG&`p&3S1xA1q#Z&mWDQ+e8$QU zdYCmRYx5Uo_^3Kpt2*gWb+llW=!(}qid*e*;K%r3yXT@z9M~6J6s4W)yAYFWe5HLK zLzt|wA*)yYu{qhsS{D>18jm#IH$G*d<0Wc!%;ZV=R!Zbb{^7V)aDh~#YlpjpjKM9N=; z>p{p}tsH%-GWJ_W?06|`VM8Q3<;UnLcV=dbQ(dHnG(Sljt7YptrcYv!i*oOTH}{dKWA=+9*g{ZYWJuh2k-7#a>5t$bF)tT%YE zXknN}yshg~aR3ihYrf2JAi1;`U>8O3G~wXHJT%z47}=uULl5)|GbC{@3l!y+B2*~f z5DjcU3lNj0L9LvJs2$yYo&PnlA$`0mw8lE44re*ay-w$)@TQd*clNAR(%5uPdB1zi z$VV@;e2am|gwU=bi3Ahc2-#RQ@Nj4ZR|M%yV{F)u1EjT!9~IyGxH=6o=bI!9tM4V9 zbj_g>xz2R!1`{swDfWX?J_xn2!x`6(1sn7`%cIC}oA8KLKFZ6G`1-{Mb%Gh{twcVN zq6VA;DyiF|ZA@EJ=2F1GleU)erF@D~9hw9hVXb^lDkhymJIUFHVbQAc(AH!-KEV8w zAjx)Vwy>U^Iw=20(<2uf(23nLxb!{&gdH4nxP_*xYF?fdBUT{!B>#)%AdnKLLoAd% zF)T0&Lw=ZSZHt59{(K>Bkvty(DpM`l82!)rC-3lEYU$}o8c0{qipkSGIh)_p6+1p# zvQ=^Jkc`a9Sh>;&={E<<*3Q65XH(xKGsk_s8o{X6xD&4X*)r4CLE#*tde3<2Ftz&J z-bRK2D)TE^O0lz+q_}32BSXH1giVjkV-(CZqm^v#z3`3d>Q)Jlz#WZ2C|%q+1=V7( zOL<5p{(S34Nr@ks)(@gEk0mIzP1K$3)Az#HKgrY=yXS2rUBJ+Y=+H1-R5Fa~QBCT! z;f*{V=ue75&_o`g?M=eV>fF=Ze+=&v4p)Cx6@aLwjlc>kTCyq1q@mr`ZM7q*a8^Ly z7rz}o$wn8ZUHU<+Y8&|JQlkt+Luh{UZ0GGW=pkwJ@fV_I9S-k7!Cuo$&2Vpl9RZKd zRQCZ-s|f59qfG4gNx(e7C8Y721+6zf4~s=w7U|a_o6;>swO!S`4CNDZwO@EKZpwjQ z@Pb_6ThX|78nr(WG{ROYB;F7^oFX=zE~dK9y4#dXex!BgnaRaZU$J?%%%?&@hbFD_ z%Ej3Yq2$%}j60QKxp?1@dHrs(8ZPvf(sVTU+E_+p@nQTY&2sr@D^;-;ho|sPO(8yoxcfqEqX?w-F68l>x{*l95$+F#fzj1+VJ-K+ktL;m{t$ zn*%I&+651%T{a&pFy@uVK)CaMp}j?{^FkcEfLYv<4xTgo(Wqm$#Om052eiCYmD5DZ z&ijs8rrC14S&PxVisY*Kk%D6meU3**RHOwGs&qZsrpG0M*RMk9!HROcM%3-mu)-(XZb)E($w()#z-L!EMb*e%#1Z&iG(gpF+| zPXJUKk3eY3l_H->hMO+$C1jVgFKG1?m&zkX*b&7{SCJIYlb(0r-{B6Oe9N(5)5M=Uak}sB*b)ZU~ghv z(IG(iUu5B<3fH9T^vKy~ats%hi{$1Kr^pY|L96c7P4Ov5#}w|2zlD{iskUo=IVpM& z5&@Ix^_sV=wO8TrX-WhxY#pk%*a8z;q0z?Y<$dMxBn;Zozj{YZV2o7z&>-DtLB`*fMufc%%(P`up2-<26ztjiYl_%skr?=WwAIm-DJTPl3SZ?3yXxi-;#GI?^qq0Vz>4 z17s=BFD^xg9QS3XB!9=mS(}0@iPiJn9F_P{+q@xoiB?Pdx_epH5dJ=0UgN)10zR@>e3E?b9{{ zu=7O-DJXpk$DfkL>3b_qCwqJZ(UJ*8MzM^gggLS^N`54;Yct-#~H$Opm6;`8YGxoQ}nH}tDm6C{>AWzyOt zc*q%{(5GjR-L*c-SM-qC8rWtpJ}eyPLfs2(;`=O)&pfpP?+S}`2*d-mA)Gz(@Ft?R zt2G~BJg^gwVe2)myY~)kl+hL5HM6v*|CE5I0N*l$uUwYfeSNjeS z`)!3Mh4u&uQ#rhcI;Damwu(b;3wdYGeE#~QH2~Q}43<5R`+2?}n;|>zyo?cv{eTw- zriS0vVZYvMCV^{zOFyle9<$auzW9~f7(b#M^>`otrAN#T%&-+lM;i#CcGV|Kq`IIT zf;N?5q-`97b)<>Z5tBoK^NWxKcbHM5957zsdeFKAo1-weVs;pe$jiL8B7qK@+Se1& zXa+-)2$2@;Eb2y4lmv>Y)31$JA!c467rmo)o3P%2aapVL?BrhZdYJdl$-%C~;;j&o&8+sIuC5Hud||g|)0M~D+^e+JPOja>HqYSdkF2!= zgGe!}hQQ_+Gkdd(J=c=$`tfz|1&_XOo>|5>oW#%Vf*atEtQXbgyN&#ESLSPS$QOmq8~BiXU;z6*+xu=JQSQ+JU~{t_=sVL>ii(V-}H6M-2+xf>cp> zIMCfb4tePxIM{PVzTgVEX~XBfSH@ArgQ?rgVuj+KEw;e1sYH^vCBEZf@jht=o(vh0 zn~>wHx`X_i$*#mR0uKVRmx_9rR7y)Dk54veWKQB*0V(P+L<65F)^;aRpkKp|uzBQ# zo}#0DW&>}U>Y9$o;AA+UuF9WZo{;{aJKq%kvUXhy@=*89D=Ub?a*T7eU=t2h+ju^F zT_5)2dY8%7pe$0{d=*6%?4Gze7XqdRlwH+q2?g_SN?906dm++;hlki%IqQRNO@&Q% z!SKZIOzqvXZ3rpRV5U&ucY9@~&?Y0Necd9wZF3id>w>~;lKJf8M9mK061%TP^D8Kb zef?xC;PJJB%t}etmuBPK6ZAmAKR04Yp&^}d-hxC0@DY`!5%Sq1AU0k}@zaS<{_efl zXBtzKcG?TAhz9f?RcZV09+=C0U0L^`zEC%$(&r{GWIUWFL1Kp=f_aO?8DHW53I-`u z4V*tDLS-;4uBl^929^3*t!}ClMZqHi{2n<)AM5OlG$KK6{1ii(a#N**5Ev=Xup_*I zEX8BvB%cD69?VhC-nAo5&*$&7D^H~kO6|04QqmFHP9^o}rY89F+v6*7?T|%yH4v}_ zE7|Rc_i_q_AM$%n)CxcyESmRZrjxoq=Pt^|TMQqH9t&kO(dBN?7O_MO`NhuVg&e2`KMd?Bt{8q+~=86vNUk!`z}G?0+n9sB%)sDV^{OiS*9!yH7{@mmZ){U%dVb_5R?MpzGt|H7&>z1wlHDwoin!&tU!a z1pS$dTb84Jqm{4~VT0ck=J#;p?w26bGjL)w$3pSqz17UwhJQp&f<52e$)-SwkIoJw zl3+6_my0ke)>r#ck&~DB_0+Q~Vzkg@UHqpJX6b<>II!X;$L}{tsz%|S$N!8RZ3f;J|*8y zv-j+r-|k1;Y=AN`lLUfxzTlPCpSoT%X|6@lc?;IY1ayVOOgT^2PUUS?)o#U^i0_9i zTu0o-kv;+dSXi&KzyNDt1QPnyF)2_WG$5e-t!3@@=)yKWI$x^$+nv9bmT8PRmo~bD zTUb3gZZ0YLI@35=QnR}on^ZU%wOiL+*w_`uz&o<4W#t;GZfYG72->_;5iCFmzHkm8 z0sxSiz_J;Anjg)cZyn8SUCk)h%|rk-s~&!~t{r>w^`p5;&Wi+D79=|DR7aDT0%}$$ znXClJbk}rfKOa!P9H=m6P(q(aKK_8{y+`dCnBfFzgtyO?}e)*?u*m%?G=5O*z`2edwRd!QC4AjE(XI{AQK2_nUv53>yY}6 zXY1or!u*R;p2vY6(a9ttr!Wah^~>vqHMv#|;cYFG!>CPR>D$x7>7(4Vy0WcXIZ`{L zMdOi2Gu)UBX-RrtJW^m~;VGc4ww$%#wNmA?CnLF%QyG~(_IfAiAJDb83#6H<)E#XQ zuNPlD*h$;|@vFy<+50j@lULpkJNe-tbg#!CXGM}dThN0wY zd0vvwsyF$cYcB;lFx7re)zbU6b@2G|M z7#N0IF?1Tz^kwo`N`MlDJc%7H?5U1E970xI&R&U>=N~t!|BzT>?G{ zi2LohH00cJBGqih8UXLB-)vMXOm3E3*_x>%MGb6Y*y6F)mhTS!iL>*b#!5PiqhZVI z$~m()Do1J`!oH-CrLC+9)HTDH#iJkwaWSOy-Fjc6o?NPaY;+0=vs?I+Cm=_x2Z|CR1tz2#D!j>Ky_mvG8YTe#^)P^=aWIVm1W+!q?2PpDdy z!?>rDk1u3$O-du}p_t;`9-r~}ifx7sI7ctJyM|jq=E%Y+ZHXdcB zD^_NV)L~*WNzzaAmMIcvsT0)5a$murA&+jb$#ZTbm|7gO7-y_K@f>_1uX}=w2i-cq z3Pgw{kejSq7cPDurWz?n7QAO!Up7fOsNC)kOZ6%f0n7IE+-wRwcoT0G;tFO) z-D^=T48wu}uwoZAI&#b^nC--lEY|;+K+tdXLkEM^s;5z6fD1eq!>Mln*iy&K(k|_n z41HBF3y`~EyqV0J<~){HJ`eWDtFVWNBZG8ao-{tJXhE7?6wKn9IxDDEEZ>{D>*8Jd%etAphHkuB|@oH-*n(2lBVC9(vdED#>(+ zPWLRJ5*Ngw5`y@2p;3Pe_UJ>x(r>Nf7auUlUg8-s^P41)A=Q=dZCpA!A6hLDt+LA| z#*1MGMjyYYqYw){pTOjse_3HF?t+M)T&}IaG?+S%vc0mabYi&Onw27s-2Ub)D4cg! zv2j0;48?)7!zjwIEmYd9mTo6&9S)IGqO9jjw-v)dq*XUur=Nj_*7SNoq8MageL`!0 zvh=ahxC!Zp)kZZU0?{*yOkC1cD$Ycwrn!BkS6oW_jJcl4!AzQ4A*QX05lbN2!U4Fd z=-qF@_K4l1bn6V*o*T-okqm#pPB+? z{(?uujG%lulY0g%vS13?ZExpbCw;v|ZPVT!z-7_e`l*Z%Q}ihmEkjcw)QY*k5@?3z zgSF{yM+-+$;8+kBO9(v^)9~_Wh64SDZUE=kgiD%|+x$8vZb$D!$mAfnCLfV2pPBka zXsh$GcwRb!mARyeN5ckNa}F3e?TU=1Q5kc0lBQyCI8#`ON-V31H9%9|#x_cZEj~tG zAH2g0*bA=kBxYBc2!ebgIWLGFNJd8Rn9iJ;lFOm{NFZp346wiUsI0G;DPY={^i4cI zI@8<-nmOwDp32#z_uHhSC;IU_M3&tvexDsqgxF3h`}BkkEGDu!mx;D(`bC>Q4ahLH z&4+doE0`V5H80hmcXz>?vI+q*w&HWnTiQ#4-y~r|M7$m)BxS&Go6kv90$D00N-P3< zz4?s;&W$~kK64y%dKg*grOr|DLA{}Ltu%&o_i1DoDsfWT4zh+23WO)N;n2cKWIDmi zUbup8~!V0J%e5xsHP@-#daiW)*n9C+tON1&Rc~%Smt}T>mS- z?vjE;;;Zfhe{&Kz#E3o9Md^CLGSqueKlR4g?6Ad0d{W}dC@;3A&ex~wqAx^0=O+j8 zoSH?vieTcMugR+RL8b$fjsF5|>nv% zxEn^)8#(2^009s{*V&13z&H9 z=*@0}=T0=^)#^QZHrcEYR>9P=P#Zqx%0ZpZzE}04u)l#zd(QQw8PWQoedN2vehh{S zbg_5OM_Va2DOu)11^5`q*9J1I%fVlMa)DlWpWt-{B_+(zU#IJ&lz_?0pGne~AOl^; zDN_$LN%cyYbPfu@dz@t77=x}Gh-#|y`G`(vf%8`+8erGxC=cKT}~!RUv|^lX+J+VF^7FRJIUc*hvsNK$Y+Yr z=`FWwRA)%e9qe-$9`q;_)uzR3ww`gPN>&PI!A9s(sb}Xso%|H9RZ!zfm+0VSyccH+ z!K)XJRQMZjRyZO+;} z6#GxzQqxEQ{VY#pc%R3A9DSYV;(2jMiErqwYZM zTvm6f1&%lib=g>dzUEcF&^HkmAB?!3nf&FV%`$Nk#7C}L zgxtM7h-S1Omi*i>+54-v(JIqg>Qs8ss2T9EUAi#=E!HnONh1p%KTxh! z_o^5o|N2P;7Y{YgQ{>@=pD>_0YAqLy^#qgyCnmqA;4CiV%p5n_9-a<=x&XtMTA>0~ zfhmX`Hq#5mOPMxA{%T|-)*AEyAjfSv=}R4)-(V>*;d=l+7kj~rRf*Fj*fi?8@aC<8 zUFq_9HFaZ`*{g>PxSg7!JS{SkGcbNNwW$PWae-szqRcd*L+Xe$g#Wj~c{cr$J$g#||a$w_zoQDn}38gsA#hiNTz=exy zcJRYD#5Uxrr&WOn$J(nI+2boL5fAJx4Ij&cDxxvtKC3Bddzv=&DpI2-jkw64qgORN zc$m=nL3+khHT^M(vnTp7!3L%JRAUn-odw!^%RaNL=Nyy!yX+9nm_kU44x%7X=c$S& zY%7e`HA56^;uSA2O1_HM2n{Z$Lt+Yk?86qO;A!Kw4Y8k8^q(AT^;FV!psmj0DiAl( z7Wo#b>?Qu9`+@MMN!nFQk}1xx7$rwbLOe)A#V5ua@a4mvHR0|tG(2Mm zdQ!tsw~%b}t<$!DA`IpY>xEnx663d%D%!2xEpv}kPOx>VQ57w18LH3fvxvEZ6NJG| z3M+unT*e<;5YKrZ0!<7G>3LqNpoyl6K&`|$8+L+Lz+oL|6-I439VQiuy$)BndftMp z8m#Ee2SvW!;v+kt@%*FSGpJ1eWHiuc2+ixo^V&hGh6*I&vdI+B-&Henmq^IiscUY2 z!$?vj{IJb5QjZb!HA~n%P54RpWYMrRTCGl~H`_VAj7WulF;G)6Ed=rdCG~z zxs?L3y*5#mq+|(wzmfLQn#I2y)XUS-;RT zxKe2?d;DaKx=Hywz1Q>vfB~a#UP7n(G+YA*+Y?)Ca-f%GG~%2P>nF2>aI@Ly4y5nX zsinVFN8qb6(g_#}_@c3TP&_0ywbf0t%zTBtEJU{5Z(O_?;J&pr1jF_~`6*aT4>zFNJ%Y8>&WmbBO%?!Un`jw`rG}8sB%ohe6 zbBev?3Gr@gmI&03t)mlNf*Ok<|8Nj#;T2^KY=TApTsc$5@sZ*4i-7Q_+>Zk1#+_#} z^HERFrc#S8-!*t!&f1uP#RiT8N-f?lvJ9cGFk5nz)u?FE@Ml(i%1=EYb01v`KS;q&H)QEwZ|;4l-{Y0H_h7?d#(eWX zjsKRi<`y2Dlg#PQy7^3|_o1t7p*E?=Cc*RWK4hlY4mfBSW+pkSeG+<6+ROMlawR#| zfx1nhOS)cDvsAV#(V*bHt^l{3O7R)q5tsZ=oKJg_hcAc>Y&$$83e6)w$gn%}a!Scc zSY)pRxs-AlqWJL9tBKmt4?y5gky-d3c(latzaej*u7TfV)Q=MeZSErBpj9E{#yh72 zCz)MW7!*2(oZ%>eGI;!T=~LMi(P1EcP27^WpzwgAywdn3%BR9u3~6ku7(!8#3!gki z9r;{nQENM#2`>FOG<2UZZ5~tUdSq%bZnJQ0i6;%CgsJ=9?aQxf9fusRiFR6T)YthE8G zwZgSCJj;X54UNeY^KY_Fz(6_=11D02I_b09yze(idsxM7tP)l~kZs zwXf6Nx$czClwA;$sIw>kR-U+NS{x@d2cG zS24YETRaWL2`O1T2uK86ngj&X-uSR_YtJ9Ln!F58>5)GT4<<!84SkQ zOLIE)@iKFXyA2Cl@NR?t%ery|_jXN3@?Em-u)P($$QJDl6gE${*O%=BT?IB~KIaE5 zFlB~m4?AiF+nQ+ybw|D;IfRC{q)MuW>1*shsVd~awZ}GrM{4dVD!~E&;_E(rXljg=B46p<*~w<^3q6PlI**kG z5~|0u8B_K{tgLGg8mfqhhSZD|gFpf>S^!^d9@BvHJ8XZDF_<|s|F?CN^m=b+$)FlW1`_;STZOw!}xa_pD!xb)x_=s2EP-**;NscA=+*hj)J4tl`D%=BY*M^|C~~82b3y z;*tt(=)xz`lHPBTzxGS;JX5$u4ZeQRq}7Cr7=48=fFxv0Amp8h)~qLsHmRdTCB8(4 zT`!oJU-KaMhbl2I1X&{}Il(1Laft%=keVULUYQdF*>A<@lkadUW>r5BVjhpl`vh_3 zvvl=Sk}+D4*b}0KcBD|!)?yJ9qvwJ5xf{#_tY3|nhtz$V`)PJphS5=sj`}w2f zg-q_$H!M$|V@0U=9QnX~#v182cI1rvoCQcn?uyit>3%*QQxNERJ6~~XSmmG)P>oLU zcR#1N*ZjNAHu* zPSisFQSFgCFJ*-s8J|CG8*;j^Q?xkc5P8Q z#wys7I!_gb$KlQ&EFP{Jm>7#b*en*ZjD@0*DHPo7VkZGcSuD^(RCz)BnY*X+kxX8y z2G6~CRv11f?DFtq=QiD@PV=~>nZcfz^M@zNsF}H??+Zt!uI%0H!o}YfEJvHjQASDC z1ecURu9tm@Lkn+vVU54Qa+{oA*U7%Glgo4Cyxj7uMlFz)e^d+)=2ZREvIN^f*poc@YE zk@`+Odyz|AMK~5z-=YKg>ZEBZzMP$)Ul**H1IuSF>IZs+TMpDh;PsUKg$+&|q)}4gfnM1^VD1R`q4E?m$aCmgIjnj^gloMM|sF3@;AEIA%tD9v)ob(lX^DxYp zOqxsR&i1W$haqqjen>bm;9P?7Jx+Ou6B)B}FdZALfa&ox7Q(hfHoBYXY zj+|PPsvMaTz+0m(h=8#toTFMn)-N?bq18v2&N$V_cnL0}hJR{lCvSXQV$<*a;3;|4 zR*7B}1=Z<_aK+)Vz4DZoweqy~l&o{OISFxh1-s3XUAI*y2=P+|mMe+nA)W^P&~L^9 z*Iz-S4(SX&85?-AR(dAuOL@MSAuP^zg5+nH!OumM0fzvE%mh#&hF&$%_b*oPLbf}6 zH-JJvtL^O$8(m`^r-5prM|#>oVG4(~`wl3~^|sNMw7ZQQp2|1W7?GiGk}-aJfH21g zYiJ*$vFaM-B1%X(Vts-sbh2-Fn#&hfU_R zr{ByQ_c?68!qdy&CTYJ$kckKyW09N()Ym4%>#-1=UF4RSO{7Y97@@J09u6Vclq?y> z^So{H=d-Fn5>-{1`b;u$MRB7zG$blBxM}iMa6QIE1F&)z?i_ zcRjDpBO5f|(9|>Gd>vF~?ulf_JnA7BMxISc)WO-F1-t7HW#qqA&&Lt>cK#He4RL9N ztMRRxNykAsAFucejDGFF*VY~WG0;gH2~FhI{^649EbyD3Ob%0MAIv@Wi82{EeM=Bs zX0)LCik_kK-LN~ehC_735E|69ktz*q-7YtVbB21nIt(JArHU{&U0n5qw^wk;;+`tQ zlmT&1?4*xWuwd1ZBR-_HXb8@GOyrM{FArx=#j>Nln3M%M&T9HJ8S!Fl)$vJF=B3o$ z+cNcje*g9}$6OF$8f{vU2pT#HC=X()u5?Lf-&6O87vTKQ4e}qB<3j~faDQV{VrBf$ zcK$^)G;7Qb)}j4CFDN3cW_o!)eH2^K^IUhqngUCN%YR<>nZA{JTzDt);|b$%+?7b~ zbeH@+_NMny5(%vPO(1#@48E+ek4u;8TMef&zf5afR2BADK9S!2k{2@?8)wPD^)S8L zS@_-2vy$eA&w1mEU}1)Zf(x2<+6p4@u^Ht__Al$`WtXrKRF~SHhjXo?wZGT_-!uVt z_IGA_IWcPf#MyJ4WB)?+3w((FiziTy@A5MFi>F2V5e7eg;LA|l__m_xn}K^$Z-KSP z{7C7n_$r(NF9s7*X?yIP7FRwsBnJDDbM0mc@0*OV5Zps7H}wms{71W9FS*}Eu3%o1RRY6}yG-xWLgCou9ov8y(EuK1Dl>kax9IoDgSPS3P57F(h{p zD87n_z1n3LS&&e!xK)P{a8dnEDz#qf=&C;eeu!K|l1p!ZIm~Ozs=ATwk=8q5%JNUV zmxFqb1k(mBYpm*e{dc}rG_M#u=5#*VI8tU1QRT7T;wPGSoK(o6-hF5CtZc_pl~sgA_t96w~mxim?(}Z&rHUb^CEPt`{tb zdn|BJLHs$3iejT8Q4p@%OEp*H&r8yw-6z2!Ae-{8pw$rr=^nLT0Tb)2T3PgUY2F49 zo_&2@R)cY73tFwXI}cq(!vA@xxLrXS+hFBYfPxRQv5V@M(0GH-yq>l z`^jf7v{Q7EQWBS7Xz&%(8>IH^#pb+trKVGnk3ryicoXAb>3U>q--w5K=+pXQEi5Ui zE(gUeT1ZMEY7Ojadm4F8ew4B(1h$$j6_ka=r8z!x8ofOnvU$3{Qs_A;Lfcw1i zk>>>x* z4pJ&AjU%Ga&&JBG|5pV6P6liQ01W`}Ne796_W)eZ&BTsIZ8d?Z02%;*QADJ1p29>3 zr!()Pd1hZ4Z&*t7JOoM&DYfz8nZSa@%&`n$OZhUM#_MrAs)IGa2jV(G!@!ZuLlnn8 z*UHp%Z%l?aZhH*9g#ma9kLETh`)m!s7Kx-s*=zBo4Ayx#CR4(<$fsIf)E1E79rV?~ zSIEdz?^>H}4v*5qPMEn6sPmgL78ifnIQ7Mrcl*Rz!34 z>G2@V$2fXT6|faTr)T&}PM?akOXsi3zG_2xFH|HRs=mpr1n6Cg9X8v2!w~P z&q*%jlPvJ<;;IeY?i@Wj;%QJ^Ysh|&(Uay(qSlG8MfHb{U+`SoVLPmt3#TQ-@ywab z=5QC?Kedr8G8XuGYs?D~#uqQadc2IlelSD$?4mqL$Pp;j|511P5*?=z3G1C-8mE=p zyN3AQVR^W%;;f}E&(%sH9V8)qA<(T*$PVKmex7(HtV zdp!obwlS~nLon>uA&9!O9P)k+Bg;bKpy)}%RyNI)+vV;mJ^EDK0n%}KO`sOhQ(3$N z<;jyWA-FI*FD{?$6h9&rO}Zn zSM0AK*6IR)<5T#QmS_pD=3XB1tHEa&N}jPAcYZRl z&E|c;B06bCohg|Zr0>m7K%qoAgS&-p=;8BGsUoRa^hAa-sK*r+@nJ^pV8Q3omd9O# zO&u!nFDzL{5rca9n>RBYpR7J7Frr*XB5z6nIc)3k<0o?LTW`dxZ!WGd7JgA$;Fbgi z7E@#V{`x=dm)dA9VZF+gb#2H($w{6D#Hw^HJFoM-!n9jmq8lZDHM3vc4WeTOlbNw@}bvErYEQ`^wyE z<53`bY+tH`o~-sjq$I!(22e~03-A=U{x+%=fSJKn4sb~Z5MDcmqnp><4nUA)$T+&{ zy-e5@#|nW=1w3!5KS)(Se;=52E@_xjs$TT`5o(Dj6anT2e(UDzxnkF;Uf052heK-L zLQY0l+SjdcfDhDXl$96@HH6WMLBT{EjQ#_Xm(9NX#u47|eYt!6((^JX^sH-wuc1Xs zV*ZLIfibfFe2)z}1O}y27n^MfiB_SzwwMwl@zY1-6c2cpIu78V)ko`*UNb$#OJBgk zWx(NeGzsD+nsnA090UFJJ*|;12vj@AXR(hym5p1I z4*e5bN6vkpjk_bt>?)iGfZujYtg4>vMkZ}1sy(FP-!<%m&};*-u?39>C-ec>UH__v zs-ut<&?LTn+U!z$+%$zZR#@`f8IR0Gy~b)vhetKpR8wUPJ5xlK^h!HW4uwe3SJC_b z0ark%zeE`52!J|0DgA6&aEOX&AC3v6E=Y42wq-lL_t= zlI2Bzv=vuVB<3!8R7<5W+3KezP*z|V169OoV?M_`V<*@T)*v<;>(Vl*iYb=To1>;v zBGMUL$70-Ac6RJcK*X>avn8>c#my&8{rE?bO7s3j6P+yG@Uo7Be|_(l{D_H`(lX>S zv#R)vxydTL{LGx0fK1kgV~y@jZJ0af5;)YE=_A&JVxw0L4V)3LWkq&go@OaL4JB*e zv87TdY zP`mM)IvuhDk!v2Zs#UG8s4f$W-?H6*?J_LNS!nm%|I`o`-nuQY98<_v?YH7`#S-&{SruCSs*BLuC7z!tCtD@%)-r3Bv075=OV-ol{N|`6h2foR>TaW) z(Co(+`Fm;y&lr;?ykg6niqF^XyVdGG%~m_>1-;0AVY4npTRofFPC&Pc<_@zG)3I=| zSlE25w8;DQ7#mB(*2jtq2;CBDj!m}6w-kQ+zTaqj1ng^+&3BnwUSo(p&S%*kW}UBj z@B6w~MaQ)&)fTF(hw!yKF2EkxPkCNTZEFY~5qT9lugXe<_$yep`u3H_-skWQxD63)OaWKU>GNjPM zTjpg>9+{Jt%F_Deaontz#GBT~o~y@CV-8&PSdgXJTH1-2^yPL>H);>2Wce+~!ijQC zx_!b8a+tejyue40U!*)IWEiC(F|N7a09uA4YgmCqYE-AQt9H@SC-EX&IkPi710Y+4 zL6JE8y>(3$!m|MP+OZ>Km{aoZe}u1rD0->}yJl+hy_%E1wjz|tt*3(-mZ0Q^b z#~MSj>Dxpm2vRNY?qnH&#e=NP70N@^w7#%;d8L43v?9uKFsE6JnVZmUR{8Z7IE=-9?qD@)8&P(kW`TXmgmG zP~6-x`*;y|IrG&)cHh5|Bj!8cWfo7H`&{@&V6ihk?CWb_b;XDv#%hv}{yALkBJ)Ww>xm5Wjv-y=J2+C z?`26PMlW+MbMx`drO(>K88X3lK>_{lqg+$5Zu0xG7nuYRdEEJTI%O& z{x7VU0xW`Wp3Ml)ihA0xX`ha(0?s=Y+-+gQ^%7t-wRmlxTWUGe^zSr=0cl{#F747G z=~Q(B!}Nysbo9U=VuvL3GVNc~hZ&*dXS)i903mk`FHRt4DQJXQS53K_)WWG&-v*LT zhZVS)u!_uzY=`t$c;DZ`d(Dvc{xil5^Ie5X`aK$v+M@>&wn;Ze_g>$SXB&;sJ-oq5 zD{xzbEgEXZzkl8PqeC>%7P0H6(-WXTk35sV_6GC{+X(voC~8*iZGnr&h>*&LYTjrW zG(BuuPfC*|>zaWf2~V8>fT-p8mF$rH@*t?|gp3(O6oSa>P^oWgbCoofeBatld^TY* zH;Oc*Cru)kA6e`2vXG~}>1&I1#UTtobLe`@VLB%xIBcLU&BU#n57HaChUKB8kM6+a z(~zs<=QX$IlAePepq-(FDhJNnTARkWNsokXMcMx)F|(Fygxt+z2Nj18A(;c#QkzvQ{@)CmEIxht7$1P-LEacQLw zb`w*gvGg)P6sz8G=b5||UvKbva>mfByCl0p(~@aJU2xNP1@MoVzA{OEeT?r%f@;d& z89l5h-u+=^`p+n}<=2C@z?sfsFEn?}zeLeB2f;d1!v)5^jxBKwctS(xXbDegI^9vi zb%4{8=66mnS_TDutDnYQA1bZC<`_Oqa<-m65p&DR(WwP)r~s#sg6VfnSPq+pkqVf7 zWpG^;kKl1sxpS3aT}Qp4LSjc`*bEHRVeJ^3W zG0Nx}3`#sr2sP9|Aln^r%9lI&igIF%`Z{Bh{U07~5R%BodDu6(vyflu+kVLU1bKqz z0Fbwn?d}`6f+-W&&^hY>4RcD$2u0?|&xU8&=;03WHn6QOyLt}&Qy)O@D zu=VW^*0ienKIm|6N>!;Abtsj@i_I9-(E(t7C29@S;?4Q9RK3J99Xjc;c37Ene2Q&X z$$n~*^^NX`xPw4CG{y|<(4M$lU8n=%JLb%oj*ra0^E<5W4>~;Y5xn5Y#y<5|Hgg7Z z5C|0mu@m+&7s9>PBLuO5UXO0!dfH&Z$#+;V1{IDpQaMg(x-~xsS?$T;h%}0<7FHW(6}6Zr;3N1(>)M z27p%yt90UyOQClAYR%0@e;kxYG;$FMu)KN}zRs{T@X(2BB#Sb`Z!vxaTdQ=#<~pk- zlfB_FL&)wIepTrl*w(^esPDg|$dVvLS4c(C6EGCfdYZ$eK%*&}^`N8n=%pLUSR_OM z0J{Or2nc<`P)Iw^V;k|^nK}aQGnini7u{6YutI7O)o0k?PLJ$e)gE(Fj#V+L024&=>-7Ty$Tvc*M2Bw zc}RxC<^Ve94_2BE1aE-|c!xD1a08Mv?oVzRg#5t)bU|1gl+YWd0ZwDZfw2zYTW{-- zr-}+sg#50dyXwKE6nNi>Ifa+}76JbSvmG9=OJ~#68YE1OIn++$|JO@C)tE6)w3W4k z6%Z;)>N1v21l9}dC*_QiJ`gblI34yxh=C5j!Hxv+U>83}B)yc&Xke5~q8UU0fXx9k z{s?wZDZhCL+V!AIN}%FD7>|O#g%I^Y|3k(D7XSbd2LJ%zI{*Lx00000%9sW;00BS% z06PHtpnznA2OIzZ;Gh5u003YB0002NLy81j3A%&UCgPtZ(Mx&#)MExgt?Hy+5xyiC z!-Tk3n3z7_Noch3H@FzO#4?1#K|1XW!Ec~|?;Qt}mZ)tQGvrZZ`B3v@>5+>qL;#!KsKG0^Wf5 zvMw4aH2~2(>sqkVe}e3rrylCcJ7mb%I>dl=5p{|mk@m5hVbc$-Mlo7{eb(5~RZq`? zSKgeD~gtm6M zooZWntb^OZ{tB1M_5OfY9OL|lEI%VDohQsGZg&l%l;d!Og~%Nw5?l-TZJ7UpG$bf7 zRK4L;sDmP;b>0+&K9}u{rLCb9m&29x914}C)9cmPYUxrqjU?hEdEZiuO;)(gSNn-h zf!UMs(v3OviC|CWjiCRQx$H*rzeJ0E?RTLjsTxv$VBYb~r?vcRN727sWS$AkbqF=4 zlf1@YUNzXG=tW=zN&_Pf`j&6Sq=8C3Yyq~%o{@w34Q21lkYF;$l){3Af2W=H1?*iS zZyoKwkCmUjvvYK$+vFEA8AnzvOUjNwj)BPz#+{zfR&M}&S)-t!58Jpdch%7w7rU5?=KUK&K4KEA;7GUd|Yr)V_$7cT!|0tCDCo??g z%`p`p=s>TIN27kU(^%uhj{ObTgdmi!^(hiWPr>}_ZBgY=2R#5H@nN!qD93_%>N*K4 z79&)J$b8ylje`n!2$N!3U*&=T022ect_5`f%co0FdBj{hy^!kI+>m`| zsjs~y0N~`$Q}aL1D^WkAS@_x^siHZ6GXMaT!2c)ziU=4FM5is;NDyK^e6SdeZ(T-> zf!+{bMh^b6bu(;c&uNmYpM2H3aqXcXZqSJQEE|y?-ek1bkrtG;8KljPGB_Bc$%Kr+ zZbxEAm?db7Vg4IU41os#Bg4awX9gG@8cfcCYSo41KKQcO-}_)|g)@qNm8_tEN!H=X zrx>e)(dQAs!OxarMDf92%s7dis3MDtzL?DqYf96)VZ^i-N#jTLB3*~DSDxj>*tdxg zxG8hC>Qk5sm^oZy(ejDiMexcUWSZyxD`}tqnkmnCQsUR1?@iJeR01Qki&nP2>x}J^ zW`~htr5J>B$f2{8J=Fh5Oq#`bK8k1*>q0`LQKGP1MN!@g3EhlH>)Ka$+-^{HLMJO@ zwpHpsO5P@uyH;T~>nb;XPSk{bsQ^*I{tTMP>t>WcmhkZnyQ+=hyzSLUdqAACLAdq; zL_ebpKj1M`z^_ZmhStrM#4xOmZIn_!kVq1WO%*x&qBdz6k*O-OWM#XZyguPq%meJz z?$RQCQAI45oHm@QcS!XRF~~O3y6jf=bSy~b(2sQZ29O3S@nIc8?TVQIVi+Q~zg3Ef z7_6e#fJe38Kr4nyN(uemNhTI?6scmK@ZX2qiJlBJ;V>ng{C8Fp3s_mCEkiQ8wAk1M zkL1fEJ<$14cZ7QDj^AoS`p_l#DcUak>ES2-$7;wSz5S1zgRlHCXjp<`l$zIk1Pm7C zsG!}45zF7u4pFnmT-`67P6VsU>KbV2>UDkIg0GmjK&xrMrDmck$(L|9`$5&QT4=c| zH%)nEyc0=d?%7`Rjq4YGBzjZwnH~m7+dc5fL@yQW$}?e_dLokIC{6hp`8E~70iDDk zl~8J)UT6)U!%NAKkx>iQKsy(axD9DkU9ad_jTlq|w?S3DqJQzJaTk;Tv=abGK^Xv? zpb7v0U;x^91}Xp-C;%wdGynh)5CQ-I05l_DH2?s8aJ$>}x~1cFycVa`(qa18iM^Y3 zyBzA*-uoYHcXqpN=dHTeRNmWf`)_*hdwspV_iDE^uqNLcYn5;W?>+D{W( zN&$D>9HWp;z4tWtXbb@74f&pK@7wNOyO}Mvwh&#nn(kh^+wFJP zt}R;>*0=8cce=Lz+@z997f~{hfH{x2KQGEsmC2ojA#5dkEJ`4Qm<_#fgykm(12 zJ$-+cOaucv|0N3(1&9&O7xM0Dm4DKq*vS zgC(g(l>8G1jC5l^XV$%ZHVK8;^tvF0Kx7R1%3xd)mD(B5$)W=f9+Nz!QfZxy(P4-r z%6pvb>uFSk%yu*>IaSpvEJ#^j*p;|Ae){|;dHX_}Unc7%k&TiIVUa1w#ishEPDF(9 z$*7`>1lKN=f)OeZ?b69`Q+z{#p3p^dE5K*o{;OL=+1rAih^ z#qx8ibVP_V!K17fFoxqCK5HjR*+sAliKEI=uu!KSuop$oc#uS4D;&Flg?1wd@l?r) zh^mmvA;IZ-m4%?JTvh$2#ga_gb3(P95b<=jlu)w?viGt<9#jjYP{~tGNqBW>TS2*& z1uGB~i?7NR5RtWY`4#t7m!8Q{SoD=YnHmyd&QB17(nlvy(NTmRulQ zf@l8uukj+6rWa?M&WUc1nU$dsp4DQ@?e+SEuPr_!ds#yyXbMAAs6fSwS0@4ZGj)7wyxJ6y zbk9c>g?gx7WIt}}SCc zxJGT_r|^1AO9w>i()(Qh8h%{Ly+JvH%)%r}mL+wLwqvIctPjVptel!ip zK?^Z$tS~N`1-__MT*maWYNG<^4<2gNb+GV%@KEVJB^x*XitN>91-BnHJ&;^CJAvxr zR=6|=iv*L?Ku3B?mbBRrWIH&9x!o}{7rg9{jQCG`AP`Hry- z=6PD9xHYSig}Rbe0C@Z=JSuThue@iGX&i9ciQAZsQs1mapOexOKqd=HvsBfV1(g7@ ziq)6Sskx!lVRt$bkYqH&s!%>H#{Chr6&J%J4(GP2vj54~zJ(+xEAE2r9AnQH{*~UU z{Yw4XxVf;oay=0m;Hp~8&|p;tiF*FVB^ni5udjXp$DeuuFa* zFYx*KlOxeL($pjyex*;UpBr1u{k5)axa}jN%3ZFJ4sHQ7Z8FksrXoGa3 zrS@++fi+jt#AY2!^oiC{=u~PnW(2Gss9Pu?JK!Ws{QyoIVId3^=A8`A7cw*0Vep3u z%+9*d5h7F*i1z~vi*IDl_MIX`D&Vq!hU1*At42HBi)*$iR?%YX{5GZ(;=5AsoDG3k zaV6TZ00CON)HT??oB}Q-($2;JjlMBBKKJ0b36gx7J=NO?&aSoqtNzwcw+1>G>%$^0 zpm!wg z?5TkDV>#`KYMFsiRI(ZN2Lvpwtz*d-BOTfBSl=iF94@oQM{40#&j1*^oPK4~GF*Ab zbU{JG#HSKECt?7Pz~P_3w?t((isxn-TF1p=C0^gKGC1e+EADg7fXP2;69ioY_&_Zu z8#|{4Z3nr7zzJZUz>c4eVy;>+bFB$PHPmk_tQwD7fQlWOl!=?$&;$QYHd0OU0iTcr zMEsl+I*p|q0g9O!Hr##in0;KOOW~;5I`B%A=ghVGI)_4@BCt)+T9cwABTRFX8{7Zd z(t#vrc-M_0flU_pbp)oCekJ?OdEQf>XKxe^k8&}7QL!(m=vz_IXrGPn?v?MJkfh{n z6MGKgitAYIGhSW6)~w_+NQT8uZG=8lx&a=r}XFu6EG8^#k(yr_`rJ8 zJufN%vSV{0Fhsdg=R`M~cUx}g%I#f7wYIJVya}>s`MP_Gbcf+qXwEHE_K4eF2j(t0 zIO+6T6E0VpgzEp53j^{aIxdHlbkuIO0JFu=vvMs?yXzrYmc{RzCc$J=e4e6YcRGzo z9jdOb6XTRqZ!irpud8i3DRB?We9W7=F`LJoH~T(OYLp?e4>N`ONp1LYcC%3lH%4>D zyPZ}M+fK^0=GeQBK-0A2$-~0k=yJLS%+k)sTbCKYWzLrAMD64y3dB4Q9*morR~rA1 z@ri?8G_zaU=lkOOu4miyUC@$Qkgc4mobrNFj&SXI*N|sPh3%+sBCCqb&7IySP18!U zhT(Jfv9OzVA+s0W+q@UMa+?-{W*qMs4e@HKKrdY$JFTv*hgffs)C!mCOcPmqvaMkU z69e`(U@B}i+5YcWx(c<_FegGG1+WJ)XiLM7py$;|ChiUqT6N=lW#X7hAv7n&6JW7~ zk7LsW$J@VPaDEcG&9T>%*FtCSW!$MU2OHAn$NcabfSTCr;b-{r0=ocF#S<)iQa6yR z&`7@dB5?o*PysEv;&j*(+#h{U#AAm;f{;TwfN@%4ucyF9V*#?#Z{h7Eu5V{+3xatjtS_Unn>68f2t~-=bb)c zCY0NTrfZ04tgGZdqk)twibk|)b+1YgR}x8eT~hWDSm((kZV?tg*vA)h7hX}KgvzV?tf3#e*%zipOe&JRte=jSK(}N=)@< zn%=wIZpd!c@oQm+us%#jBUQa_7ZgYo4Y;3)YrgVyOr-R@a$zKSXCpP&Zlg;Ike|(& z{*GbI%^qP>+f)N3{MAvfX`@x0RUvpn0Rg;4^8jz!%iJ2D$kduH>( zJGM3;U!lpaQ$*2P-OD;)qWu8o5wedb*@C-559UQOM8^MAndHqJZ~m7|22lS+tlHC> zd%mDaBdF)i-*HQWopsYc4w9w#0vjpJyJg<>OGF*0HLWqgi~%C!n&_UIn_)kPvTwEq zeG+hJ9X5sCbaA%LunF0KQXC#}Vj?!5M&EYXQ$G+s;6n9Hwmd)Ap=;r6wE>>aO8AokMYhd0Ix+so{B3#@Bz4Uh zr19EYU6XZ&qU5j-Ipen9FeAAiwxR=zhvklR0{Sq)a=77m&7}?MIeS2NO$hlVXau6x z4c%~`{f_{focR%9+q3qH;|IM%ba9SukxnrO;hrJG8d$sXH^hDb#XB({?#qYVe2y21 z>REV)C&kt=m%ubuHGFO|A1O5*LVtTdeDwFAoOX1>yUEcIc?DCZ0ICQk-5DeNQ?Ag zb_)iH@#3?4=79qD6B}f8F@=!uk!5@i`}>7J4EpX`!1fXSpCdkM5qu@ZW}Q6L9n#Bg zFGqq`Tt(`+HJqW43=ZlP<Z|SeQWfm%CP2wX_XBjcLc(*@*}jtVjRf|(^8U1X&>H)P7dgCU+lM@4mrz*Sd6^c-a!B zq-I`btx6Y4)$C%b+k4gycFPsMDW(H!t(Ld0c&%9B_4bc znrEQ}DH`8WU6e|=#!Cog%=jQ{9Rm6ykqcx-jxzQo1LmR&;ZNq+MrXu68USu&nvJvu zi|KtDJLL@6N@wOTP4@aVQRZ(Xj6c1*%8n){5<^VWZP$#p*5tQsL&E6HLm&MiXtc&6 zVrIMKOId3IT3;R{>`@*!E|Oe*N&okdhS1q^y4<$=4Hf_mLA1i(r8l--(zKY)-!Z?x zfx*H_BZh29G%0MkMX8(p(RDE+k-|luB7}j2jO*`OE?US@OsIM$igHpFj8I1~?RAu% zs)eFdG3s=qn3+;MYMb3W>d@czqk!%5Q6-js_@V|vi4KL6cqy!boI_WyF(#!u3mFaP z%68od4pbEe|IUYJwX`;}8yFDw^ldsc*e40qy51a<#SmrH>iNxR2%05zE6z7-8a8BT z(9Lc^I?$JwdHgpde{^oH^H;64f$Rs~BRX%{QUFnUH5Ly+}^Q zje9pZXCD)YxABkf6U8#%u&m)viNLsyDHw?dy&T-OQpJ@cqSJ@n;)X_{92^uPrOu5l zMUfoZL7Gyp`wWRRNeIZwb(&%B{EEo$sj&^Y4pvT5(6j$rn4<*1EwzRS`ldTS{ez@! zw$;xJJc)p*tnFr-{sFlv4)qFK+I{$0!?dslLk8Pq?~Fsg0%g5w)1~5AO+Z?!Sjg*L ztz3>e2o-F8J&v4(E`exZ4J+Iib$u2}Lq+A{_2N)by)gAhQG$^@>b*)MM-&Mdd7~~+ ztwF)vqN)_M?gqP5lUz`WXlw~V(UNtLY+6OTnQ@@c+7)F{(1Bd@l4wUPXrP8+T<+eh zLs_whXr^I}BW|_H?2}gVIg`-mW$yqdqDng+BHDSMWz-O%YsVZv_<2NFlWr|X(056W z6ONTRfL-t42)!$;K6y{n5ZMJ)V9SY;VMMq9<8@?s?}~J|KQVll5ftHZv@;xB|2!;K zbn|4lFwo{N7?P)-j6MHzLMZA$DG#o5zSgWA51E5&Ur*dtp^NZZzKu>bq7Z(qd4}qD#c`)G=*qoe~ z!tlagTp1@*{I1`g;jj43c_H)tWB+B#4f*hoHwkNR>^HpkFJ!rVlNiVKd#C+m>$q}Z z|BHsN{eyn=-tQd!;~AGc`X^ue1GE0|^2>f;)i3bY7~asX<}zL!y`rjMy zCB3iWTr)6O8CyQW0f_MCA+KJ?m!6m3BfVwr$G`i2Uohle8SZaBdD(ZIa1R~>6a0m9 zuECZ;NTT1*J&Lz5=8xQa=VScl_osev<7Rx212E>_oO!yT;AcNe+LZgJKiM$^75I#`y@BcXM zSK04@PwO$fZ~kqTXY<3LCotYlT;ml@p8L<9*8>hZ_g)Y4pVoc;0rUDOaYbg?6dzgW z$tCUtGjuuIpK@q_h%cODn8JK0;U_;O^Lu#{?!k)C^AIz;p27=q;m_E5aPS*%`14Zu zl#@8M-u>p`!+oI0^lN!o=qujw*w;LM+WxJE`TgfJw*C0Wt0R9e;dk6IJ@d`ayo#n< z`_AH+SXYq*;3Y|nfP{@e zg%^YY=?77s!1{&YLx^NTPY+2TkP;|BN(KOCX26OJ0PX>NlJ31~^LzK*HbANbZFO%+*17h5N7>qIFMF%jw%Xa`>ej`J+f!|1i;J6YWJeYe zFJ97)6%#&q5)WX801WU36hMG}ApoHO03i}YnkxY7J$wE4y6gRZ)-2o0mXo{IX1lRh zN;k5bH4_bU4G@_qV z)_5>D9(zh!WdZ_dA8cs5s~05piu4W~vCi(cyv+{rN?LWQiMMrd%-!~9^If*w?FF}t z>=kfE8+F_G;%Ptl=&NdhL6$6S%fqfWVm>2QRd$>&v63&uN7Odp1i`n!Jt5d5t-L<0NUcxLLVD0ZA zd&a8U>S+f?@!3o-c~M1Kz}nijOk!AvA^VGqVVg|{13l%BFIhEJvqhUst6Cbzuu5co9^Y)II@&JZ^>@@)9n5dBCu z!SWFJH4tn}*a(XmZfoS&@US5}lIxLn%r|7D9nIBAL@6gDsGKKIXc4Cn6pWz1e<3JA zO^Xt8#yEwbhy;ZpC<;MQ2*8splJCly8*x@i*vK6s_W4JG5j020Lr&6&mS~JlAt)lm zmVb;+AyFLxGNVMpQBi&xf|?!Oe6t^7L^12MoYIYyEGyqbMwUcP5)zTbMS({v5mB1y zBxI@cWD1Sq6oMiU6osHe1Wgno0H!nHwY(-iO^ud*?sRqR(lJ7}o5sxu+TX(Ic84I3zPNi_Y8279$mx zyq$32PXjWn(Kto8YQfb8orc>Dw~Vx5@jDS0ZzQ&=w#V&b*7dhe%4u!RDHy84+m%c&w*e4Hp$QjH( zzdOG%oAJp$c+)2=;Eq@NGadQc!!O$}yS16>)~n5q;T`UH5WJdjaSyyN0>r2xdXlt( zd8#ZL1<-}v!T-)h%mo40%Nn>IR8IHSFxuL@DJliDmwlLVcosLul-eB!-Ny&`afSw! z`rBgC!ElVr6my;OmZuzMCzbJSO08C4%HG6l_^J(MtMI@-oZqPKTBElwygR$`YhAm| zUugPsFN0ni--7983p=^j@q7B7mBg`^@csL+M42;JL%cm3ANzi_OEWy zr}B%2v<2UKL;~{~eus?0)1$y4hEsd_fB6rF$R3e;GXFNw5e^Hl9fzSFQb>Z+DWUhB zPX>$r>eVxC(J5 z3D?AK9v(Bc)xnY5?DX--7j~tIR*lh$w}|ev`Rfqm!KD|UcM~~~5y6d-U++mo>OVl9 zyKRlev5mL2m&$w)y__5~dRZ{)4c;%IRjwRon8N|+L@V=HyX1j zZ6eOnR-&+K+PZ7!2zr?UhFD8qpv9XMl0}fOI8600IX0&mVQrx?6U0!gCzIAYy@8_B zh=nHEn2#`EKSlcrG;*T{yzobSJtz;f7wlb;~cR9;#6C5>*3z`cnS0)Dj=gS0) zRcg8G)h1;^dlkDdf5NSwS1zn?RWYFQRflB6UXYttqfF%Eu>+zBefBWuMm-O)q}$F6 z!Ij%^SW<^FOq6~dU&#?%O?s1Dtk~a{CwA5c0-R8Ofgu@gsT_?=jksMz#u?%g_%s}H zCpa_hacu4A8s#q0^R0WGHXATm$LO3umpDJ{BV26JVQMAMx6A?9>7Ry}oeJDnqo{UU z#9qghq<#4H@r5MuW=PWlu3YvZjVze=j8o3<@a%L6xzlGBQx09qEE#ytgD)DuUXI>; z^%JD5))zGG&s#wg0*s@x>7=c@by!85nqa3Y=o7=Kn>QONx4;?qLwKb(E7q;Bdkeal zEYc)GE*s^3Tcn#r zoyWQi+dA~Q5USU88vQ)4CbXWe%sWv#D2v`S>K)K<&!Nf^m)nD`9EW;PfE1S^tSaV! z7WAF3+@uLFPN^?w1gOYb0a7yT#AO3>(mEUlbwL-P!g;53)Pt~Sd`If&jF1oWxtuQ3 z&wZI(JAEUa3^n(r}=d zQ;}Kr3kb0?SMb%ex{QmPFPCB>!9XoBGpWwGQr+YaW0a)g2!8n0ANobEDFLQLt?UrZ z3G+|>4xDW>ikMQ*Ciy{Q=Ro_Z-t~sen3Ah^qUQvqsIMwuVzDBejn|z!13L&W2Uq@W z*DQSZvuO+G@dN%TJw#`7_#^HA3`^oLLpu}d-7yFI^K_EYd{LVWobbVmw&c_#3Q>7L zwX!}?YLE-n$n$`#_VS6ef6z_d08n7+&0*B|>_X0RD-P(Pi4}p~s4(}}^;JHMAAXQK zJAP0wUFKz2}i(&`*b z8KtEDnoMho+0f_XHcOn1Ylox#k>aIit7ggT*4^EXKI6TZ`)K#iW}Mh0(k*6$ST!8> zhNWK$YJsp8Z=?tMOYsP91uIn7#d03f50*oDt99U?p2&9XxvQ(5y=vX6UCL!?DqY!P z?A?K22J4~$l|N+t5I z@REJ*SsCuB)ez;c)eLikP=uDaba(P*n3}{o6|sB3gMEAB(Lqow-Hdmbm7hH5&Wm~# z=uCIgo zuX%io{eaD19hT{6!PI-ltYzgUnD~-1Hvh0S46OJDK`0jHzwC&E1 z6#5<{Se?iR&8Ym`66wfP2ux}>y=9JB~IkaSw z?wldheSJ}!9~p_Bg1w7jf@(%pcB37ouj~MD?tfTCvPj3?yN5Yk>+GF}^_1CD)F@5b zJ69Ms#+!SHoykvTg7&wGi`7j8(Ja8P*XR2}5#{;C6IK}wgVsM!hb=gvzv@t#S+oh= zEBO&upVtGHzhw7#qA9@}$KVo*m@cQq6tHZon9b_W1pNGM*OWEO$-TC$%29i~Rc%G| zbM354a^^Ue>A%XzXicJL-MKzeOZ>D8ZRw$8VFPsrN*luA0_KY-3L=lz^vW+}f`?ON zJHE*5o2&M=WijDlk2?T_g`k)4bK%|IU)Ow!sReuYOSTJ8QQA4Iv)Coh!R}a7gfd8E zWg(sin_?jG3x)37Pi4(0K()Cio@y0ZxNld}SMO{!a7Tt>z04=}(e7@nZm}P#>s~GA zGvtj^B+^C}Yx6#!_N^cpnON^buy>ug2)b-=h~HQAqYEnNedM-E?bKY9>&_r^0dL9MK zah!%Twn`(?xDM2+#-Q-{m+TlZk?Ul$|Q$H89RslwCcsYX8hNhni?9n~g9_^(ZMa!++I4a#g- z7;0KjX^Q=1Uma)t46AM5_0EaJQ##qDkg{dZI}rs#_$0yzm>43QkV);5TWRe{Y-wz% zZaHs)%7_JtZ;VzGVPcNr=K0S9^&0Y$F#gNF`*|qrQ(aN?S@a!}?D+htrQc{K8%qn>i;~6pQ5SE}9<4+DK(-Xxh)a$` zp6CsrGeZhT4o2p{S9pMVaQ7jYW&~TSyC-TVT}BD|WUAGIML%&J-MPo%<*{Xec(8d1 zq;mc9guUa(xcOmA$&)RE#D&yYLaNz=We|Vq)5CmY)^WCVJN{N1b>QHItw5Z)gvJ0M(Q?Sc_1*)XWJ zBTVmsoG*Les*?R?+C&?Wm4$H$wQTt0z~oC><6*6X%u*sL_!Af4#bsL%1_pnU95`En zJp_JwVN_^ByV6>uUEm%GzriqAMZgCT=1O<|Gi6s?l$Owy$SUP;EnpZUD5@;p=Hg#F z*~LC%UI6-0RsAaH=>WCIGFTKmU$lZIxnr3Gj@Y@cbp7&1g)}#?)nr-qHpB^T%&M`! zBf;P-ZO51r6||yu1w@@PW0fDqfi`*Di_ckt@xNhopKnn2WlVe{eYICdydI)fkypbTSCUt5jQzGqc^t=s5BDS&vK{IMenXR zRw9%90`1|d$MDxJ()a8hy@sm?O4W-7O<_d&qcOCW0rgCMvY9~1!{I~%^7OqbZ-VzXg!tjh)n7%Kpqkh>;n z{$&w2G3m1#N{3cZJaNp77^!!(_TXmR!{?=6>LF2npn0J<1G+dak(M`y9_o(#M$i~C zS*d(I@~jzLb;SYIs<98yo1?0bIyq;#hSmcsNJ z006h~d$0BaKgGobbEGXc?MUo^1?CWXNvnnPp(89`q1e6)KBGMgA^cLZT*r@zhsm>I$CV z{LHCo^EqCbI!k;hZzd!lKhz1fO8&bMYCmMwF~QhTt{*DR&BgmvsVO-iJ;hY<``EC^ zZNeX?IxHX4;yv(okO(m(YCQ~n%jO2? zIghahl|CQ|dqwqnj7UyQ{@+i`%rk9v4-#h+1)cfAQ{y>d2BV^e$T2XSm&T*FM}81- zv5&!$F0`cP5sinPjafj<&2St}_K=<@S9+l1aonPUU2eSffHC6WctLndtSYRU_ z)ft$Y?aPAcQ66|a@okhtx3ClxuL@XzqXwu^ITdq3hYVO@lo`zjwXI{n-SP>`M1`$^ zx_#Izm&4Q0`Zh4w-~%nA$y<<*Ub$el2Gv>4n55UE`3&aKlm_fRwswPr9;A~sSoqju zFQ>^{BAabDu-d{f$z_5(q~^sV4wP0onhFkm6DUmP<} zyYxAqvE2oNM<9Zr2T|+mhx3>7)%q!ezdHFRs}O2Of8=?KVfd#fNuU=8TN^W=7hZ;S z!SfwDOpUb)h9G{pGS7|wo~7g320LGbIBN0?^aG9C2H^Ag9DEl$qwn6^G>uC2ww{ZS#RF*Ai-nMb}`&<;y`ce@s)zJMa*i=j?b4E`a zHTy~f_?93hYoAav%Ih3bPW?dFNT^~3mV^EJQ4@$TWj;#j#|E-9mYB_pRqzfnV*qFs ztZNM_yP7LJp%o{mI5Fxi_nI1^yjzB)G5%p#NOC+FxSoRs&n-O_Q4L5Q8 z82xPt`Tfc^A<{RJbbV@fAOJ38y%oF?Cvfpmqj&TmP9-W+8>pf;SQ(iXmK*10AkCj* zJJ$$}@6ty-6l8GkBAGUOLzz+HX;6O#RAYLPij-i%ru7&pn3dt1Ol8Bf1;-3+wG3Wa z?A3+AVgoGKF|!UMhUYG0JM{==#CtyI1`rtuv!$vZfR7s4y%HPJwKOLLsaqxR^=J@( z^Lc@)JOCb699i~5$qI>Qib*x&RxNOTj0>RB-Z`qUZ>zBGKBlM?e@~U^H{34q<8%b( z?Jv6_n0%S9U=G}0GKNT4%pg}MHPjmTG1L84@~X!m4c4EwNq>;>XV#Z|)H)WgUK!_{ zmMnLI6bE-8l{Ab*)6ZvAxTL;sF;5BS2pNK&p1jcpB!pTbl`O$gLsIInmS)b)a|x-2 zV&$qA_~$|%<&}QcE4CpU`dmy80r~$lV{gd&f%~8Nz@ULA#TVri&A^`-iTk4n zW&l7<9ey;V!$s9Z^0rh&f7a;#B142LADBWqC*0wOJO6O3)(2hP^5Kp<+;E2-?zqDa zciiFZKhDf#x3m8<1ZR2GeYpkU_XC>F>EHjanD5mG%HJ8!j?Gl-K^gF72u2;vWbamY zZ} zvSKN+At}-2LQs)5o1}GYhzhm2P$(c9B4RBfmMt5Ua&9hSGihQIs(fafP;3|zN>f6o z$ST#;gewTf|4och358Orgi#PRHA4jBdmG71pEb5vD5*+k1u36~C{)dbQWeGtbvB_2 zQf4QbP_Pn2K~&Za5n0$MrB7Hv1a4g-h2I;kC8(hAN}`nCSSce4((edwA5mbKX&cH?!f(lK;EA&Yo+k8mP3DoihyOAV zXZ08((|au^5(LuN(snyRNjp*Nxdgqm$lBH>`O+Y4yPNAv1i`ewwx3RrrvdPG6Qr8s z8*c=8n&4YdCy2DpTfZmBwAI|dCkQm!xS>ywX}`IEO%SR*xbsaAscFm=U4oIC2;IUb zB(;#bh);oPAbCxct5*cEt?#{8g2an_7F0pxv_E{+$lQ-7-D>3S5KV;O$?!a(n{Y&- zKWXrUW914A6|WenS$PG&f)mJ_H&((-7Arzck|-3DL`j&GN}{AB62&D^C?<)LF)5Tp zNl7G%N}^Fr5+!0%D2bDjNfeYsqL?H~#iUUZCMA+6JfWMoM8To?sW0M*-oz7AMCX&< z=M%q#Cnge&4-SP-3CF*GFZ?S%1E%}feG;1x_udf5ga$H_a5VsT2LJ$5<5)vu8WJD| z15Nfs8XEL&*gcS*n}1_>Hn7;xjPCLlaNmX6I!Yv#KgH86r5iqNA0jF{rp!T!yNu zhA^!28{>W)2njew7<6m%&5*+y1q461A*>ds3DKk!H54^cU1@2-a;~QxP*vYubKgnm zpDB`t?^WMG?33Cw;I67;sPA4{^3MC4oRw1<2+w=(*~M|^^WA#G%y|j?#OT?Wz@J%X zjQ{}@6#)PM5e-KHL6l>N!ol7csf_umDyzIntJxRs@83c4QP%~M=Fa>2L8m!DYp(08 zdL!-g30?jYGu3=^a@mLa|G!4n$@y=!=itLRJ_bdJ!`G1Eu3fCzSklV})kw*cA^rv4 z@7@FO1F~LQh`bU3q&*u*A{(^RynsJm__){k1+Vkw%a-tN!f9KZnQ}x;RqXWY_4N9? z#ZSC*MelCWJNc{d?cL|)qEPuN>wNFJpeea2$Gb`meHG!ppD-1@wEGIGx#!;OQg7DZ zzV*mbKUe$DK?Mh0r$HC`x8CfqraYuDJR!qybVUz6hF1JP(E|N{aXkvgcEG&Rtbha# zZLx?&_)%yv`H;bLELevZ!ofbe;f#fASkW6ihJ%QqNmp_Dp|hnYgS!Cit#YtE+&3y3{{EN@_ejU1|?Qk5gGk zO}V?=(;!Og2(rHIfwVi{_MKu~4?JXU-(My5U|_U<d6ZVl~ZWZIklE-Q%gvf@?9))uPe{%_9J0-?-44kA?&@OnYo07 zmehrX=F~8fEPH|91lH#4xpVSRJ1u4u=bv35rz0M>MADyXKN6p6I#P^kZe5qUrsngn zf5KBl097NB0#*BwomC}C&#H(dXVo?11X|jU3au?k5>$;yidNV&%v!Sc)q^Pe%}6R# z%}Fv;ElE05jYy7Ge*G}ivIDa0efdI6?K4VL%}J3~zrCeXO-YKXzV%bL?WQR#pWXFm zg(dUrff<$^-`Bn4JBw92eXUHqSRNjcIma+H_N`Z-H*2;pR_O8z!e{?4bDdE3pIhIW zZu&><=-Ez2s4Vs?dN zhS^?@2Q*G)>LAH7swL{kz!D>CLe@yL4g=MaJU*Z~E$7E?bpU2XQbs_Oozo5=n~@Zj zBm5(6vzB3gEI%U!z-*&6a^9KRVBO__LSr3H@rYQ~$l4C+k2*6xaxmt(T`jB$EjjHn zaEVB>yN6m#p1#guR^pCKupTI_umklGh?bC@b89tUha~Fo!6ZxzdT3%)_CtTIu&q4V{9lbLNgm z_GD?0gBaJS&VeQ~v2iUTcjt%26Y!hUF#Vx8cH1k{lt&gyCL>|h1Y742OxXvnN&!S`pY1sjG zwui;pg=L7sfA6Rp38DR~JW$C|FxbpUw~%#432zva{;mSgcZqEuC#^<&WbDvkC29<1 zU*;!p4$PV39RHfei?ZSm&8obSA7ZGAr}9iTHf$%bJSqcyj}eck;J%Oc3gfQ_?qH`? z6iGzdTsi%kJle#(7tW)KO}eWUmV@RSG5B_I{c=#`yU^RkXYY2^@Jz>rxy-wDZhV4$(D8mNewstJQ22OP2YEa zKg`?TW;`#uh61-uV285emkmafGFC&mJ%W)Oo)E3&vzV~Q8Xo%$SGa^6`TEJ9Sn%q(jj3sHZ^v!m3E4xVOyFCT4b{x%%!PB z#J_7Q#8)CZ;C@cq-AtDzz{^xp(DPh_>kAVkMI`$}UoJW(#3(Z%8xsD*XJbWi0wEPK zB3T*Q!bee13j_?r-8V{8WsRCNglIE7wDXn*K#WSfot#6#t9GTVX zltiHcxi8ZKs9co8V2fGj?LVFe%Zu}o`cB_fHgGz0C&>qNJJ7h2M~}ocmaeg`So!UM zOnvEvZ<7Qk=(SY;rgoXqQ`aCkGcRjx=9?^;#G2WoHgr+cIf}UJu7{iW{(u=&)ylds z+WrRwxUMSapS*i9c7O9VkWNx=;{(^C_%om-G59U-Y_}cg@m>g|`PEod31PlE7b;YH z7-X0QCA(*+u~&euF@FL588#1C7)^~iw0D7c1J zlm0$#Y!odA;GY-OM%3G&l)B-!76(JeuP1*}n;W|8-H_c2yMrW5b@J_!&b&=Bh9h>&~MqsApd5TCOAEBuXLh;T>SX&B5K^3+NF&(5J@rrD8KuFAuBNEAmY3CC- z5J90c0fz1y7{iftJW6OGhv$OWpYC3~_ufFruNjFDPa|`N6wC=G%pF(E{+-Mmcp0B? zk|Ea$q|+q#A|aEQY0Mr1*P|(~*eJbfush^Vq)28 z6e2N_tDh+jwc0aR^H1EUehi^1(tG*ZJR7y=!YZQ2Rh&Bx}vCpoR^&;$c2;SVUiQI#KR?E;P-Yd%8*kyc|9 zy9-ek>@c%%(%OhqU|_AIOFAM@;dt|^*fvmXRb`|BPv5hABI$6d{FSq0C46+IV(aZ9 zW>be9@^Sqi#F^Tl6#3dz;fDG7x?e>>ktYst*B=iG?O1QHNeq03bHLaR`2$0qHH=1i zf6R?!_cD@Q-#@uWSu@Z39PjM~b^Aetl5_<16&mX@4!u3Wx2Z{5GAS#kXFBuLo>p3i zS|lgFXz+N;`_h*%JRPKTHTG*2fHFFru7jF5hxJJeL5M4;BQ? zXqHNR!Fj>t^(J+MCb+Nec{k4*vOBW!H9ehq;tfnmoM9TKUeNmcJ!EsXg(wi~cn-?j z3@j4?cU)zCXUKR$QFV2+)`GaWk^nxt|2-7bA-Rh+IRx}+H4t@|gh*gIVwxi~v*7I% zMfD{DU&y(IJzC^VJ%kGowS<*{^~Qt7%21}Q2;oEvy(_M!w$r;v+|6SRSH~t+G9 z)}S5;#=reIB?I?u!p|0hT&QiC{tjnDT`&SdNpCzOuLhXPlv z>+2)SXl7VukmqJ*XV@Hgs~MS9A^Tta*;Wo^)joRvkezdIwi(A%IVWj`$N|`xuSOl1s2)IB>cJm@dX$&2dZbWSJ^pGW)vya7 z5Ult+pt#}Yqc)7sHQUp}_I#LfCwek3l#!0{^!Y;8;*qi@G!Go7aPXmhuMb{2I(ZR3 z7m^eA;b70(PRRrk)BhQ96~oDZRzE{=Q+Y^VZK|ZqZPTzE^!0k7G?4L=lN;*TF zhIOvy@j@YFcrCfCGtp8b2E=;JZsFL>qr4g5&$7maU@nG!w(KW6%Vl~KWN71BO%XAu z^D*tBC`vr}=CZjMV^#MKCd;LA;e2Fss@L~`?k?a%7R93Q2@+Ox+eAWWf!_+X|8R$eA`PSeI^TPw%|2NyXhi=O|6f$gNk{={V5`Ig74wRn` z9?BAqSQ|-ZIX)I_z7PivZ&_guJUBi)I4nC{nd3NjIZV@hockcRJISh}J_4CrO^+(N zDobs56sp}Acm~+bV6?gemdRov{9vpiI^$Ug=2B8+vfyWBI3@j<18o(hgziPlj9Yq z^YC*(#L3n|c5w$*o=Z(gqoWl!!_v4G@JM0nTF#uH#0jf|N~TUBKr&{Wah?|rZG>E; zsH~ZjtleOCaY7Punc6GW!oo>tvBR4l_EtKwjZ>c>%#30k%lj7{OENY@;KUTq&FWX7 zpwotPw9N=>O0**YAL(dWu#C5M^EG}FHaW4f29C4cWxur#Ivdzs-7Rhe5!dACCyDE- zKuwO75!}cB1Df64f>rzGQg^vsU74ul1JSBqCj768HqzDCzKmS*LkGbx<;pNHwQDGv zYR9{)GpIjO8shQNS5@erHQ`=vHDk}oNm@_;DLfg{7WJi}Y+&yCr-<~XrDQaLk)Z@6 zB$kBH2`UqqAP8$l?BQ7aDzVLVZr}y&3_C zv8I8#{WaV5?M{J@_f<6A|7SjfZ`V`xY#gTIoEjOrQkH0h`*Q^i<9lPZxHIazn+@Tg zt*?CjegDOs>QPVqfB<+rf(ne^_v|X#QOgE6c)r;2`n~IA+Ozr@3ZUOF_h&X@KjYN< zQ`NTAg|fpKV8H2o7?OEDh1{g)Yjtr}ZEhrA3&_2l?y1R}V+$B?WX9em;c-&!I$%k3 z3$ksKS%Mf-+VD+s*Vp`jh1Q6JrUgy*dY)qI^*}U3Vy~A#w#kzFaks?H&5F!QSDYCf zdBad=s7%`esZn@T;#Q`N0vvfM+1b{1r>p~v^J7ji@l>#`77WHld*}Faw`+#~K~2FC z*M@O18i@l_d6c{FQWJPf$DFD8^FR6EGmjka*1YBtwP8@*p9M3|IWQ=r#AQY+Pi0*@ z+vxNNkzvEGymf#fA4w_54tJFnPe^!)3nc?q{PrRchMC=cg7 zFyr#mE*3u{A(<;pwXB-HdtXjSiIwOmOi};x*rcC|1sO~RO}FERMH1584Db25`o}+v znYMT9r~IPa`OJaXJasakPTcZermgj>vdW(81&szKUgqmy^X^0o^{oa`hTUntG(!A5 zh?!)g@Dl`vBy*Zr8aHIrbHIZpW7DmZFFpLfrZlAzY3*TU`(YUJEH`0+FxI`tU!sXIC!4 z$yI^ap!&o6LY1f*|2ORep`013LL94-{jGiJP4&S~u@%eyQMmffxCaMcX!uy|jc=7S zv;$3WvtRPR%BA1PpNRc_@xgs7U8h-lKh-{c)%le!;S3`55*>PS z1Upr?+1cR6!pGW4u6ZBX0Xnm-6^UCy3AgFf0_fl#s@?dOt5Z_m>1^KY@uMk8kPl#1 z_7dCrSt zHtN}7(a=h=z*!UQ>6NMGK1$wA3pEmc724~TKLFR+ZK+W~tlK+zs4Bv@w0QlM25{<^ z0*5>g;%HR84oy4oFAb*Y4(voetsn4x#N2$j(v~!1AcE}vw`=f@gE(cW{tVl{( z@QzOSVvk?bh}PBZ|CSzV#ysc*)fb$@79@$5v&U=z2HB z@TXVA{+HH|kG-qt_I;`%rcv|>%}0iys9V@cq!Hp(j55(6hy}G4_RQ4Z8ww^S=@<-m z=nK_w?L#xK_NgWytjdXDe}3}*RXZ3POcCRWj>*Dei-72nl0Q6`R!j-q>A+=P2K0WV z9UJ-$mDeXhOAD2WEmS&GL_FF>5_8x+Lb!5x!6B#RGlV12#AVxR!8fy|d1?F#XeAwO z*a@#e8j~_#SFD*5(4IgD)~&E=jCPt+Moq9tRh*WWpKkF4(8MfN<2>eV2LqR){WS}V zMemN_V(1Ag5K03Jw8~q|76^J>EwRKeb z%lO$QqgyN6X1gapno8{I#e1N~DAExAf8@F8&bNI zo})Z}?^fFl|S!<-=PJay|Rz?Lz~;WVK}%=2v3rL8M-tYkL*lSi}%K?Zt-A%z+t z(6@2&^X4{6cQf4;tjneMnKSJ?2tG7?q3%s^^FJN+D@GZq_BbEs=7b(!5RG_|%ZViq zJ;<>P9#t%Ex1X2j)^qGunI$1tVMg@IOSMuKV$~dP)}+XcZIcw8pOG+z&hxMS;*kOC zxjp5uOsE!kY1=e1axa-nlP^@b>nYAa^jjhwj7kJO5{)MVucKY`*CoZG;)fSR!j<6X zud#5BQ*P z0*ZZqn(WS-7ddP(<>n5kuz5o3wREcniBm`H-8ebDIh`920=q#lDb(W zc;~j-t_%us=LHm~PZd-aKFj}x64@8n3b~^tTE9teQVDT~;+HimERZy(l#m2|NE9-( zVlZ(@7@aC&M+ui#CGHm>Vk9~g3};J}ta~3g0oij#_7}gI<%}nlGW!ryGdW~6^FLV- zjhHJ5`zP%!5SS>v!z>tNaP-yDhW#P(tf5Sq78L$?-MR8O0?zz0S*b6vlRI)rhp3NXcWhduPm`#1tm7f^rP;6!%CCL6;4n~>JjH0@iz z&M>C=GX3jwK|wEdA;|$XE0I5NazLW z#?iq?7s1DhbaK(u>-G=D(}3GyZ9&|i6z^3gSUga+g`7jPr(hlraRr^oouk-d zmOgqALg!j)$}XMjYe0aQhksm!JjP(K&KB-d`9i=(_z1updJNdO zjfut#pir68(O>}pnRg<1Tppv5{j23?%=5wkc0iw%Xb7fPOaY(?*G}YnRE@0wQ1i}e zRE4#wq$)gxcJ~T&nyOr#3h5i58ePs|J5-*^vzWk6yR>F)_51=WUv+mkLeUDvq~pny ztLQpAbo8x-eVyTW8gl5Fgo9Y|i+Qq5LP4q0*>M zLdjz1*qCf>d)5(SP0Z}8(`lVd$e#4d8jU2FAY<^KvMH@?^LMzw<%HYtlQiaP$HqeM zZjYxeR?a9ctL9AFiJ1!A94`w2`l~k=olq{ATcN=&3M> zZn6qc&!BO?d!crO0CXbk5^Z`e-G0ZjlL}ATUQoKoN|EPP+`^_u1^gwIMzV`jPfxZ? z5JrVGV%Ev%=9?$tB_+{MMk{B1@?%aA^RW9@%4oK@BF->pqijTlb4SrAcDlERcqgiv3_+qLe{CiMx&4lD$KWLw>|7P|fQg{t>5IH|5x#@2g+uwgtgwN-+F)>?CS zsWyp8^6UsUl~1eC_<=ngl8WGNsj-rt3ddzUT?JhCQ_-0dLeM3-qb$`7uCd>uKl6Gf zeB){Rud-7VN?+XjguLrq&A;ODf-VV;;E*I|1Eq+N+}`&Lvw+{E8JGw*jnNzx4;7yz zd`~%B8WA!21f7_+FU=Ebb_R8#Nc#NB>2}Sc-6)^g_lQ%Na=l_QH8>vWrtgSPXbFo6L7G$2j{|k4F z1Idxu!t=wMP(@D#)G8?tnP}NSs_%H9DC9jKfVYj~la-+J2@BFBC{rP4tUUT$DRe`O zvE@7F3VbFh?wr#r^JJX+-kHDqQGMxbZht~0MN9tVX$y!d8zP&+K3po|awqvtq1>;< zl8_`pagQ|;8wrtL8T9|548@!8`|!*xxV?bYCpHDCnLdsi{={;MDd?$K)hnItDW1I0 zB&%;~`WIL}b;i>0$B{Ri02HyHN#4t;7RD3LlClq!crEA$#-U56Qn#0xqI|t5-SA4I z)vn!YshrAYw0LXl?IyOfgfIP}bTk&yu5)y};?xuP8uc+7aiMjwiX@-^y__c5;Nfr* z6u+P|=;Ed)Ep+V5m1ZvHmwuSINlG9`b1ySB*P@f@VaXnHq|Ey^!P4`O|9!N2hGj8y(IR%nEwAt4T^oAKKtF1x4{Jw4Wv+#K_g?l#= zn1n{0_)jWnCXV0a8Y$m_t}JJtJNCTn_o(b_#*tAIE~2}Ergf6@?NkUkq6Ev76U~F@ zb#2#u!N_vZ^vy}RXd6ryDMNLCf}egg=Dc~}RJ~f2O-3RrCJ5S-(>^hCtqSG;+#eZ= zj<5Gm5mga1VoZj8>gf?^tx)Qy=qee?YL`^ivKliR=I^UjyOE7eBqi;Pq}-OHXODE} zjTKWiby2Rh5n5na>pzd0H1H*!qy$}+r=Cm9?~()(F|QNL|9X0Ww7*nN_|r@eXS-fN z+*{$6hVpgR5+2-gSHMA2XzIDYke8wzW0B8AI=mk<7+O%=LKXfMvg#$x>kHPF6A>6q z=+mCAvsBW&-gDx)Gin_oKeMHf*g(~2Jq=qErbaC=Slfc_JaE1ygP+- z_Dtk6(ow4V>Y9pZCl(|r@{G%oxBnJ4v}LiEftF)FqdA938|l7U?g7l^=h|&miTy^L zK7lo<`xLQsg$mll&7|uvqNd2_o@-BwfA-#A(3w>10MclheX`G?|D=*BH_*ul8s?BL zg_C+M^3@oh7x6?>>~rVBOB+WQwMyVj-zaeuL#W06Oxvu2peT z3;r_wi@W+6WVUV0iS(4Razm(*teUivD!9={WESw;DfuZ=XdhivAY1&;zK=@T$o zd--3LU`(ZY@dof`YR6 z7C0mCe)8EYMyC!SB&D~`t&y5wnSOU#x0(sqD}{?MhF?(w`Ky7!jxK7@;c_&*3X< z*Mz4gT+X8^ysxakQ-KWlkAqB?r&6N4g^_;C4cF3)_hGitfXX!gp}#4dZ=2>Od4uDn zUxAX-=#pB(Kwf3fhDr)G-{5EX(m&&HF;dqsR*y(8NOVP`0Y>SUF zG=F2`<3Cnr(&_b^$>~V``6k9A3ZqWjKcVT85GP~&awh>s|~!PaZQS12r>AM90_-jb|kl z5x2^7D#Lz_vaWy(JFeJ`IFqo!-W6w{7xj$^pi7J(E|YO)zzxfmRs*oBONAqodTx`> z5;6azrx0JQKM9k>b^K!_X1f$=>D_OCGfwzHXVCp23U`PZ>!m#*72t-w9oBh|+IheW zkVuaxBO)h-xSTg8JHU8bcE$_#GC2S}>K^gdwyj}1$jSPbJZPDgf;36Mw-E`3MdUBd z#34!9x|Af+P~$Hv+Vr4xLu%P_KmZrGwaIH299QV6%YUHBgIGd~>@hnrGP$>^ds2@x zNR?>d_#B593CH*+l&F~M+`CdB^4036BE#$h(U;FhG&HGhM-i907U63`e^da0CF7y8 zY3M{*A8q9Zyjrz@(Wzq_F2@WT?DbIunWzFtdQcwsOtn66G&yf_R0Q#TZWTC4$Y8s6 z*sGe~+D}yX&if5D8C_nz`PUQ_O?B@wfd3;Aw9ygFPM40+`IP`SGJR_2%=CKNwmJoy z@X5{&%T}$z;J(JLqM8rQf<&PO$q!4)chTl(GXnd+r~Z4mi6@ZoIkASU6o?BSqyqzJ zj(Y^~ZeNj^1-TdtX_aOBuBxHmw{WQCaGY*WJQfbMI2a2!C&n|P`#Ch6S>~j%OL_-G zX9Gy^F65s~`hW{wj8d&*>*dv7$MYsI{e;lizV!p9TR1tNEIj`e#C``1mx9zM{jjb7 z+5-UPK@ifIwJWp@++|6*FwLlDD}+wthPZ;Pg+YBZ(Bs594XB}$^w@C!>bMZm6nG~M zoF*(a09x}L#w%t?=;<>QkCoqeC|M+qS>0QatO?&^Mo%*9_1H~or~SR$zKm>7Cv=&$ z{m@o)=jN@0e-dKN2D%)}z|veztZC@noBzyJlbPABdZvxFmuzi_@YZZ}J47*C%@AHT zFKY)}zhAS_dNeZLe%*5^OFy)ohK6>p`zB=8J}Pys0KXqx@&#)6Go~XA=^tZcSMRKl zax6L=GjWFK9Iux8&5esZNItH4Tey*G4LvboOtnUuMyH9;WWI7;9GgblFedPi&N;X4eTO*CTjj~~0?6RrR1s|W70QpJx`xY`CV5^XRQ8aFl z4ED^`94(w-D>s7get79P1)KWK(Lg~)T)Im0bVG)5ly_)aKN6_o>gfTS7(@NCeAWtJyUlEUuSP{R6KE59Uc^Ex-5hbf?Ym91D z6bl6HGI4Y!uU?3Sd@ove!fXDd_v&B@xYk|Xy;IIz#hE@)NwD#`E=N%tAbZwmhvOTL z8*h!($#pd(H@<-JxP1v*^*Zvo&})-mT-kJ%wQDA79P%g>ibV?noEqWlA66rY%2EvF zDU5K5Tl86ld1`wu)3sR=`eQl!kTuy6UWUW3zAf^evF%|PcTw43>R$S+|1fOO`k5k) z8i2gQ=`nX2ZWCnHc8bRU%h}yOCIFz(kP!^Wpk7-@yS>t!D%%l zSmMG|NQ9N|PJdgPwX)?(aYZ7pT&X}|RBq7Sq@+puY z#6N0(i~Y7_Hd>?wYfpwz_?~$twW}lBAn#B=p1Yk;ZrEe*17nx_8SI^x3}i3%J-k1w z%ei&kEPLX!aCUE8xDKt978%3Za~j39^b3 zxK=dJBZ5B_mvUM}Qh6k4fb3Lj3qYrBETn1H>O3DGG()!Yf6kMy5ggSu$jIMpZ3pcy zSLFLblvJ(i(nJaJMRSNQ)#MRjSR{-+96cZu57@QtEXVYZ%rDhqbaV2&T)`Zhc_bjN zxCV*ky`s|3Hk#7~SCye0w>2M}+RH77Qd$m=_?o9yPTt2<8!TC-)RrKR7<#=8e-IrB zT>Y$2rUXa4LBC7KazdiXt8*TYwC#vAe0BilC#Z`U|w|IV{LG zl5kHcNa91RygA2|fC3~R`wvA@+>0I|WBeTJobTTUja+-fyz~JT%=fE3y?b2a=gye+ z86L+q!H8Po4W7QU;#qt-+uTs3gIcmj8j?_3RLzwZoyHAu0>hnY!|4|)rM%7*ghVA+ z_0_O(op^(n-1mw7NoK~K zgt}S$>$ZIfP*I%q5)}iIfDdf&7fpN{sp_&%>(3TF!^}&#@s5l2`|Y%dO@A$&TQ!I( zK;{_dB6A`F*- zv2tPVGFw*ADuSad)E?DYLSbK3EaGj0F*a#(m3O;tRN8@Th{^LyC1y5k7+ySAY1wIf z+3&F!2bp$e$&ScTG34#(dZ&GtXA46%^V->Sia!MbFuzr4?bi$6dtCM-% zqFOLv#nQ!k+IxV3_Ri2&5>L;4mK!}U!Uzle$^p>kc<#Q@g9k^N*2ANy?J)WNCARBns zXDoR&0lgo)jkl*HMZn zZk%0duFP=m`)@WNkdrX^g6Saim!5q^4S;APweTreZO&38tKg!$l}g z4M%`G(tDcp$Cry{PAP{d#CbC~I1Q0_Y~J+{pP^uRvLC8tp4H9BZczt%+JBHORU~pm z$)Zd+a!8sfe#9q@^*?*}-=ph*C7@$59&t(c(v?FCT`q_M&@~DHD&rRSb1xp=Hb}|P z3%$vNfNy5jgIw7Mt5ur3W~njjBRyKc@CQ#wi&Of$9>7*v%V&bOf6BLjSGl~cZ-IPC z{0i^{cExuA_a`+Y^caIHl;a4EvEg`Li)V8y!EuW1@>wO_^UB^OvcNK}GVqyO8Clk# zZR)*Y*$-45v3D$}28Nrgqe>)Muq8n!)dMPKXCXjd8fCh2EMD%?P zzfba1aE?JnM>tp!7RFA>WkpOAd8ueMMS8@@LqtaWd%6EE*b=c1l8z9UN;IJ0bqX!W zJ9p+p=qOmZ5)Ef9MnnBQO$_08xM{lxl_HE05HE|am*n3dM#D@8bJWu3CVTSenT_St zmxSy1v!nU}2)jd0RP0`zukJ|}@4*W^Jxw`RA-Dhxxvak?BaW7S*50%oPe)q9RWaIrG&wjmon8W)M!C(9X-#Vl;gtC>^-Cqeb2m;XJ`;FQaG3`oq+60Sy zx&K`MQ43p|RQpjA6XaI^3w8T|NNbzzb6uz?(UUS)a>ym~VKe2y3*y@b8anJ%o@stV z*Y-0}Eev$!kYYo})5OlgmDBhjX`{rQqWQWAHqdq{758F9dU= zx-W4YRMY7i=@b-n1m}Px>#cCurQ-(Bxn?cL64o?T`qpU1rAz$0dbbMnMUy3I{*Xrh zw3@0G4kG6aP%Q+`D(94u5as7Q6G#MCt%w`p9BJpg7PPH?YiwE)mgII`d8YGNLUnLb zN9;GJi>G8IW3Mwla4^jC=348{)5_RBT%6M2+C9~ZYWU8{rLZxd5G)NmjjGll5S#wj z&c$Qz#Sh`!9HjT5TD=1y5qvuP*kIix1hTj`93cbOM2&Va+OZwvBG$2;@(iZrN&DnR zvOwBwALFZXT@#snRUwW-MY&fMN@|u*GJuU4p(<@vY&Bagla|VU2RVb9BG78`=&9DL zi~7WCI3cxuuVij{_tPyhDBvk!Am-slxFihsG7*X->$W`2NwSz1l{sUA zRMs>G8b>({=NE+eARx@;P!J=5FQ5bfXbN8@B(}(AVDmtrk@W`-W-pSFLR<$DFMf<< zZ$sSykZwqy2;V40f4b}o-LQLD zk6L&W(lr4N`28v~b%QO0x^Q#BoXDjhAoS{llLO?(K0mqcC|iN>ccqaKmfrx$`?-o& z)I>Y>=-HkU6Ep&U@dqpbPX1|Kr3DeprNL;NhV|*%QQ#!kJi7UrN1?!-xTgE6%dy8v zoQu0mS0G$O6OKJ-u%21*OMDHv{0xd1Rj8J!J;Bfey~ZnrLXcauSk^Mo7ZUXa2&_5u z{sKj-9-o_WnIbUo(A6rvJdsv@aczczH6Aeza}KRuTcFjj%xxAs(o`Dn*ijaW4nm@fRAhR2jD6h~kj^{`@$=g#Tf1oHhg zYZ$0XrtJhm`q#V)qqYK@YiKVaOtu%hiSGkIWtA|!r+b7`bJ}Za<|Vh~@+Ctytwk9p zpVj8a^7BIL5Y8Il{iyF3oFVo_QRx-_$L0rSXT-LDB-_22m4*#Wq?$VoUADu~@y-E? z;Uy=dQ{|K%i}$e8rIWLMY~$|Of+dr5ngc@uOfyaFhwmtvpK3#tFpoF!%Oa*LrT2+?V|Lgzb3phF#n+HwT? zMMC3*i~+;=c-%bc=j40TpVk9%&ll&)o)eBb3|f6N7qjuq$GBSbjM=%l?F4 zfoqexWYa1{M?U51LUS6zK^c`E$iz_zLUc1lre#79z1Q3g$=rDO?u z8U{VMTdj>p@*8F8-orE^%rQRtQz$^OC!ul|B`VVoFK%wQhZKpPEP)~U1_CW0>6rg8 zMeeb*-);JH{0W&gn#%T82a;JB^3Y%_X!pshY4b?we~5pL*M`VBg~&WcmPhcoy2)!6 z%#|ZJqtJ_Y@WE5a3t3ucU#zZ@`y3T*mpHS4zbt;=R1E6{9zJvtF(SOg8NEOSuov=RUaXQD4WP z#PbnV^wo0QZ0KgRLX{Xj9X{%QxQ)kV^<0B7Cac8as$wW3+$*P0>2h7Y$5xue#- zG0(BPHl@uPAdCteD^Qb5lOG24_W*uV|w4u?c{B|lKSlT>HY zQ=l{Htyz!D9=iLwPb=u=I5Rh@1s3MyW;H;`t|mnB+62XY#lwvOJ0Zm0CHY1>_nKa$ zlyrHG5vm^Q>0ElLno{O2X?oh1fJ?g4rfVrpw<9?Z@R&!fz^`wpKbO2$=Pp|1z+H%R z@QrGYD=X-$KIVx7ssv}$o~WwIZos2jj=+0e=A9|(gEjLE3k-N&LaiA2_0rv7uQk73 z!WWpZm!F|@0il)6*q`;Sq0a|d!0WhPolLc*UjExK~k)fpe6a&yN|hOwY@qb%tgD}(dLCFG&)sSery0)1+3Axy*= zPIW>}Am4Q>mchW5Tv+UsDlhL>!@89iO3e=F;ocU170G~euLF+x*e?Z2kAok@xS!a| zEMCR@uC79`R*p@HlR}JcPlioJcV4=7Fd3Pj2_*5FLzTIF^*5PEOu!K;QNFWnCBnYm z_>;-i+{+qZO@tbV0sM^*Hqq|Q_x*KPfWLNRTOBC)*n#h=Fm;gQd>PpHNk`%gpR1~K{>|&P{sUvV zN0aGGZ_5SGUKTz$rs5g6szsf1 zir!+~KxEg0^6D33lLreo2v#S=g>0uy!4sFO&Je7>VEF>HLiF@a%M7xfm0xkFzEs;( z^vPSh=CkNhU|l~hxWEmeHhQ^T#gU`O2Xj9stTW;~ znb`!;es{g9S*(hg?4FmENwyg|Gt66 zt1fF#4PC(}d^*D-z>Ik&ns43oD>wu`*j&o4C`|5+;k(>!2)*rLGj>%A9I5P9-u@4;)P+fOvG)=U#7!!JqbC~hmswo{k_d#h zi0`4NQk}l&9)>t&c`yxxL2_V3kA00qUK^Z~hLDZmR2uM7MGa`}mvZ1x zh9KrXMcW^yL4I(yqOrFa6dA8G5ot1TM9-sQqVXkqhGM1jH5W#i^^8V%w&t#!06`DI z`UgL;4O1%B#7FP!R*dYh7O5uN8>Qev0dlHpN`hhq*nL%+ym-Wp^}61joUZtn&DGe2 z6R|HjknvX@KmSSV$VbEA1?fzYG0&QF8PXM98)O<)?1HTP|DdKExRqyyPqnfp^zp|I zZQE49I_g{~fZ+ld= z0VclLPo(#+KWCGWek)gTNxze7l8j}Y*fx5=yGg7_TEZx(l#z!%SG)nq75}YBrQ}@a`l#{3dy&CC)tdbt9)o{ zM#@)3CQa$|&0|{n51S=A+Znyr>Egen;YsVDvYnpn{iQ}* z0=~^NnW}DH6~0Z08wmOkXX50lq#r^*%uL^yG#knpbj@m*rtgv_;`dv41>UH7FaLzM zEo>aZA{l;>8%>L)+!9}}#UcE$j7rI*b1&Av#ozq9yP@I3TXeeUZ4z3Bo6 zTj$9LjUd!6cT0DI%)@sFP|n*x=LjGN0C5uluyg=5Apmdy0RM0AeP(;+*>CvJqf+Ct z4MDrZekOciOfAE`y_>z;)AQcj+to3rcjYIO`^pD9chRl7)X_=rR;<#wvbPG;MUA5+ zAt6g!SpY*b05l^2W>5hA4Nu!zuWoD5O*Tz5(13(Qap9@HR<@whItlA_FSiK_*S2Ym z86mOK4%-wZ5Tx$fCd!V1wzg_yQiTvsR1rZ1r!q#Prua&URFn9DM}knMN%ornBLDz2 z1_mNT0M}C$#W27WMd!xY$IED&Y4;M6&I9H9#6nBe{F0VwyrPb-@>7N(S8$NVJ316bHlrdX>N^!_+y3%-TvCFxelPd_VN*!T`52q7hf zY;Yk|qvkI$3N4uS3*Gw>ld)2pLL*Sh1tiLE-{I}vXofE#c+8t$SQOth^0HB1#?n>8 z1LOV0UB&NLM3-YS4svpf;Ccd*0j$; zu^#DvQdjk5T?;bnzsMS_!v?aMj}SSLdurdhY&I^zMAGxRZzJjtuV!Zt}>A^ zGV@q^vPN8$iqR}?;RrXxY|?mr-=4{Y@Qtb7AuyNZxfp*ZZhs;0M!2P_e5l9|Q&gKO ze@P-RY(AkZK~Tk1k?agng101n`pVzZg+F8ulI2iS(1T&(8i@IjL2Qv6$8KCIU9u8- zEL=NorY56AO2bq z!BiGZ!pAcsej&hDlT>zOuZlNOqbi|RF$!oGWy9VwQmpf_>a*S}HpPcl`nry4r+U-t^1 zN+H~M2IOIy^qzzljfv>($y8`i&_dy#?F(j89Nb8D7C0cD*YUl6YM+pIDk|eLZ*id0 zzoO`yl)JJ4aYdRNIW7Jb{$b(i+~vZbnz^7;eVgwR8#6R15>u@X(sz$fmsC&&nWLtK zd%gI@Qz;zDq&b=9WT$$z;!P45ifD~Zr0V-e7*Ek5e56)`8_Kx+^RK^?dB9{GeU{_S zaz4>>G%?Z{bV%muTVD&1(lY*knunOFfqgHD?T}&!s&3th+{%3Rs}jXa`sc$UD8os! z3M&=~A)clBH6OauRJy4gXGgUqJCi!q=vl{Nvw-ie@G8Usvw#!Z!6L(JaNG}263NUM zCtx*(&AO2B7>h|s%-b%C&_Y^fu@Cj}mQFjIjo8aazccwKJRa9sBwLKB&Wyswvr_z;x(b-4<(cGUTr<@o-9x3q7$67a8vcYTg=oydHl z>2o%w4Hs09Ld!wL9`eC5ma8YV_00qC2Hd-26)N%5pGO)|Kv z3O-fM@s71u)iew0WU=QSH^|_}ZOf#__SfT)o~+1y?PMZs?$*|zKWZ_1u=Y2mrP`Gc6Jl#=*!c4v-W0&6Y~tZh1}*Y*|#7TN*4Qfx9Rqg z%sA$?*}cPG}c-h3~oSQhB>*u+VYb)j^VHGU)Wpuj^>9NK+ zIerD-RIP%oo>ndK+pQOz_$z8%QWw~o)w+`3=FZB$VK1@zp44OxvG`AA-S=r+vFo!= z>}v$|E!UIg?n{1iFz)@&d&t>jZpxe^kHa~Y&}upd6URE@{RQtE<>={W zSSDKNY2gWky6A_xrw3cj5Lv-XexGfS`*5vK=f_3z#9gVriu^q_AJP?}gIFi08MWAA=OHdaao6qLnzEI-A~?t)O%dlCEzFnop6svD!DT z7Hf9)ZhK>7ZGLFk<1nKk-Ike|LG(Ai&-b^cBRXhd7Sm}8bwVL%=yJOq*5YSlEr~ge z`@FI&b>b`5rFw%gZ(3jJOi*g%n^b+-J&+e&70U%5>QZL30*^rH8NHr}c8Kom64A`Y zSl5}XLGJ(|QtSeR)ChivY<5Jt7`^ge3pXax4%)N1T%E9lsvY~)(T2lUWR^TbOUaE9 zi*1Y(u3wTaW9lwfm}(b1(KEujyrgma@Y2vM8_*aZB7@_!izn?s%dNn7WFr zIj4zPk1UFo?tX*eKp&bx8>m4Uj)?mzp&l~FpzK#GQuM|?rxBxPAU`UfWh67|aH zG!2Dv z{4YmSrnyNNa0Uzk1HgbVUd3&qvW^2iI5=P?=sgil!JCS7r8m3T;tS?&h@4PFfJPiCOt z%y$9B1XbPDE@Hz0=3P5hWe za5P4o7P9yi1somTdxjta+8AC#Iow4o6s66M^5_O<0mqB&8BdK5Cb*n`6%r(T*YXLT zVvOH5U@`cHaKMUY4}e<+&~VrQTI0AhRlcCGf$tU!CNUZXF;cTcUb2>|8w=ze!VFx7E*Kf z7hpiZfIIa?O%?zFcs^$|o@M_0wD{3Ix`AB=LhU6Qt^ggG-AK3e(YZjes{^Cs6RWBG z-~mm0aEn?T1y~j00FZum3&VVM1K9=8=^zaE8UlBJy49!$hoa(;3$y3I>>6f%_5;WP zaArdB?=^vfhn#OHc$V5{D0u!}C-2P*0?f}was|MEqZl1;_8soIq9=?NzT|&qt@s0DpbRtE|s&VD?PHwN?DFYF7R}86_TFec<5i``d1!46D4@hqQDSJCmP$%}IetNF*^_-9KLu7p3D4y_6ExQ}})??<*nKBjU_ z_|{P0{I}hZDl#y%RIj12k*Vn7;Eo_y_@as{>Rs)2t68=4XxgrQ<|;^{ z?O>498*>mDu=iV@z>yHx3T$nTcXSO&1u&KS$&JQ4ZSu6%n12sVE+Z$VPkTSgAjlvUPb@0py({M>{-r_!w)v{`x(iDKw%GEgWL3N2C6-$j{BF{IKWPZB^#wBgjR{@k?M*?jURSwoU2i-K}8N z$nu&p|2@4r1GQr9)xqRSu)*YfYKf^Du#@5DaaC&2`f@DRLdpu-shNa`tew@~^3ZfZ zG1#O|-1O5(^trK1GnAURL1aZO#ID`#X@AU&Cn?CQ*tuXM!xgvQY)yBNN1;Mfz^(Ta z=;NpddV4NadePH{7BgCol{QS;VQjvs%dfE*K2DBy>SlSh-6O_Nu*H9f*`tEBqq`RS z2A{pdwHqN)eecuaSn7ycS+4V8h5ce4dFGKyaYsQsf= zH*m`kl@V`Q!|uzg4e5u;*^iFg%b+Ua;Kaq-Epd2znybAchvin&WSEs^L*H_;0E!C} z&7g|b$&Qg(7V*4;lqmMfsaO8SRX+J^usl&g-fgNuSr7sV9`Um7MioJ&IZ zvCK`$4utQ#@4)}+?@E{-kHT{x|MERLZF~b1wg$Lbrm^7R$bplmCZtoaT9foA|LV~V z+?Moi5L(box9MsCD2r&hpm%K_r9&q>Tn)^obDL}3VkYD~m*8X(7&X#Kexj}>c^o^% z34gz3>h`^ojKsNhxPV6`&1@6?=2dUhSV|v+{gad^tuYQ|S>!CV?1l=Ka)k88dSftB zWOcb-c6qZ?{gPB_|D)NZwd}$MbgW|n<}1)YQnKr%9LakL-_%EYOZbl^(3CRHXxY?M zTN(`sIV-_%LU`r6&CEKGY0x^}D(l~xFfaauURL#p6}Lwe+Q!n^QNKuA;$PlNSm_d8 z!?p80BdZF4`-vy~ZX#3vJ4jTJR{Q#|M-%=q-r>--Ir)GOS74P%?Y-JfSm*yj8j@~P zh4zGKrEgD%D=@udxta|6ZwAzMA4ZA7PO@$ho@w9cwN3b5&+(ogJk$Aq`A$jQRm%2P zdENKrDU^Nkl*+$%N+oB7|11*EzX?Zcl2sx}_f6w<;#Pl`7h=O?Z7Td*32ywR3E4+5 zHIlgu?PS8XlxwZb2rb`l?MMwm`f_CiF}0JMT2?0Nh7Ej;YA61}90{+L;M26VePOY&nkBKR;;dKmG+I05&Z*@S zPf1Ud>8de1)%(s>5;IcqtaHTT(WBJUO?FZBj`voCuat;wMt?@|au*u5HZaB?B&Ad< zEX?@R%d^j!5?d%vXj%z}6Nf83PbEIpGtx=b6Igv}NYaq)ouT6)!I_04OeEovT1BE$ zwSgWjzmX_~ZBS0IJC4}zfrLzIBs^1XYPo3RwdKCVQu2_A-A6C{mHtg9tabanchQDZ z86njl|CBSiq?xLasl`gg;=!x1)@pOH*lQ>5o(YgHKmM8-KAftqelN?`9}-6OQ-qS3 zrPgT=Qj|}cO<|Lxk3ikN&SQs{?PknsC&r9Cb-vCdUe8MsY$+{}HmNr!?AS(6RosE_ zzLq^Y6A8;2gN#Lzk5S`R^Rvvy4>GC$D%WiqL~)X(0ZgnyT2kDP>4 zs{-@OYF?WO%T<-|zqAs1kNRo^Q1#2zbQpF&6-&QI_fEjn&l07ondmABP7_)yhoXio zt^WT<7iRy9DqabwcQUl6888+SZ9XaD=eQUThJ9$<8Es)x59#DKM*Os93y8lyowZEd zmv;Bx%^c)Q{~_EwH&FnG$hOAi+={;nUAcD)SPduuYYWp_od-1hs>jIbR)B!8ci zpH4vAHKV%cpL(o$MdYViO3I>{L_6u)BRk|@5iTV}`{3O@&Y}Ax>@W(1*L#BbJMF^%NQ{>(o7g-akb-Vk<#zjOygIF@xXuQD-KiLLQR+Pr&k z+ij0$HrleMZix2yn=gV#);mPh|L)w;t~Zb(&u9zR=8xn#+9IxuRojWDMH5Xm+M+V) zXNgeSZxI1$GR>0+rUbT*_F6==EfI2Dm-l^<-clCt0xkl{8^7a%HosJ*_7xn@%*^Q-D|d^5C6zmvx;W+|73!)PH1)gm^q*( z5x~ue80~kF{k>dGTx#N&zutzrdHbZ4K*TzyYg^Yst`FUZtq4!}N8d*9i9{ZM zU7dW%EZ$ch&J(O{x&wi4+Iw;7?`DHi& literal 0 HcmV?d00001 diff --git a/zlib/contrib/dotzlib/DotZLib.sln b/zlib/contrib/dotzlib/DotZLib.sln new file mode 100644 index 0000000..ac45ca0 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET + {BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs new file mode 100644 index 0000000..6fc0fdc --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +// +[assembly: AssemblyTitle("DotZLib")] +[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Henrik Ravn")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.*")] + +// +// In order to sign your assembly you must specify a key to use. Refer to the +// Microsoft .NET Framework documentation for more information on assembly signing. +// +// Use the attributes below to control which key is used for signing. +// +// Notes: +// (*) If no key is specified, the assembly is not signed. +// (*) KeyName refers to a key that has been installed in the Crypto Service +// Provider (CSP) on your machine. KeyFile refers to a file which contains +// a key. +// (*) If the KeyFile and the KeyName values are both specified, the +// following processing occurs: +// (1) If the KeyName can be found in the CSP, that key is used. +// (2) If the KeyName does not exist and the KeyFile does exist, the key +// in the KeyFile is installed into the CSP and used. +// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. +// When specifying the KeyFile, the location of the KeyFile should be +// relative to the project output directory which is +// %Project Directory%\obj\. For example, if your KeyFile is +// located in the project directory, you would specify the AssemblyKeyFile +// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] +// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework +// documentation for more information on this. +// +[assembly: AssemblyDelaySign(false)] +[assembly: AssemblyKeyFile("")] +[assembly: AssemblyKeyName("")] diff --git a/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs new file mode 100644 index 0000000..dfe7e90 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs @@ -0,0 +1,202 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + #region ChecksumGeneratorBase + /// + /// Implements the common functionality needed for all s + /// + /// + public abstract class ChecksumGeneratorBase : ChecksumGenerator + { + /// + /// The value of the current checksum + /// + protected uint _current; + + /// + /// Initializes a new instance of the checksum generator base - the current checksum is + /// set to zero + /// + public ChecksumGeneratorBase() + { + _current = 0; + } + + /// + /// Initializes a new instance of the checksum generator basewith a specified value + /// + /// The value to set the current checksum to + public ChecksumGeneratorBase(uint initialValue) + { + _current = initialValue; + } + + /// + /// Resets the current checksum to zero + /// + public void Reset() { _current = 0; } + + /// + /// Gets the current checksum value + /// + public uint Value { get { return _current; } } + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + /// All the other Update methods are implmeneted in terms of this one. + /// This is therefore the only method a derived class has to implement + public abstract void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with an array of bytes. + /// + /// The data to update the checksum with + public void Update(byte[] data) + { + Update(data, 0, data.Length); + } + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + public void Update(string data) + { + Update(Encoding.UTF8.GetBytes(data)); + } + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + public void Update(string data, Encoding encoding) + { + Update(encoding.GetBytes(data)); + } + + } + #endregion + + #region CRC32 + /// + /// Implements a CRC32 checksum generator + /// + public sealed class CRC32Checksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint crc32(uint crc, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the CRC32 checksum generator + /// + public CRC32Checksum() : base() {} + + /// + /// Initializes a new instance of the CRC32 checksum generator with a specified value + /// + /// The value to set the current checksum to + public CRC32Checksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + + #region Adler + /// + /// Implements a checksum generator that computes the Adler checksum on data + /// + public sealed class AdlerChecksum : ChecksumGeneratorBase + { + #region DLL imports + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint adler32(uint adler, int data, uint length); + + #endregion + + /// + /// Initializes a new instance of the Adler checksum generator + /// + public AdlerChecksum() : base() {} + + /// + /// Initializes a new instance of the Adler checksum generator with a specified value + /// + /// The value to set the current checksum to + public AdlerChecksum(uint initialValue) : base(initialValue) {} + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + public override void Update(byte[] data, int offset, int count) + { + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); + try + { + _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); + } + finally + { + hData.Free(); + } + } + + } + #endregion + +} \ No newline at end of file diff --git a/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs b/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs new file mode 100644 index 0000000..16997e9 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs @@ -0,0 +1,83 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; + +namespace DotZLib +{ + + /// + /// This class implements a circular buffer + /// + internal class CircularBuffer + { + #region Private data + private int _capacity; + private int _head; + private int _tail; + private int _size; + private byte[] _buffer; + #endregion + + public CircularBuffer(int capacity) + { + Debug.Assert( capacity > 0 ); + _buffer = new byte[capacity]; + _capacity = capacity; + _head = 0; + _tail = 0; + _size = 0; + } + + public int Size { get { return _size; } } + + public int Put(byte[] source, int offset, int count) + { + Debug.Assert( count > 0 ); + int trueCount = Math.Min(count, _capacity - Size); + for (int i = 0; i < trueCount; ++i) + _buffer[(_tail+i) % _capacity] = source[offset+i]; + _tail += trueCount; + _tail %= _capacity; + _size += trueCount; + return trueCount; + } + + public bool Put(byte b) + { + if (Size == _capacity) // no room + return false; + _buffer[_tail++] = b; + _tail %= _capacity; + ++_size; + return true; + } + + public int Get(byte[] destination, int offset, int count) + { + int trueCount = Math.Min(count,Size); + for (int i = 0; i < trueCount; ++i) + destination[offset + i] = _buffer[(_head+i) % _capacity]; + _head += trueCount; + _head %= _capacity; + _size -= trueCount; + return trueCount; + } + + public int Get() + { + if (Size == 0) + return -1; + + int result = (int)_buffer[_head++ % _capacity]; + --_size; + return result; + } + + } +} diff --git a/zlib/contrib/dotzlib/DotZLib/CodecBase.cs b/zlib/contrib/dotzlib/DotZLib/CodecBase.cs new file mode 100644 index 0000000..954db7d --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/CodecBase.cs @@ -0,0 +1,198 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements the common functionality needed for all s + /// + public abstract class CodecBase : Codec, IDisposable + { + + #region Data members + + /// + /// Instance of the internal zlib buffer structure that is + /// passed to all functions in the zlib dll + /// + internal ZStream _ztream = new ZStream(); + + /// + /// True if the object instance has been disposed, false otherwise + /// + protected bool _isDisposed = false; + + /// + /// The size of the internal buffers + /// + protected const int kBufferSize = 16384; + + private byte[] _outBuffer = new byte[kBufferSize]; + private byte[] _inBuffer = new byte[kBufferSize]; + + private GCHandle _hInput; + private GCHandle _hOutput; + + private uint _checksum = 0; + + #endregion + + /// + /// Initializes a new instance of the CodeBase class. + /// + public CodecBase() + { + try + { + _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned); + _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned); + } + catch (Exception) + { + CleanUp(false); + throw; + } + } + + + #region Codec Members + + /// + /// Occurs when more processed data are available. + /// + public event DataAvailableHandler DataAvailable; + + /// + /// Fires the event + /// + protected void OnDataAvailable() + { + if (_ztream.total_out > 0) + { + if (DataAvailable != null) + DataAvailable( _outBuffer, 0, (int)_ztream.total_out); + resetOutput(); + } + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + public void Add(byte[] data) + { + Add(data,0,data.Length); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + /// This must be implemented by a derived class + public abstract void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + /// This must be implemented by a derived class + public abstract void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + public uint Checksum { get { return _checksum; } } + + #endregion + + #region Destructor & IDisposable stuff + + /// + /// Destroys this instance + /// + ~CodecBase() + { + CleanUp(false); + } + + /// + /// Releases any unmanaged resources and calls the method of the derived class + /// + public void Dispose() + { + CleanUp(true); + } + + /// + /// Performs any codec specific cleanup + /// + /// This must be implemented by a derived class + protected abstract void CleanUp(); + + // performs the release of the handles and calls the dereived CleanUp() + private void CleanUp(bool isDisposing) + { + if (!_isDisposed) + { + CleanUp(); + if (_hInput.IsAllocated) + _hInput.Free(); + if (_hOutput.IsAllocated) + _hOutput.Free(); + + _isDisposed = true; + } + } + + + #endregion + + #region Helper methods + + /// + /// Copies a number of bytes to the internal codec buffer - ready for proccesing + /// + /// The byte array that contains the data to copy + /// The index of the first byte to copy + /// The number of bytes to copy from data + protected void copyInput(byte[] data, int startIndex, int count) + { + Array.Copy(data, startIndex, _inBuffer,0, count); + _ztream.next_in = _hInput.AddrOfPinnedObject(); + _ztream.total_in = 0; + _ztream.avail_in = (uint)count; + + } + + /// + /// Resets the internal output buffers to a known state - ready for processing + /// + protected void resetOutput() + { + _ztream.total_out = 0; + _ztream.avail_out = kBufferSize; + _ztream.next_out = _hOutput.AddrOfPinnedObject(); + } + + /// + /// Updates the running checksum property + /// + /// The new checksum value + protected void setChecksum(uint newSum) + { + _checksum = newSum; + } + #endregion + + } +} diff --git a/zlib/contrib/dotzlib/DotZLib/Deflater.cs b/zlib/contrib/dotzlib/DotZLib/Deflater.cs new file mode 100644 index 0000000..d7b8dcc --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/Deflater.cs @@ -0,0 +1,106 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data compressor, using the deflate algorithm in the ZLib dll + /// + public sealed class Deflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int deflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Deflater + /// + /// The compression level to use for this Deflater + public Deflater(CompressLevel level) : base() + { + int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize deflater"); + + resetOutput(); + } + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + while (err >= 0 && _ztream.avail_in > 0) + { + err = deflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = deflate(ref _ztream, (int)FlushTypes.None); + } + inputIndex += (int)_ztream.total_in; + } + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = deflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + deflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib deflate stream + /// + protected override void CleanUp() { deflateEnd(ref _ztream); } + + } +} diff --git a/zlib/contrib/dotzlib/DotZLib/DotZLib.cs b/zlib/contrib/dotzlib/DotZLib/DotZLib.cs new file mode 100644 index 0000000..410deb0 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/DotZLib.cs @@ -0,0 +1,288 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; + + +namespace DotZLib +{ + + #region Internal types + + /// + /// Defines constants for the various flush types used with zlib + /// + internal enum FlushTypes + { + None, Partial, Sync, Full, Finish, Block + } + + #region ZStream structure + // internal mapping of the zlib zstream structure for marshalling + [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] + internal struct ZStream + { + public IntPtr next_in; + public uint avail_in; + public uint total_in; + + public IntPtr next_out; + public uint avail_out; + public uint total_out; + + [MarshalAs(UnmanagedType.LPStr)] + string msg; + uint state; + + uint zalloc; + uint zfree; + uint opaque; + + int data_type; + public uint adler; + uint reserved; + } + + #endregion + + #endregion + + #region Public enums + /// + /// Defines constants for the available compression levels in zlib + /// + public enum CompressLevel : int + { + /// + /// The default compression level with a reasonable compromise between compression and speed + /// + Default = -1, + /// + /// No compression at all. The data are passed straight through. + /// + None = 0, + /// + /// The maximum compression rate available. + /// + Best = 9, + /// + /// The fastest available compression level. + /// + Fastest = 1 + } + #endregion + + #region Exception classes + /// + /// The exception that is thrown when an error occurs on the zlib dll + /// + public class ZLibException : ApplicationException + { + /// + /// Initializes a new instance of the class with a specified + /// error message and error code + /// + /// The zlib error code that caused the exception + /// A message that (hopefully) describes the error + public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) + { + } + + /// + /// Initializes a new instance of the class with a specified + /// error code + /// + /// The zlib error code that caused the exception + public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) + { + } + } + #endregion + + #region Interfaces + + /// + /// Declares methods and properties that enables a running checksum to be calculated + /// + public interface ChecksumGenerator + { + /// + /// Gets the current value of the checksum + /// + uint Value { get; } + + /// + /// Clears the current checksum to 0 + /// + void Reset(); + + /// + /// Updates the current checksum with an array of bytes + /// + /// The data to update the checksum with + void Update(byte[] data); + + /// + /// Updates the current checksum with part of an array of bytes + /// + /// The data to update the checksum with + /// Where in data to start updating + /// The number of bytes from data to use + /// The sum of offset and count is larger than the length of data + /// data is a null reference + /// Offset or count is negative. + void Update(byte[] data, int offset, int count); + + /// + /// Updates the current checksum with the data from a string + /// + /// The string to update the checksum with + /// The characters in the string are converted by the UTF-8 encoding + void Update(string data); + + /// + /// Updates the current checksum with the data from a string, using a specific encoding + /// + /// The string to update the checksum with + /// The encoding to use + void Update(string data, Encoding encoding); + } + + + /// + /// Represents the method that will be called from a codec when new data + /// are available. + /// + /// The byte array containing the processed data + /// The index of the first processed byte in data + /// The number of processed bytes available + /// On return from this method, the data may be overwritten, so grab it while you can. + /// You cannot assume that startIndex will be zero. + /// + public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); + + /// + /// Declares methods and events for implementing compressors/decompressors + /// + public interface Codec + { + /// + /// Occurs when more processed data are available. + /// + event DataAvailableHandler DataAvailable; + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data); + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + void Add(byte[] data, int offset, int count); + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + void Finish(); + + /// + /// Gets the checksum of the data that has been added so far + /// + uint Checksum { get; } + + + } + + #endregion + + #region Classes + /// + /// Encapsulates general information about the ZLib library + /// + public class Info + { + #region DLL imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern uint zlibCompileFlags(); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern string zlibVersion(); + #endregion + + #region Private stuff + private uint _flags; + + // helper function that unpacks a bitsize mask + private static int bitSize(uint bits) + { + switch (bits) + { + case 0: return 16; + case 1: return 32; + case 2: return 64; + } + return -1; + } + #endregion + + /// + /// Constructs an instance of the Info class. + /// + public Info() + { + _flags = zlibCompileFlags(); + } + + /// + /// True if the library is compiled with debug info + /// + public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } + + /// + /// True if the library is compiled with assembly optimizations + /// + public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } + + /// + /// Gets the size of the unsigned int that was compiled into Zlib + /// + public int SizeOfUInt { get { return bitSize(_flags & 3); } } + + /// + /// Gets the size of the unsigned long that was compiled into Zlib + /// + public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } + + /// + /// Gets the size of the pointers that were compiled into Zlib + /// + public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } + + /// + /// Gets the size of the z_off_t type that was compiled into Zlib + /// + public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } + + /// + /// Gets the version of ZLib as a string, e.g. "1.2.1" + /// + public static string Version { get { return zlibVersion(); } } + } + + #endregion + +} diff --git a/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj b/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj new file mode 100644 index 0000000..71eeb85 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/dotzlib/DotZLib/GZipStream.cs b/zlib/contrib/dotzlib/DotZLib/GZipStream.cs new file mode 100644 index 0000000..f861675 --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/GZipStream.cs @@ -0,0 +1,301 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + /// + /// Implements a compressed , in GZip (.gz) format. + /// + public class GZipStream : Stream, IDisposable + { + #region Dll Imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern IntPtr gzopen(string name, string mode); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzclose(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzwrite(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzread(IntPtr gzFile, int data, int length); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzgetc(IntPtr gzFile); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int gzputc(IntPtr gzFile, int c); + + #endregion + + #region Private data + private IntPtr _gzFile; + private bool _isDisposed = false; + private bool _isWriting; + #endregion + + #region Constructors + /// + /// Creates a new file as a writeable GZipStream + /// + /// The name of the compressed file to create + /// The compression level to use when adding data + /// If an error occurred in the internal zlib function + public GZipStream(string fileName, CompressLevel level) + { + _isWriting = true; + _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level)); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + } + + /// + /// Opens an existing file as a readable GZipStream + /// + /// The name of the file to open + /// If an error occurred in the internal zlib function + public GZipStream(string fileName) + { + _isWriting = false; + _gzFile = gzopen(fileName, "rb"); + if (_gzFile == IntPtr.Zero) + throw new ZLibException(-1, "Could not open " + fileName); + + } + #endregion + + #region Access properties + /// + /// Returns true of this stream can be read from, false otherwise + /// + public override bool CanRead + { + get + { + return !_isWriting; + } + } + + + /// + /// Returns false. + /// + public override bool CanSeek + { + get + { + return false; + } + } + + /// + /// Returns true if this tsream is writeable, false otherwise + /// + public override bool CanWrite + { + get + { + return _isWriting; + } + } + #endregion + + #region Destructor & IDispose stuff + + /// + /// Destroys this instance + /// + ~GZipStream() + { + cleanUp(false); + } + + /// + /// Closes the external file handle + /// + public void Dispose() + { + cleanUp(true); + } + + // Does the actual closing of the file handle. + private void cleanUp(bool isDisposing) + { + if (!_isDisposed) + { + gzclose(_gzFile); + _isDisposed = true; + } + } + #endregion + + #region Basic reading and writing + /// + /// Attempts to read a number of bytes from the stream. + /// + /// The destination data buffer + /// The index of the first destination byte in buffer + /// The number of bytes requested + /// The number of bytes read + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not readable. + /// If this stream has been disposed. + public override int Read(byte[] buffer, int offset, int count) + { + if (!CanRead) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + int result; + try + { + result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + return result; + } + + /// + /// Attempts to read a single byte from the stream. + /// + /// The byte that was read, or -1 in case of error or End-Of-File + public override int ReadByte() + { + if (!CanRead) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + return gzgetc(_gzFile); + } + + /// + /// Writes a number of bytes to the stream + /// + /// + /// + /// + /// If buffer is null + /// If count or offset are negative + /// If offset + count is > buffer.Length + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void Write(byte[] buffer, int offset, int count) + { + if (!CanWrite) throw new NotSupportedException(); + if (buffer == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > buffer.Length) throw new ArgumentException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); + try + { + int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); + if (result < 0) + throw new IOException(); + } + finally + { + h.Free(); + } + } + + /// + /// Writes a single byte to the stream + /// + /// The byte to add to the stream. + /// If this stream is not writeable. + /// If this stream has been disposed. + public override void WriteByte(byte value) + { + if (!CanWrite) throw new NotSupportedException(); + if (_isDisposed) throw new ObjectDisposedException("GZipStream"); + + int result = gzputc(_gzFile, (int)value); + if (result < 0) + throw new IOException(); + } + #endregion + + #region Position & length stuff + /// + /// Not supported. + /// + /// + /// Always thrown + public override void SetLength(long value) + { + throw new NotSupportedException(); + } + + /// + /// Not suppported. + /// + /// + /// + /// + /// Always thrown + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotSupportedException(); + } + + /// + /// Flushes the GZipStream. + /// + /// In this implementation, this method does nothing. This is because excessive + /// flushing may degrade the achievable compression rates. + public override void Flush() + { + // left empty on purpose + } + + /// + /// Gets/sets the current position in the GZipStream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Position + { + get + { + throw new NotSupportedException(); + } + set + { + throw new NotSupportedException(); + } + } + + /// + /// Gets the size of the stream. Not suppported. + /// + /// In this implementation this property is not supported + /// Always thrown + public override long Length + { + get + { + throw new NotSupportedException(); + } + } + #endregion + } +} diff --git a/zlib/contrib/dotzlib/DotZLib/Inflater.cs b/zlib/contrib/dotzlib/DotZLib/Inflater.cs new file mode 100644 index 0000000..4e60cda --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/Inflater.cs @@ -0,0 +1,105 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace DotZLib +{ + + /// + /// Implements a data decompressor, using the inflate algorithm in the ZLib dll + /// + public class Inflater : CodecBase + { + #region Dll imports + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] + private static extern int inflateInit_(ref ZStream sz, string vs, int size); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflate(ref ZStream sz, int flush); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateReset(ref ZStream sz); + + [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] + private static extern int inflateEnd(ref ZStream sz); + #endregion + + /// + /// Constructs an new instance of the Inflater + /// + public Inflater() : base() + { + int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); + if (retval != 0) + throw new ZLibException(retval, "Could not initialize inflater"); + + resetOutput(); + } + + + /// + /// Adds more data to the codec to be processed. + /// + /// Byte array containing the data to be added to the codec + /// The index of the first byte to add from data + /// The number of bytes to add + /// Adding data may, or may not, raise the DataAvailable event + public override void Add(byte[] data, int offset, int count) + { + if (data == null) throw new ArgumentNullException(); + if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); + if ((offset+count) > data.Length) throw new ArgumentException(); + + int total = count; + int inputIndex = offset; + int err = 0; + + while (err >= 0 && inputIndex < total) + { + copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); + err = inflate(ref _ztream, (int)FlushTypes.None); + if (err == 0) + while (_ztream.avail_out == 0) + { + OnDataAvailable(); + err = inflate(ref _ztream, (int)FlushTypes.None); + } + + inputIndex += (int)_ztream.total_in; + } + setChecksum( _ztream.adler ); + } + + + /// + /// Finishes up any pending data that needs to be processed and handled. + /// + public override void Finish() + { + int err; + do + { + err = inflate(ref _ztream, (int)FlushTypes.Finish); + OnDataAvailable(); + } + while (err == 0); + setChecksum( _ztream.adler ); + inflateReset(ref _ztream); + resetOutput(); + } + + /// + /// Closes the internal zlib inflate stream + /// + protected override void CleanUp() { inflateEnd(ref _ztream); } + + + } +} diff --git a/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/zlib/contrib/dotzlib/DotZLib/UnitTests.cs new file mode 100644 index 0000000..8dc00db --- /dev/null +++ b/zlib/contrib/dotzlib/DotZLib/UnitTests.cs @@ -0,0 +1,274 @@ +// +// © Copyright Henrik Ravn 2004 +// +// Use, modification and distribution are subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +using System; +using System.Collections; +using System.IO; + +// uncomment the define below to include unit tests +//#define nunit +#if nunit +using NUnit.Framework; + +// Unit tests for the DotZLib class library +// ---------------------------------------- +// +// Use this with NUnit 2 from http://www.nunit.org +// + +namespace DotZLibTests +{ + using DotZLib; + + // helper methods + internal class Utils + { + public static bool byteArrEqual( byte[] lhs, byte[] rhs ) + { + if (lhs.Length != rhs.Length) + return false; + for (int i = lhs.Length-1; i >= 0; --i) + if (lhs[i] != rhs[i]) + return false; + return true; + } + + } + + + [TestFixture] + public class CircBufferTests + { + #region Circular buffer tests + [Test] + public void SinglePutGet() + { + CircularBuffer buf = new CircularBuffer(10); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + + Assert.IsTrue(buf.Put( 1 )); + Assert.AreEqual( 1, buf.Size ); + Assert.AreEqual( 1, buf.Get() ); + Assert.AreEqual( 0, buf.Size ); + Assert.AreEqual( -1, buf.Get() ); + } + + [Test] + public void BlockPutGet() + { + CircularBuffer buf = new CircularBuffer(10); + byte[] arr = {1,2,3,4,5,6,7,8,9,10}; + Assert.AreEqual( 10, buf.Put(arr,0,10) ); + Assert.AreEqual( 10, buf.Size ); + Assert.IsFalse( buf.Put(11) ); + Assert.AreEqual( 1, buf.Get() ); + Assert.IsTrue( buf.Put(11) ); + + byte[] arr2 = (byte[])arr.Clone(); + Assert.AreEqual( 9, buf.Get(arr2,1,9) ); + Assert.IsTrue( Utils.byteArrEqual(arr,arr2) ); + } + + #endregion + } + + [TestFixture] + public class ChecksumTests + { + #region CRC32 Tests + [Test] + public void CRC32_Null() + { + CRC32Checksum crc32 = new CRC32Checksum(); + Assert.AreEqual( 0, crc32.Value ); + + crc32 = new CRC32Checksum(1); + Assert.AreEqual( 1, crc32.Value ); + + crc32 = new CRC32Checksum(556); + Assert.AreEqual( 556, crc32.Value ); + } + + [Test] + public void CRC32_Data() + { + CRC32Checksum crc32 = new CRC32Checksum(); + byte[] data = { 1,2,3,4,5,6,7 }; + crc32.Update(data); + Assert.AreEqual( 0x70e46888, crc32.Value ); + + crc32 = new CRC32Checksum(); + crc32.Update("penguin"); + Assert.AreEqual( 0x0e5c1a120, crc32.Value ); + + crc32 = new CRC32Checksum(1); + crc32.Update("penguin"); + Assert.AreEqual(0x43b6aa94, crc32.Value); + + } + #endregion + + #region Adler tests + + [Test] + public void Adler_Null() + { + AdlerChecksum adler = new AdlerChecksum(); + Assert.AreEqual(0, adler.Value); + + adler = new AdlerChecksum(1); + Assert.AreEqual( 1, adler.Value ); + + adler = new AdlerChecksum(556); + Assert.AreEqual( 556, adler.Value ); + } + + [Test] + public void Adler_Data() + { + AdlerChecksum adler = new AdlerChecksum(1); + byte[] data = { 1,2,3,4,5,6,7 }; + adler.Update(data); + Assert.AreEqual( 0x5b001d, adler.Value ); + + adler = new AdlerChecksum(); + adler.Update("penguin"); + Assert.AreEqual(0x0bcf02f6, adler.Value ); + + adler = new AdlerChecksum(1); + adler.Update("penguin"); + Assert.AreEqual(0x0bd602f7, adler.Value); + + } + #endregion + } + + [TestFixture] + public class InfoTests + { + #region Info tests + [Test] + public void Info_Version() + { + Info info = new Info(); + Assert.AreEqual("1.2.3", Info.Version); + Assert.AreEqual(32, info.SizeOfUInt); + Assert.AreEqual(32, info.SizeOfULong); + Assert.AreEqual(32, info.SizeOfPointer); + Assert.AreEqual(32, info.SizeOfOffset); + } + #endregion + } + + [TestFixture] + public class DeflateInflateTests + { + #region Deflate tests + [Test] + public void Deflate_Init() + { + using (Deflater def = new Deflater(CompressLevel.Default)) + { + } + } + + private ArrayList compressedData = new ArrayList(); + private uint adler1; + + private ArrayList uncompressedData = new ArrayList(); + private uint adler2; + + public void CDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + compressedData.Add(data[i+startIndex]); + } + + [Test] + public void Deflate_Compress() + { + compressedData.Clear(); + + byte[] testData = new byte[35000]; + for (int i = 0; i < testData.Length; ++i) + testData[i] = 5; + + using (Deflater def = new Deflater((CompressLevel)5)) + { + def.DataAvailable += new DataAvailableHandler(CDataAvail); + def.Add(testData); + def.Finish(); + adler1 = def.Checksum; + } + } + #endregion + + #region Inflate tests + [Test] + public void Inflate_Init() + { + using (Inflater inf = new Inflater()) + { + } + } + + private void DDataAvail(byte[] data, int startIndex, int count) + { + for (int i = 0; i < count; ++i) + uncompressedData.Add(data[i+startIndex]); + } + + [Test] + public void Inflate_Expand() + { + uncompressedData.Clear(); + + using (Inflater inf = new Inflater()) + { + inf.DataAvailable += new DataAvailableHandler(DDataAvail); + inf.Add((byte[])compressedData.ToArray(typeof(byte))); + inf.Finish(); + adler2 = inf.Checksum; + } + Assert.AreEqual( adler1, adler2 ); + } + #endregion + } + + [TestFixture] + public class GZipStreamTests + { + #region GZipStream test + [Test] + public void GZipStream_WriteRead() + { + using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best)) + { + BinaryWriter writer = new BinaryWriter(gzOut); + writer.Write("hi there"); + writer.Write(Math.PI); + writer.Write(42); + } + + using (GZipStream gzIn = new GZipStream("gzstream.gz")) + { + BinaryReader reader = new BinaryReader(gzIn); + string s = reader.ReadString(); + Assert.AreEqual("hi there",s); + double d = reader.ReadDouble(); + Assert.AreEqual(Math.PI, d); + int i = reader.ReadInt32(); + Assert.AreEqual(42,i); + } + + } + #endregion + } +} + +#endif \ No newline at end of file diff --git a/zlib/contrib/dotzlib/LICENSE_1_0.txt b/zlib/contrib/dotzlib/LICENSE_1_0.txt new file mode 100644 index 0000000..30aac2c --- /dev/null +++ b/zlib/contrib/dotzlib/LICENSE_1_0.txt @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/zlib/contrib/dotzlib/readme.txt b/zlib/contrib/dotzlib/readme.txt new file mode 100644 index 0000000..210f4b0 --- /dev/null +++ b/zlib/contrib/dotzlib/readme.txt @@ -0,0 +1,58 @@ +This directory contains a .Net wrapper class library for the ZLib1.dll + +The wrapper includes support for inflating/deflating memory buffers, +.Net streaming wrappers for the gz streams part of zlib, and wrappers +for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples. + +Directory structure: +-------------------- + +LICENSE_1_0.txt - License file. +readme.txt - This file. +DotZLib.chm - Class library documentation +DotZLib.build - NAnt build file +DotZLib.sln - Microsoft Visual Studio 2003 solution file + +DotZLib\*.cs - Source files for the class library + +Unit tests: +----------- +The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher. +To include unit tests in the build, define nunit before building. + + +Build instructions: +------------------- + +1. Using Visual Studio.Net 2003: + Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll) + will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on + you are building the release or debug version of the library. Check + DotZLib/UnitTests.cs for instructions on how to include unit tests in the + build. + +2. Using NAnt: + Open a command prompt with access to the build environment and run nant + in the same directory as the DotZLib.build file. + You can define 2 properties on the nant command-line to control the build: + debug={true|false} to toggle between release/debug builds (default=true). + nunit={true|false} to include or esclude unit tests (default=true). + Also the target clean will remove binaries. + Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release + or ./DotZLib/bin/debug, depending on whether you are building the release + or debug version of the library. + + Examples: + nant -D:debug=false -D:nunit=false + will build a release mode version of the library without unit tests. + nant + will build a debug version of the library with unit tests + nant clean + will remove all previously built files. + + +--------------------------------- +Copyright (c) Henrik Ravn 2004 + +Use, modification and distribution are subject to the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/zlib/contrib/masmx64/bld_ml64.bat b/zlib/contrib/masmx64/bld_ml64.bat new file mode 100644 index 0000000..8f9343d --- /dev/null +++ b/zlib/contrib/masmx64/bld_ml64.bat @@ -0,0 +1,2 @@ +ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +ml64.exe /Flgvmat64 /c /Zi gvmat64.asm diff --git a/zlib/contrib/masmx64/gvmat64.asm b/zlib/contrib/masmx64/gvmat64.asm new file mode 100644 index 0000000..790d655 --- /dev/null +++ b/zlib/contrib/masmx64/gvmat64.asm @@ -0,0 +1,513 @@ +;uInt longest_match_x64( +; deflate_state *s, +; IPos cur_match); /* current match */ + +; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86 +; Copyright (C) 1995-2005 Jean-loup Gailly, Brian Raiter and Gilles Vollant. +; +; File written by Gilles Vollant, by converting to assembly the longest_match +; from Jean-loup Gailly in deflate.c of zLib and infoZip zip. +; +; and by taking inspiration on asm686 with masm, optimised assembly code +; from Brian Raiter, written 1998 +; +; http://www.zlib.net +; http://www.winimage.com/zLibDll +; http://www.muppetlabs.com/~breadbox/software/assembly.html +; +; to compile this file for infozip Zip, I use option: +; ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm +; +; to compile this file for zLib, I use option: +; ml64.exe /Flgvmat64 /c /Zi gvmat64.asm +; Be carrefull to adapt zlib1222add below to your version of zLib +; (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change +; value of zlib1222add later) +; +; This file compile with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005 and Windows 2003 server DDK +; +; (you can get Windows 2003 server DDK with ml64 and cl for AMD64 from +; http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price) +; + + +;uInt longest_match(s, cur_match) +; deflate_state *s; +; IPos cur_match; /* current match */ +.code +longest_match PROC + + +;LocalVarsSize equ 88 + LocalVarsSize equ 72 + +; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12 +; free register : r14,r15 +; register can be saved : rsp + + chainlenwmask equ rsp + 8 - LocalVarsSize ; high word: current chain len + ; low word: s->wmask +;window equ rsp + xx - LocalVarsSize ; local copy of s->window ; stored in r10 +;windowbestlen equ rsp + xx - LocalVarsSize ; s->window + bestlen , use r10+r11 +;scanstart equ rsp + xx - LocalVarsSize ; first two bytes of string ; stored in r12w +;scanend equ rsp + xx - LocalVarsSize ; last two bytes of string use ebx +;scanalign equ rsp + xx - LocalVarsSize ; dword-misalignment of string r13 +;bestlen equ rsp + xx - LocalVarsSize ; size of best match so far -> r11d +;scan equ rsp + xx - LocalVarsSize ; ptr to string wanting match -> r9 +IFDEF INFOZIP +ELSE + nicematch equ (rsp + 16 - LocalVarsSize) ; a good enough match size +ENDIF + +save_rdi equ rsp + 24 - LocalVarsSize +save_rsi equ rsp + 32 - LocalVarsSize +save_rbx equ rsp + 40 - LocalVarsSize +save_rbp equ rsp + 48 - LocalVarsSize +save_r12 equ rsp + 56 - LocalVarsSize +save_r13 equ rsp + 64 - LocalVarsSize +;save_r14 equ rsp + 72 - LocalVarsSize +;save_r15 equ rsp + 80 - LocalVarsSize + + + +; all the +4 offsets are due to the addition of pending_buf_size (in zlib +; in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, remove the +4). +; Note : these value are good with a 8 bytes boundary pack structure + + + MAX_MATCH equ 258 + MIN_MATCH equ 3 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + + +;;; Offsets for fields in the deflate_state structure. These numbers +;;; are calculated from the definition of deflate_state, with the +;;; assumption that the compiler will dword-align the fields. (Thus, +;;; changing the definition of deflate_state could easily cause this +;;; program to crash horribly, without so much as a warning at +;;; compile time. Sigh.) + +; all the +zlib1222add offsets are due to the addition of fields +; in zlib in the deflate_state structure since the asm code was first written +; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)"). +; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0"). +; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8"). + + +IFDEF INFOZIP + +_DATA SEGMENT +COMM window_size:DWORD +; WMask ; 7fff +COMM window:BYTE:010040H +COMM prev:WORD:08000H +; MatchLen : unused +; PrevMatch : unused +COMM strstart:DWORD +COMM match_start:DWORD +; Lookahead : ignore +COMM prev_length:DWORD ; PrevLen +COMM max_chain_length:DWORD +COMM good_match:DWORD +COMM nice_match:DWORD +prev_ad equ OFFSET prev +window_ad equ OFFSET window +nicematch equ nice_match +_DATA ENDS +WMask equ 07fffh + +ELSE + + IFNDEF zlib1222add + zlib1222add equ 8 + ENDIF +dsWSize equ 56+zlib1222add+(zlib1222add/2) +dsWMask equ 64+zlib1222add+(zlib1222add/2) +dsWindow equ 72+zlib1222add +dsPrev equ 88+zlib1222add +dsMatchLen equ 128+zlib1222add +dsPrevMatch equ 132+zlib1222add +dsStrStart equ 140+zlib1222add +dsMatchStart equ 144+zlib1222add +dsLookahead equ 148+zlib1222add +dsPrevLen equ 152+zlib1222add +dsMaxChainLen equ 156+zlib1222add +dsGoodMatch equ 172+zlib1222add +dsNiceMatch equ 176+zlib1222add + +window_size equ [ rcx + dsWSize] +WMask equ [ rcx + dsWMask] +window_ad equ [ rcx + dsWindow] +prev_ad equ [ rcx + dsPrev] +strstart equ [ rcx + dsStrStart] +match_start equ [ rcx + dsMatchStart] +Lookahead equ [ rcx + dsLookahead] ; 0ffffffffh on infozip +prev_length equ [ rcx + dsPrevLen] +max_chain_length equ [ rcx + dsMaxChainLen] +good_match equ [ rcx + dsGoodMatch] +nice_match equ [ rcx + dsNiceMatch] +ENDIF + +; parameter 1 in r8(deflate state s), param 2 in rdx (cur match) + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r9, r10, and r11, which are scratch. + + + +;;; Save registers that the compiler may be using, and adjust esp to +;;; make room for our stack frame. + + +;;; Retrieve the function arguments. r8d will hold cur_match +;;; throughout the entire function. edx will hold the pointer to the +;;; deflate_state structure during the function's setup (before +;;; entering the main loop. + +; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match) + +; this clear high 32 bits of r8, which can be garbage in both r8 and rdx + + mov [save_rdi],rdi + mov [save_rsi],rsi + mov [save_rbx],rbx + mov [save_rbp],rbp +IFDEF INFOZIP + mov r8d,ecx +ELSE + mov r8d,edx +ENDIF + mov [save_r12],r12 + mov [save_r13],r13 +; mov [save_r14],r14 +; mov [save_r15],r15 + + +;;; uInt wmask = s->w_mask; +;;; unsigned chain_length = s->max_chain_length; +;;; if (s->prev_length >= s->good_match) { +;;; chain_length >>= 2; +;;; } + + mov edi, prev_length + mov esi, good_match + mov eax, WMask + mov ebx, max_chain_length + cmp edi, esi + jl LastMatchGood + shr ebx, 2 +LastMatchGood: + +;;; chainlen is decremented once beforehand so that the function can +;;; use the sign flag instead of the zero flag for the exit test. +;;; It is then shifted into the high word, to make room for the wmask +;;; value, which it will always accompany. + + dec ebx + shl ebx, 16 + or ebx, eax + +;;; on zlib only +;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + +IFDEF INFOZIP + mov [chainlenwmask], ebx +; on infozip nice_match = [nice_match] +ELSE + mov eax, nice_match + mov [chainlenwmask], ebx + mov r10d, Lookahead + cmp r10d, eax + cmovnl r10d, eax + mov [nicematch],r10d +ENDIF + +;;; register Bytef *scan = s->window + s->strstart; + mov r10, window_ad + mov ebp, strstart + lea r13, [r10 + rbp] + +;;; Determine how many bytes the scan ptr is off from being +;;; dword-aligned. + + mov r9,r13 + neg r13 + and r13,3 + +;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? +;;; s->strstart - (IPos)MAX_DIST(s) : NIL; +IFDEF INFOZIP + mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1)) +ELSE + mov eax, window_size + sub eax, MIN_LOOKAHEAD +ENDIF + xor edi,edi + sub ebp, eax + + mov r11d, prev_length + + cmovng ebp,edi + +;;; int best_len = s->prev_length; + + +;;; Store the sum of s->window + best_len in esi locally, and in esi. + + lea rsi,[r10+r11] + +;;; register ush scan_start = *(ushf*)scan; +;;; register ush scan_end = *(ushf*)(scan+best_len-1); +;;; Posf *prev = s->prev; + + movzx r12d,word ptr [r9] + movzx ebx, word ptr [r9 + r11 - 1] + + mov rdi, prev_ad + +;;; Jump into the main loop. + + mov edx, [chainlenwmask] + + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop1: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry1: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop2: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry2: + cmp bx,word ptr [rsi + r8 - 1] + jz LookupLoopIsZero + +LookupLoop4: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry4: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 + jmp LookupLoopIsZero + + +;;; do { +;;; match = s->window + cur_match; +;;; if (*(ushf*)(match+best_len-1) != scan_end || +;;; *(ushf*)match != scan_start) continue; +;;; [...] +;;; } while ((cur_match = prev[cur_match & wmask]) > limit +;;; && --chain_length != 0); +;;; +;;; Here is the inner loop of the function. The function will spend the +;;; majority of its time in this loop, and majority of that time will +;;; be spent in the first ten instructions. +;;; +;;; Within this loop: +;;; ebx = scanend +;;; r8d = curmatch +;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) +;;; esi = windowbestlen - i.e., (window + bestlen) +;;; edi = prev +;;; ebp = limit + +LookupLoop: + and r8d, edx + + movzx r8d, word ptr [rdi + r8*2] + cmp r8d, ebp + jbe LeaveNow + sub edx, 00010000h + js LeaveNow + +LoopEntry: + + cmp bx,word ptr [rsi + r8 - 1] + jnz LookupLoop1 +LookupLoopIsZero: + cmp r12w, word ptr [r10 + r8] + jnz LookupLoop1 + + +;;; Store the current value of chainlen. + mov [chainlenwmask], edx + +;;; Point edi to the string under scrutiny, and esi to the string we +;;; are hoping to match it up with. In actuality, esi and edi are +;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is +;;; initialized to -(MAX_MATCH_8 - scanalign). + + lea rsi,[r8+r10] + mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8) + lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8] + lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8] + + prefetcht1 [rsi+rdx] + prefetcht1 [rdi+rdx] + + +;;; Test the strings for equality, 8 bytes at a time. At the end, +;;; adjust rdx so that it is offset to the exact byte that mismatched. +;;; +;;; We already know at this point that the first three bytes of the +;;; strings match each other, and they can be safely passed over before +;;; starting the compare loop. So what this code does is skip over 0-3 +;;; bytes, as much as necessary in order to dword-align the edi +;;; pointer. (rsi will still be misaligned three times out of four.) +;;; +;;; It should be confessed that this loop usually does not represent +;;; much of the total running time. Replacing it with a more +;;; straightforward "rep cmpsb" would not drastically degrade +;;; performance. + + +LoopCmps: + mov rax, [rsi + rdx] + xor rax, [rdi + rdx] + jnz LeaveLoopCmps + + mov rax, [rsi + rdx + 8] + xor rax, [rdi + rdx + 8] + jnz LeaveLoopCmps8 + + + mov rax, [rsi + rdx + 8+8] + xor rax, [rdi + rdx + 8+8] + jnz LeaveLoopCmps16 + + add rdx,8+8+8 + + jmp short LoopCmps +LeaveLoopCmps16: add rdx,8 +LeaveLoopCmps8: add rdx,8 +LeaveLoopCmps: + + test eax, 0000FFFFh + jnz LenLower + + test eax,0ffffffffh + + jnz LenLower32 + + add rdx,4 + shr rax,32 + or ax,ax + jnz LenLower + +LenLower32: + shr eax,16 + add rdx,2 +LenLower: sub al, 1 + adc rdx, 0 +;;; Calculate the length of the match. If it is longer than MAX_MATCH, +;;; then automatically accept it as the best possible match and leave. + + lea rax, [rdi + rdx] + sub rax, r9 + cmp eax, MAX_MATCH + jge LenMaximum + +;;; If the length of the match is not longer than the best match we +;;; have so far, then forget it and return to the lookup loop. +;/////////////////////////////////// + + cmp eax, r11d + jg LongerMatch + + lea rsi,[r10+r11] + + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; s->match_start = cur_match; +;;; best_len = len; +;;; if (len >= nice_match) break; +;;; scan_end = *(ushf*)(scan+best_len-1); + +LongerMatch: + mov r11d, eax + mov match_start, r8d + cmp eax, [nicematch] + jge LeaveNow + + lea rsi,[r10+rax] + + movzx ebx, word ptr [r9 + rax - 1] + mov rdi, prev_ad + mov edx, [chainlenwmask] + jmp LookupLoop + +;;; Accept the current string, with the maximum possible length. + +LenMaximum: + mov r11d,MAX_MATCH + mov match_start, r8d + +;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len; +;;; return s->lookahead; + +LeaveNow: +IFDEF INFOZIP + mov eax,r11d +ELSE + mov eax, Lookahead + cmp r11d, eax + cmovng eax, r11d +ENDIF + +;;; Restore the stack and return from whence we came. + + + mov rsi,[save_rsi] + mov rdi,[save_rdi] + mov rbx,[save_rbx] + mov rbp,[save_rbp] + mov r12,[save_r12] + mov r13,[save_r13] +; mov r14,[save_r14] +; mov r15,[save_r15] + + + ret 0 +; please don't remove this string ! +; Your can freely use gvmat64 in any free or commercial app +; but it is far better don't remove the string in the binary! + db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0 +longest_match ENDP + +match_init PROC + ret 0 +match_init ENDP + + +END diff --git a/zlib/contrib/masmx64/gvmat64.obj b/zlib/contrib/masmx64/gvmat64.obj new file mode 100644 index 0000000000000000000000000000000000000000..a49ca029c63e24f907d7cd5d6eaa25f016c9aea5 GIT binary patch literal 4119 zcma*qeRNah9l-Hl+gQ3}CE>k*%H@!u&{Eq{OKC-E36g5cL57oQHb_Z|(WdE=w1AW2 z?RYuXODCSOO;ntFW8=*291wxYSKDiCowQkgQCE3QVX-I8>>I|vScF4pfx2Mg0)?*y>^#t9Qd=#!2`(C28u~T*0Xz&?Ze?m}y_3?uK3;D^n`cJtW zgGTqOr1q7F1&beZ}q78&b^c8IrsV1}U zy|x9O`rkP>wsV8-^CEfTe6oc&)iBYS)2Jz{(VR@9MLCV!S&d4D8g)K%VOmbJ&*?$> zfu9gtJ=@TlOeR|w)Vp2I4G$4A@;-)=?|tpcRf-%yC@J*H+h5+CL|sXRV#nP(Sd*2sO9q89g_Z>pjMxr>FZ_hEeZv zA71Oer?=YG$ix>7P5ike-EY{hZeq1Gx>KLt&6HO9h$c5QJW zoCw9rv{kWiA`xoWDre8GEu&R?S16X?!bDUHM1opPwbrsmTM%w*3&pjsMBCZ|?Fp@_ zqT=>qyA0SE)IT_ez2!WXAF@9h$yn;alhx$FM<7v+IR{mBIUFCM-4Y&*K_zF6a zpOQWr`PJy-@HM;<_v2*zJ>G(ca0VX63VZ`=@J+16x3CW1#yR*N-i7aDBmNOR_-DKa zPvS!S3*L`^#ie)({dgJ!cosu=4j;wy*nt-@j+d|t`TpyV;T2qq|Hg0Oe{ns2h8yuJ z_9Bz2Z-!yG1&i@n9F8xd3x9;8aXXI1mvJ02hcW^8;El+f$xV0wZ^i+fgv^m>coe4~ zb0Pe+^%Hmtet^@EIg#ne97riLW+}suaRy$-3j7aNB4d$ilB4d%+ zI11}WW+=RsPZQP7c<9Cr*|2}>PU%)N+L!?gs zF;b`h47cJAd=7t!&*M&f5r2(8z*muL^#jPY`fu^4IDp&n5OOd5P5e2&jlaO7_%gnW z+*^Mie}#X-UHBosf+uk|p20o%5$?zH_&WX#e}k8>4=-asUcrO-Ir3~>^7(z?Fr*K< z1CL-a(ieRM{sG6~ah!>6N<4+L@HEyTebn#73pfwyo9@NGV>5n? zi}4~pfb?1S<3I5Per8FZb+s2gMea7q8$tO0EqT$FN2FTDj^O=4j;X6Sia5KrHHTNk zqVZ^JLc4YGG_5&6Noz>0*P$3KD#T?zMqQx}X3ad5c`mCU!pgeh;br0WaDw?Pl$qCD zr3Rs%r!2@^)fR1E8Hy*CnODm=xgq^1Um%`nR<~RbjRs{*Rz)=WXlI8n8ttf*(K+dk z`Kbi}quHU%&x{a^RTHTOQ*Xe~!$VpmFo8k|KVo@2HQ`a#s(h-;OS-DW4 zE2IXfDk^K(qcXFST~(ViU)eP|-4C_N@wX(V6=d*~JlYY$&nggrDk;=qmHW7Fo_mt6obT60{<_Ji&&j_CklOvm(3fA^L)u+h;{~d51{7t~%tn71`w@ zB3`Y@U9cj%TqPQA=JE?ukzGa;seRTVC01mYQX=&YbI5I0WS0ga_0@97d@HicQlgP& z&TmC_X(t+G=3-W4m-R$y4|m9uR%Dm0L}Sd{HY;LmL}Sg|J}a`z8$@c~cgPVdvdd|r z5;J$!iWnQwcr%yJTfU0yGLC41nVV=uc9}sm(acp^5o04#?-Y#9iWnQwO=iw-MU0K; zW-}MFBD>fq7n-yB=_kXb$fcGCb>uUFg_5VHhuTcumX)8oA{yx^4+p!ptrhjAS|Hhf z0jcGoATRySr0$bCvj6&FEuc-hCS&$rKB`9rdFpSUvP=V_?7w={C<^lK$f-{kRGm8V zL{kerhZ>YxhEf@~yTUwFjoD`vm~*Gzvs8wUhNF~o7iT6ji;{Zx$YdHRske_zM!kcn z_lr#CtCZ9mMkW)YG@fE6(?MoRPUf3r=H_HJkns&=(#u8nP=;#x9;e!+`Dcw{JCWM2 zGa2=krFQO2W`GR)pq24iD}~yPGi~0XjoLpm8TGcMcEVJ~r}hI=w*t5609pOaK4? literal 0 HcmV?d00001 diff --git a/zlib/contrib/masmx64/inffas8664.c b/zlib/contrib/masmx64/inffas8664.c new file mode 100644 index 0000000..3af764d --- /dev/null +++ b/zlib/contrib/masmx64/inffas8664.c @@ -0,0 +1,186 @@ +/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding + * version for AMD64 on Windows using Microsoft C compiler + * + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Copyright (C) 2003 Chris Anderson + * Please use the copyright conditions above. + * + * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant + * + * inffas8664.c call function inffas8664fnc in inffasx64.asm + * inffasx64.asm is automatically convert from AMD64 portion of inffas86.c + * + * Dec-29-2003 -- I added AMD64 inflate asm support. This version is also + * slightly quicker on x86 systems because, instead of using rep movsb to copy + * data, it uses rep movsw, which moves data in 2-byte chunks instead of single + * bytes. I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates + * from http://fedora.linux.duke.edu/fc1_x86_64 + * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with + * 1GB ram. The 64-bit version is about 4% faster than the 32-bit version, + * when decompressing mozilla-source-1.3.tar.gz. + * + * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from + * the gcc -S output of zlib-1.2.0/inffast.c. Zlib-1.2.0 is in beta release at + * the moment. I have successfully compiled and tested this code with gcc2.96, + * gcc3.2, icc5.0, msvc6.0. It is very close to the speed of inffast.S + * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX + * enabled. I will attempt to merge the MMX code into this version. Newer + * versions of this and inffast.S can be found at + * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/ + * + */ + +#include +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* Mark Adler's comments from inffast.c: */ + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ + + + + typedef struct inffast_ar { +/* 64 32 x86 x86_64 */ +/* ar offset register */ +/* 0 0 */ void *esp; /* esp save */ +/* 8 4 */ void *ebp; /* ebp save */ +/* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */ +/* 24 12 */ unsigned char FAR *last; /* r9 while in < last */ +/* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */ +/* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */ +/* 48 24 */ unsigned char FAR *end; /* r10 while out < end */ +/* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */ +/* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */ +/* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */ +/* 80 40 */ size_t /*unsigned long */hold; /* edx rdx local strm->hold */ +/* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */ +/* 92 48 */ unsigned wsize; /* window size */ +/* 96 52 */ unsigned write; /* window write index */ +/*100 56 */ unsigned lmask; /* r12 mask for lcode */ +/*104 60 */ unsigned dmask; /* r13 mask for dcode */ +/*108 64 */ unsigned len; /* r14 match length */ +/*112 68 */ unsigned dist; /* r15 match distance */ +/*116 72 */ unsigned status; /* set when state chng*/ + } type_ar; +#ifdef ASMINF + +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + type_ar ar; + void inffas8664fnc(struct inffast_ar * par); + + + +#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64)) +#define PAD_AVAIL_IN 6 +#define PAD_AVAIL_OUT 258 +#else +#define PAD_AVAIL_IN 5 +#define PAD_AVAIL_OUT 257 +#endif + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + + ar.in = strm->next_in; + ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN); + ar.out = strm->next_out; + ar.beg = ar.out - (start - strm->avail_out); + ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT); + ar.wsize = state->wsize; + ar.write = state->write; + ar.window = state->window; + ar.hold = state->hold; + ar.bits = state->bits; + ar.lcode = state->lencode; + ar.dcode = state->distcode; + ar.lmask = (1U << state->lenbits) - 1; + ar.dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + + /* align in on 1/2 hold size boundary */ + while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) { + ar.hold += (unsigned long)*ar.in++ << ar.bits; + ar.bits += 8; + } + + inffas8664fnc(&ar); + + if (ar.status > 1) { + if (ar.status == 2) + strm->msg = "invalid literal/length code"; + else if (ar.status == 3) + strm->msg = "invalid distance code"; + else + strm->msg = "invalid distance too far back"; + state->mode = BAD; + } + else if ( ar.status == 1 ) { + state->mode = TYPE; + } + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + ar.len = ar.bits >> 3; + ar.in -= ar.len; + ar.bits -= ar.len << 3; + ar.hold &= (1U << ar.bits) - 1; + + /* update state and return */ + strm->next_in = ar.in; + strm->next_out = ar.out; + strm->avail_in = (unsigned)(ar.in < ar.last ? + PAD_AVAIL_IN + (ar.last - ar.in) : + PAD_AVAIL_IN - (ar.in - ar.last)); + strm->avail_out = (unsigned)(ar.out < ar.end ? + PAD_AVAIL_OUT + (ar.end - ar.out) : + PAD_AVAIL_OUT - (ar.out - ar.end)); + state->hold = (unsigned long)ar.hold; + state->bits = ar.bits; + return; +} + +#endif diff --git a/zlib/contrib/masmx64/inffasx64.asm b/zlib/contrib/masmx64/inffasx64.asm new file mode 100644 index 0000000..b5d93a2 --- /dev/null +++ b/zlib/contrib/masmx64/inffasx64.asm @@ -0,0 +1,392 @@ +; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding +; version for AMD64 on Windows using Microsoft C compiler +; +; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c +; inffasx64.asm is called by inffas8664.c, which contain more info. + + +; to compile this file, I use option +; ml64.exe /Flinffasx64 /c /Zi inffasx64.asm +; with Microsoft Macro Assembler (x64) for AMD64 +; +; ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK +; +; (you can get Windows 2003 server DDK with ml64 and cl.exe for AMD64 from +; http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price) +; + +.code +inffas8664fnc PROC + +; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and +; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp +; +; All registers must be preserved across the call, except for +; rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch. + + + mov [rsp-8],rsi + mov [rsp-16],rdi + mov [rsp-24],r12 + mov [rsp-32],r13 + mov [rsp-40],r14 + mov [rsp-48],r15 + mov [rsp-56],rbx + + mov rax,rcx + + mov [rax+8], rbp ; /* save regs rbp and rsp */ + mov [rax], rsp + + mov rsp, rax ; /* make rsp point to &ar */ + + mov rsi, [rsp+16] ; /* rsi = in */ + mov rdi, [rsp+32] ; /* rdi = out */ + mov r9, [rsp+24] ; /* r9 = last */ + mov r10, [rsp+48] ; /* r10 = end */ + mov rbp, [rsp+64] ; /* rbp = lcode */ + mov r11, [rsp+72] ; /* r11 = dcode */ + mov rdx, [rsp+80] ; /* rdx = hold */ + mov ebx, [rsp+88] ; /* ebx = bits */ + mov r12d, [rsp+100] ; /* r12d = lmask */ + mov r13d, [rsp+104] ; /* r13d = dmask */ + ; /* r14d = len */ + ; /* r15d = dist */ + + + cld + cmp r10, rdi + je L_one_time ; /* if only one decode left */ + cmp r9, rsi + + jne L_do_loop + + +L_one_time: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code_one_time + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + jmp L_get_length_code_one_time + +ALIGN 4 +L_while_test: + cmp r10, rdi + jbe L_break_loop + cmp r9, rsi + jbe L_break_loop + +L_do_loop: + mov r8, r12 ; /* r8 = lmask */ + cmp bl, 32 + ja L_get_length_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_length_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + mov r8, r12 ; /* r8 = lmask */ + shr eax, 16 ; /* output this.val char */ + stosb + +L_get_length_code_one_time: + and r8, rdx ; /* r8 &= hold */ + mov eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */ + +L_dolen: + mov cl, ah ; /* cl = this.bits */ + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + + test al, al + jnz L_test_for_length_base ; /* if (op != 0) 45.7% */ + + shr eax, 16 ; /* output this.val char */ + stosb + jmp L_while_test + +ALIGN 4 +L_test_for_length_base: + mov r14d, eax ; /* len = this */ + shr r14d, 16 ; /* len = this.val */ + mov cl, al + + test al, 16 + jz L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */ + and cl, 15 ; /* op &= 15 */ + jz L_decode_distance ; /* if (!op) */ + +L_add_bits_to_len: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r14d, eax ; /* len += hold & mask[op] */ + +L_decode_distance: + mov r8, r13 ; /* r8 = dmask */ + cmp bl, 32 + ja L_get_distance_code ; /* if (32 < bits) */ + + lodsd ; /* eax = *(uint *)in++ */ + mov cl, bl ; /* cl = bits, needs it for shifting */ + add bl, 32 ; /* bits += 32 */ + shl rax, cl + or rdx, rax ; /* hold |= *((uint *)in)++ << bits */ + +L_get_distance_code: + and r8, rdx ; /* r8 &= hold */ + mov eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */ + +L_dodist: + mov r15d, eax ; /* dist = this */ + shr r15d, 16 ; /* dist = this.val */ + mov cl, ah + sub bl, ah ; /* bits -= this.bits */ + shr rdx, cl ; /* hold >>= this.bits */ + mov cl, al ; /* cl = this.op */ + + test al, 16 ; /* if ((op & 16) == 0) */ + jz L_test_for_second_level_dist + and cl, 15 ; /* op &= 15 */ + jz L_check_dist_one + +L_add_bits_to_dist: + sub bl, cl + xor eax, eax + inc eax + shl eax, cl + dec eax ; /* (1 << op) - 1 */ + and eax, edx ; /* eax &= hold */ + shr rdx, cl + add r15d, eax ; /* dist += hold & ((1 << op) - 1) */ + +L_check_window: + mov r8, rsi ; /* save in so from can use it's reg */ + mov rax, rdi + sub rax, [rsp+40] ; /* nbytes = out - beg */ + + cmp eax, r15d + jb L_clip_window ; /* if (dist > nbytes) 4.2% */ + + mov ecx, r14d ; /* ecx = len */ + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + + sar ecx, 1 + jnc L_copy_two ; /* if len % 2 == 0 */ + + rep movsw + mov al, [rsi] + mov [rdi], al + inc rdi + + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +L_copy_two: + rep movsw + mov rsi, r8 ; /* move in back to %rsi, toss from */ + jmp L_while_test + +ALIGN 4 +L_check_dist_one: + cmp r15d, 1 ; /* if dist 1, is a memset */ + jne L_check_window + cmp [rsp+40], rdi ; /* if out == beg, outside window */ + je L_check_window + + mov ecx, r14d ; /* ecx = len */ + mov al, [rdi-1] + mov ah, al + + sar ecx, 1 + jnc L_set_two + mov [rdi], al + inc rdi + +L_set_two: + rep stosw + jmp L_while_test + +ALIGN 4 +L_test_for_second_level_length: + test al, 64 + jnz L_test_for_end_of_block ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r14d ; /* eax += len */ + mov eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/ + jmp L_dolen + +ALIGN 4 +L_test_for_second_level_dist: + test al, 64 + jnz L_invalid_distance_code ; /* if ((op & 64) != 0) */ + + xor eax, eax + inc eax + shl eax, cl + dec eax + and eax, edx ; /* eax &= hold */ + add eax, r15d ; /* eax += dist */ + mov eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/ + jmp L_dodist + +ALIGN 4 +L_clip_window: + mov ecx, eax ; /* ecx = nbytes */ + mov eax, [rsp+92] ; /* eax = wsize, prepare for dist cmp */ + neg ecx ; /* nbytes = -nbytes */ + + cmp eax, r15d + jb L_invalid_distance_too_far ; /* if (dist > wsize) */ + + add ecx, r15d ; /* nbytes = dist - nbytes */ + cmp dword ptr [rsp+96], 0 + jne L_wrap_around_window ; /* if (write != 0) */ + + mov rsi, [rsp+56] ; /* from = window */ + sub eax, ecx ; /* eax -= nbytes */ + add rsi, rax ; /* from += wsize - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp r14d, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* eax -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = &out[ -dist ] */ + jmp L_do_copy + +ALIGN 4 +L_wrap_around_window: + mov eax, [rsp+96] ; /* eax = write */ + cmp ecx, eax + jbe L_contiguous_in_window ; /* if (write >= nbytes) */ + + mov esi, [rsp+92] ; /* from = wsize */ + add rsi, [rsp+56] ; /* from += window */ + add rsi, rax ; /* from += write */ + sub rsi, rcx ; /* from -= nbytes */ + sub ecx, eax ; /* nbytes -= write */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, [rsp+56] ; /* from = window */ + mov ecx, [rsp+96] ; /* nbytes = write */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy + +ALIGN 4 +L_contiguous_in_window: + mov rsi, [rsp+56] ; /* rsi = window */ + add rsi, rax + sub rsi, rcx ; /* from += write - nbytes */ + + mov eax, r14d ; /* eax = len */ + cmp eax, ecx + jbe L_do_copy ; /* if (nbytes >= len) */ + + sub eax, ecx ; /* len -= nbytes */ + rep movsb + mov rsi, rdi + sub rsi, r15 ; /* from = out - dist */ + jmp L_do_copy ; /* if (nbytes >= len) */ + +ALIGN 4 +L_do_copy: + mov ecx, eax ; /* ecx = len */ + rep movsb + + mov rsi, r8 ; /* move in back to %esi, toss from */ + jmp L_while_test + +L_test_for_end_of_block: + test al, 32 + jz L_invalid_literal_length_code + mov dword ptr [rsp+116], 1 + jmp L_break_loop_with_status + +L_invalid_literal_length_code: + mov dword ptr [rsp+116], 2 + jmp L_break_loop_with_status + +L_invalid_distance_code: + mov dword ptr [rsp+116], 3 + jmp L_break_loop_with_status + +L_invalid_distance_too_far: + mov dword ptr [rsp+116], 4 + jmp L_break_loop_with_status + +L_break_loop: + mov dword ptr [rsp+116], 0 + +L_break_loop_with_status: +; /* put in, out, bits, and hold back into ar and pop esp */ + mov [rsp+16], rsi ; /* in */ + mov [rsp+32], rdi ; /* out */ + mov [rsp+88], ebx ; /* bits */ + mov [rsp+80], rdx ; /* hold */ + + mov rax, [rsp] ; /* restore rbp and rsp */ + mov rbp, [rsp+8] + mov rsp, rax + + + + mov rsi,[rsp-8] + mov rdi,[rsp-16] + mov r12,[rsp-24] + mov r13,[rsp-32] + mov r14,[rsp-40] + mov r15,[rsp-48] + mov rbx,[rsp-56] + + ret 0 +; : +; : "m" (ar) +; : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi", +; "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" +; ); + +inffas8664fnc ENDP +;_TEXT ENDS +END diff --git a/zlib/contrib/masmx64/inffasx64.obj b/zlib/contrib/masmx64/inffasx64.obj new file mode 100644 index 0000000000000000000000000000000000000000..8df5d82616098e1f791526c3cd9875b24f5ad8c0 GIT binary patch literal 5913 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 z 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 literal 0 HcmV?d00001 diff --git a/zlib/contrib/masmx86/inffas32.obj b/zlib/contrib/masmx86/inffas32.obj new file mode 100644 index 0000000000000000000000000000000000000000..bd6664d111d573b4aa7a4d4a182d33b90d705700 GIT binary patch literal 14893 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 literal 0 HcmV?d00001 diff --git a/zlib/contrib/minizip/mztools.c b/zlib/contrib/minizip/mztools.c new file mode 100644 index 0000000..8a50ee4 --- /dev/null +++ b/zlib/contrib/minizip/mztools.c @@ -0,0 +1,281 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[256]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; +} diff --git a/zlib/contrib/minizip/mztools.h b/zlib/contrib/minizip/mztools.h new file mode 100644 index 0000000..eee78dc --- /dev/null +++ b/zlib/contrib/minizip/mztools.h @@ -0,0 +1,31 @@ +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +#ifndef _zip_tools_H +#define _zip_tools_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#include "unzip.h" + +/* Repair a ZIP file (missing central directory) + file: file to recover + fileOut: output file after recovery + fileOutTmp: temporary file name used for recovery +*/ +extern int ZEXPORT unzRepair(const char* file, + const char* fileOut, + const char* fileOutTmp, + uLong* nRecovered, + uLong* bytesRecovered); + +#endif diff --git a/zlib/contrib/testzlib/testzlib.txt b/zlib/contrib/testzlib/testzlib.txt new file mode 100644 index 0000000..62258f1 --- /dev/null +++ b/zlib/contrib/testzlib/testzlib.txt @@ -0,0 +1,10 @@ +To build testzLib with Visual Studio 2005: + +copy to a directory file from : +- root of zLib tree +- contrib/testzlib +- contrib/masmx86 +- contrib/masmx64 +- contrib/vstudio/vc7 + +and open testzlib8.sln \ No newline at end of file diff --git a/zlib/contrib/vstudio/vc7/testzlib.vcproj b/zlib/contrib/vstudio/vc7/testzlib.vcproj new file mode 100644 index 0000000..97bc3e8 --- /dev/null +++ b/zlib/contrib/vstudio/vc7/testzlib.vcproj @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/miniunz.vcproj b/zlib/contrib/vstudio/vc8/miniunz.vcproj new file mode 100644 index 0000000..4af53e8 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/miniunz.vcproj @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/minizip.vcproj b/zlib/contrib/vstudio/vc8/minizip.vcproj new file mode 100644 index 0000000..85f64c4 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/minizip.vcproj @@ -0,0 +1,563 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/testzlib.vcproj b/zlib/contrib/vstudio/vc8/testzlib.vcproj new file mode 100644 index 0000000..68c3539 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/testzlib.vcproj @@ -0,0 +1,948 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/testzlibdll.vcproj b/zlib/contrib/vstudio/vc8/testzlibdll.vcproj new file mode 100644 index 0000000..f38ab5e --- /dev/null +++ b/zlib/contrib/vstudio/vc8/testzlibdll.vcproj @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/zlib.rc b/zlib/contrib/vstudio/vc8/zlib.rc new file mode 100644 index 0000000..72cb8b4 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/zlib.rc @@ -0,0 +1,32 @@ +#include + +#define IDR_VERSION1 1 +IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE + FILEVERSION 1,2,3,0 + PRODUCTVERSION 1,2,3,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEFLAGS 0 + FILEOS VOS_DOS_WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", "1.2.3.0\0" + VALUE "InternalName", "zlib\0" + VALUE "OriginalFilename", "zlib.dll\0" + VALUE "ProductName", "ZLib.DLL\0" + VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" + VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/zlib/contrib/vstudio/vc8/zlibstat.vcproj b/zlib/contrib/vstudio/vc8/zlibstat.vcproj new file mode 100644 index 0000000..fb97037 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/zlibstat.vcproj @@ -0,0 +1,870 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/contrib/vstudio/vc8/zlibvc.def b/zlib/contrib/vstudio/vc8/zlibvc.def new file mode 100644 index 0000000..a40e715 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/zlibvc.def @@ -0,0 +1,92 @@ + +VERSION 1.23 + +HEAPSIZE 1048576,8192 + +EXPORTS + adler32 @1 + compress @2 + crc32 @3 + deflate @4 + deflateCopy @5 + deflateEnd @6 + deflateInit2_ @7 + deflateInit_ @8 + deflateParams @9 + deflateReset @10 + deflateSetDictionary @11 + gzclose @12 + gzdopen @13 + gzerror @14 + gzflush @15 + gzopen @16 + gzread @17 + gzwrite @18 + inflate @19 + inflateEnd @20 + inflateInit2_ @21 + inflateInit_ @22 + inflateReset @23 + inflateSetDictionary @24 + inflateSync @25 + uncompress @26 + zlibVersion @27 + gzprintf @28 + gzputc @29 + gzgetc @30 + gzseek @31 + gzrewind @32 + gztell @33 + gzeof @34 + gzsetparams @35 + zError @36 + inflateSyncPoint @37 + get_crc_table @38 + compress2 @39 + gzputs @40 + gzgets @41 + inflateCopy @42 + inflateBackInit_ @43 + inflateBack @44 + inflateBackEnd @45 + compressBound @46 + deflateBound @47 + gzclearerr @48 + gzungetc @49 + zlibCompileFlags @50 + deflatePrime @51 + + unzOpen @61 + unzClose @62 + unzGetGlobalInfo @63 + unzGetCurrentFileInfo @64 + unzGoToFirstFile @65 + unzGoToNextFile @66 + unzOpenCurrentFile @67 + unzReadCurrentFile @68 + unzOpenCurrentFile3 @69 + unztell @70 + unzeof @71 + unzCloseCurrentFile @72 + unzGetGlobalComment @73 + unzStringFileNameCompare @74 + unzLocateFile @75 + unzGetLocalExtrafield @76 + unzOpen2 @77 + unzOpenCurrentFile2 @78 + unzOpenCurrentFilePassword @79 + + zipOpen @80 + zipOpenNewFileInZip @81 + zipWriteInFileInZip @82 + zipCloseFileInZip @83 + zipClose @84 + zipOpenNewFileInZip2 @86 + zipCloseFileInZipRaw @87 + zipOpen2 @88 + zipOpenNewFileInZip3 @89 + + unzGetFilePos @100 + unzGoToFilePos @101 + + fill_win32_filefunc @110 diff --git a/zlib/contrib/vstudio/vc8/zlibvc.sln b/zlib/contrib/vstudio/vc8/zlibvc.sln new file mode 100644 index 0000000..a815a55 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/zlibvc.sln @@ -0,0 +1,144 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" + ProjectSection(ProjectDependencies) = postProject + {8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Itanium = Debug|Itanium + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Itanium = Release|Itanium + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium + ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32 + ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64 + {AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64 + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium + {48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64 + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Itanium + {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|Itanium + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/zlib/contrib/vstudio/vc8/zlibvc.vcproj b/zlib/contrib/vstudio/vc8/zlibvc.vcproj new file mode 100644 index 0000000..e717011 --- /dev/null +++ b/zlib/contrib/vstudio/vc8/zlibvc.vcproj @@ -0,0 +1,1219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/zlib/examples/README.examples b/zlib/examples/README.examples new file mode 100644 index 0000000..5632d7a --- /dev/null +++ b/zlib/examples/README.examples @@ -0,0 +1,42 @@ +This directory contains examples of the use of zlib. + +fitblk.c + compress just enough input to nearly fill a requested output size + - zlib isn't designed to do this, but fitblk does it anyway + +gun.c + uncompress a gzip file + - illustrates the use of inflateBack() for high speed file-to-file + decompression using call-back functions + - is approximately twice as fast as gzip -d + - also provides Unix uncompress functionality, again twice as fast + +gzappend.c + append to a gzip file + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of deflatePrime() to start at any bit + +gzjoin.c + join gzip files without recalculating the crc or recompressing + - illustrates the use of the Z_BLOCK flush parameter for inflate() + - illustrates the use of crc32_combine() + +gzlog.c +gzlog.h + efficiently maintain a message log file in gzip format + - illustrates use of raw deflate and Z_SYNC_FLUSH + - illustrates use of gzip header extra field + +zlib_how.html + painfully comprehensive description of zpipe.c (see below) + - describes in excruciating detail the use of deflate() and inflate() + +zpipe.c + reads and writes zlib streams from stdin to stdout + - illustrates the proper use of deflate() and inflate() + - deeply commented in zlib_how.html (see above) + +zran.c + index a zlib or gzip stream and randomly access it + - illustrates the use of Z_BLOCK, inflatePrime(), and + inflateSetDictionary() to provide random access diff --git a/zlib/examples/fitblk.c b/zlib/examples/fitblk.c new file mode 100644 index 0000000..c61de5c --- /dev/null +++ b/zlib/examples/fitblk.c @@ -0,0 +1,233 @@ +/* fitblk.c: example of fitting compressed output to a specified size + Not copyrighted -- provided to the public domain + Version 1.1 25 November 2004 Mark Adler */ + +/* Version history: + 1.0 24 Nov 2004 First version + 1.1 25 Nov 2004 Change deflateInit2() to deflateInit() + Use fixed-size, stack-allocated raw buffers + Simplify code moving compression to subroutines + Use assert() for internal errors + Add detailed description of approach + */ + +/* Approach to just fitting a requested compressed size: + + fitblk performs three compression passes on a portion of the input + data in order to determine how much of that input will compress to + nearly the requested output block size. The first pass generates + enough deflate blocks to produce output to fill the requested + output size plus a specfied excess amount (see the EXCESS define + below). The last deflate block may go quite a bit past that, but + is discarded. The second pass decompresses and recompresses just + the compressed data that fit in the requested plus excess sized + buffer. The deflate process is terminated after that amount of + input, which is less than the amount consumed on the first pass. + The last deflate block of the result will be of a comparable size + to the final product, so that the header for that deflate block and + the compression ratio for that block will be about the same as in + the final product. The third compression pass decompresses the + result of the second step, but only the compressed data up to the + requested size minus an amount to allow the compressed stream to + complete (see the MARGIN define below). That will result in a + final compressed stream whose length is less than or equal to the + requested size. Assuming sufficient input and a requested size + greater than a few hundred bytes, the shortfall will typically be + less than ten bytes. + + If the input is short enough that the first compression completes + before filling the requested output size, then that compressed + stream is return with no recompression. + + EXCESS is chosen to be just greater than the shortfall seen in a + two pass approach similar to the above. That shortfall is due to + the last deflate block compressing more efficiently with a smaller + header on the second pass. EXCESS is set to be large enough so + that there is enough uncompressed data for the second pass to fill + out the requested size, and small enough so that the final deflate + block of the second pass will be close in size to the final deflate + block of the third and final pass. MARGIN is chosen to be just + large enough to assure that the final compression has enough room + to complete in all cases. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +/* print nastygram and leave */ +local void quit(char *why) +{ + fprintf(stderr, "fitblk abort: %s\n", why); + exit(1); +} + +#define RAWLEN 4096 /* intermediate uncompressed buffer size */ + +/* compress from file to def until provided buffer is full or end of + input reached; return last deflate() return value, or Z_ERRNO if + there was read error on the file */ +local int partcompress(FILE *in, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + def->avail_in = fread(raw, 1, RAWLEN, in); + if (ferror(in)) + return Z_ERRNO; + def->next_in = raw; + if (feof(in)) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (def->avail_out != 0 && flush == Z_NO_FLUSH); + return ret; +} + +/* recompress from inf's input to def's output; the input for inf and + the output for def are set in those structures before calling; + return last deflate() return value, or Z_MEM_ERROR if inflate() + was not able to allocate enough memory when it needed to */ +local int recompress(z_streamp inf, z_streamp def) +{ + int ret, flush; + unsigned char raw[RAWLEN]; + + flush = Z_NO_FLUSH; + do { + /* decompress */ + inf->avail_out = RAWLEN; + inf->next_out = raw; + ret = inflate(inf, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR && + ret != Z_NEED_DICT); + if (ret == Z_MEM_ERROR) + return ret; + + /* compress what was decompresed until done or no room */ + def->avail_in = RAWLEN - inf->avail_out; + def->next_in = raw; + if (inf->avail_out != 0) + flush = Z_FINISH; + ret = deflate(def, flush); + assert(ret != Z_STREAM_ERROR); + } while (ret != Z_STREAM_END && def->avail_out != 0); + return ret; +} + +#define EXCESS 256 /* empirically determined stream overage */ +#define MARGIN 8 /* amount to back off for completion */ + +/* compress from stdin to fixed-size block on stdout */ +int main(int argc, char **argv) +{ + int ret; /* return code */ + unsigned size; /* requested fixed output block size */ + unsigned have; /* bytes written by deflate() call */ + unsigned char *blk; /* intermediate and final stream */ + unsigned char *tmp; /* close to desired size stream */ + z_stream def, inf; /* zlib deflate and inflate states */ + + /* get requested output size */ + if (argc != 2) + quit("need one argument: size of output block"); + ret = strtol(argv[1], argv + 1, 10); + if (argv[1][0] != 0) + quit("argument must be a number"); + if (ret < 8) /* 8 is minimum zlib stream size */ + quit("need positive size of 8 or greater"); + size = (unsigned)ret; + + /* allocate memory for buffers and compression engine */ + blk = malloc(size + EXCESS); + def.zalloc = Z_NULL; + def.zfree = Z_NULL; + def.opaque = Z_NULL; + ret = deflateInit(&def, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK || blk == NULL) + quit("out of memory"); + + /* compress from stdin until output full, or no more input */ + def.avail_out = size + EXCESS; + def.next_out = blk; + ret = partcompress(stdin, &def); + if (ret == Z_ERRNO) + quit("error reading input"); + + /* if it all fit, then size was undersubscribed -- done! */ + if (ret == Z_STREAM_END && def.avail_out >= EXCESS) { + /* write block to stdout */ + have = size + EXCESS - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (all input)\n", + size - have, size); + return 0; + } + + /* it didn't all fit -- set up for recompression */ + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; + inf.avail_in = 0; + inf.next_in = Z_NULL; + ret = inflateInit(&inf); + tmp = malloc(size + EXCESS); + if (ret != Z_OK || tmp == NULL) + quit("out of memory"); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do first recompression close to the right amount */ + inf.avail_in = size + EXCESS; + inf.next_in = blk; + def.avail_out = size + EXCESS; + def.next_out = tmp; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + + /* set up for next reocmpression */ + ret = inflateReset(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateReset(&def); + assert(ret != Z_STREAM_ERROR); + + /* do second and final recompression (third compression) */ + inf.avail_in = size - MARGIN; /* assure stream will complete */ + inf.next_in = tmp; + def.avail_out = size; + def.next_out = blk; + ret = recompress(&inf, &def); + if (ret == Z_MEM_ERROR) + quit("out of memory"); + assert(ret == Z_STREAM_END); /* otherwise MARGIN too small */ + + /* done -- write block to stdout */ + have = size - def.avail_out; + if (fwrite(blk, 1, have, stdout) != have || ferror(stdout)) + quit("error writing output"); + + /* clean up and print results to stderr */ + free(tmp); + ret = inflateEnd(&inf); + assert(ret != Z_STREAM_ERROR); + ret = deflateEnd(&def); + assert(ret != Z_STREAM_ERROR); + free(blk); + fprintf(stderr, + "%u bytes unused out of %u requested (%lu input)\n", + size - have, size, def.total_in); + return 0; +} diff --git a/zlib/examples/gun.c b/zlib/examples/gun.c new file mode 100644 index 0000000..bfec590 --- /dev/null +++ b/zlib/examples/gun.c @@ -0,0 +1,693 @@ +/* gun.c -- simple gunzip to give an example of the use of inflateBack() + * Copyright (C) 2003, 2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.3 12 June 2005 Mark Adler */ + +/* Version history: + 1.0 16 Feb 2003 First version for testing of inflateBack() + 1.1 21 Feb 2005 Decompress concatenated gzip streams + Remove use of "this" variable (C++ keyword) + Fix return value for in() + Improve allocation failure checking + Add typecasting for void * structures + Add -h option for command version and usage + Add a bunch of comments + 1.2 20 Mar 2005 Add Unix compress (LZW) decompression + Copy file attributes from input file to output file + 1.3 12 Jun 2005 Add casts for error messages [Oberhumer] + */ + +/* + gun [ -t ] [ name ... ] + + decompresses the data in the named gzip files. If no arguments are given, + gun will decompress from stdin to stdout. The names must end in .gz, -gz, + .z, -z, _z, or .Z. The uncompressed data will be written to a file name + with the suffix stripped. On success, the original file is deleted. On + failure, the output file is deleted. For most failures, the command will + continue to process the remaining names on the command line. A memory + allocation failure will abort the command. If -t is specified, then the + listed files or stdin will be tested as gzip files for integrity (without + checking for a proper suffix), no output will be written, and no files + will be deleted. + + Like gzip, gun allows concatenated gzip streams and will decompress them, + writing all of the uncompressed data to the output. Unlike gzip, gun allows + an empty file on input, and will produce no error writing an empty output + file. + + gun will also decompress files made by Unix compress, which uses LZW + compression. These files are automatically detected by virtue of their + magic header bytes. Since the end of Unix compress stream is marked by the + end-of-file, they cannot be concantenated. If a Unix compress stream is + encountered in an input file, it is the last stream in that file. + + Like gunzip and uncompress, the file attributes of the orignal compressed + file are maintained in the final uncompressed file, to the extent that the + user permissions allow it. + + On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version + 1.2.4) is on the same file, when gun is linked with zlib 1.2.2. Also the + LZW decompression provided by gun is about twice as fast as the standard + Unix uncompress command. + */ + +/* external functions and related types and constants */ +#include /* fprintf() */ +#include /* malloc(), free() */ +#include /* strerror(), strcmp(), strlen(), memcpy() */ +#include /* errno */ +#include /* open() */ +#include /* read(), write(), close(), chown(), unlink() */ +#include +#include /* stat(), chmod() */ +#include /* utime() */ +#include "zlib.h" /* inflateBackInit(), inflateBack(), */ + /* inflateBackEnd(), crc32() */ + +/* function declaration */ +#define local static + +/* buffer constants */ +#define SIZE 32768U /* input and output buffer sizes */ +#define PIECE 16384 /* limits i/o chunks for 16-bit int case */ + +/* structure for infback() to pass to input function in() -- it maintains the + input file and a buffer of size SIZE */ +struct ind { + int infile; + unsigned char *inbuf; +}; + +/* Load input buffer, assumed to be empty, and return bytes loaded and a + pointer to them. read() is called until the buffer is full, or until it + returns end-of-file or error. Return 0 on error. */ +local unsigned in(void *in_desc, unsigned char **buf) +{ + int ret; + unsigned len; + unsigned char *next; + struct ind *me = (struct ind *)in_desc; + + next = me->inbuf; + *buf = next; + len = 0; + do { + ret = PIECE; + if ((unsigned)ret > SIZE - len) + ret = (int)(SIZE - len); + ret = (int)read(me->infile, next, ret); + if (ret == -1) { + len = 0; + break; + } + next += ret; + len += ret; + } while (ret != 0 && len < SIZE); + return len; +} + +/* structure for infback() to pass to output function out() -- it maintains the + output file, a running CRC-32 check on the output and the total number of + bytes output, both for checking against the gzip trailer. (The length in + the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and + the output is greater than 4 GB.) */ +struct outd { + int outfile; + int check; /* true if checking crc and total */ + unsigned long crc; + unsigned long total; +}; + +/* Write output buffer and update the CRC-32 and total bytes written. write() + is called until all of the output is written or an error is encountered. + On success out() returns 0. For a write failure, out() returns 1. If the + output file descriptor is -1, then nothing is written. + */ +local int out(void *out_desc, unsigned char *buf, unsigned len) +{ + int ret; + struct outd *me = (struct outd *)out_desc; + + if (me->check) { + me->crc = crc32(me->crc, buf, len); + me->total += len; + } + if (me->outfile != -1) + do { + ret = PIECE; + if ((unsigned)ret > len) + ret = (int)len; + ret = (int)write(me->outfile, buf, ret); + if (ret == -1) + return 1; + buf += ret; + len -= ret; + } while (len != 0); + return 0; +} + +/* next input byte macro for use inside lunpipe() and gunpipe() */ +#define NEXT() (have ? 0 : (have = in(indp, &next)), \ + last = have ? (have--, (int)(*next++)) : -1) + +/* memory for gunpipe() and lunpipe() -- + the first 256 entries of prefix[] and suffix[] are never used, could + have offset the index, but it's faster to waste the memory */ +unsigned char inbuf[SIZE]; /* input buffer */ +unsigned char outbuf[SIZE]; /* output buffer */ +unsigned short prefix[65536]; /* index to LZW prefix string */ +unsigned char suffix[65536]; /* one-character LZW suffix */ +unsigned char match[65280 + 2]; /* buffer for reversed match or gzip + 32K sliding window */ + +/* throw out what's left in the current bits byte buffer (this is a vestigial + aspect of the compressed data format derived from an implementation that + made use of a special VAX machine instruction!) */ +#define FLUSHCODE() \ + do { \ + left = 0; \ + rem = 0; \ + if (chunk > have) { \ + chunk -= have; \ + have = 0; \ + if (NEXT() == -1) \ + break; \ + chunk--; \ + if (chunk > have) { \ + chunk = have = 0; \ + break; \ + } \ + } \ + have -= chunk; \ + next += chunk; \ + chunk = 0; \ + } while (0) + +/* Decompress a compress (LZW) file from indp to outfile. The compress magic + header (two bytes) has already been read and verified. There are have bytes + of buffered input at next. strm is used for passing error information back + to gunpipe(). + + lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of + file, read error, or write error (a write error indicated by strm->next_in + not equal to Z_NULL), or Z_DATA_ERROR for invalid input. + */ +local int lunpipe(unsigned have, unsigned char *next, struct ind *indp, + int outfile, z_stream *strm) +{ + int last; /* last byte read by NEXT(), or -1 if EOF */ + int chunk; /* bytes left in current chunk */ + int left; /* bits left in rem */ + unsigned rem; /* unused bits from input */ + int bits; /* current bits per code */ + unsigned code; /* code, table traversal index */ + unsigned mask; /* mask for current bits codes */ + int max; /* maximum bits per code for this stream */ + int flags; /* compress flags, then block compress flag */ + unsigned end; /* last valid entry in prefix/suffix tables */ + unsigned temp; /* current code */ + unsigned prev; /* previous code */ + unsigned final; /* last character written for previous code */ + unsigned stack; /* next position for reversed string */ + unsigned outcnt; /* bytes in output buffer */ + struct outd outd; /* output structure */ + + /* set up output */ + outd.outfile = outfile; + outd.check = 0; + + /* process remainder of compress header -- a flags byte */ + flags = NEXT(); + if (last == -1) + return Z_BUF_ERROR; + if (flags & 0x60) { + strm->msg = (char *)"unknown lzw flags set"; + return Z_DATA_ERROR; + } + max = flags & 0x1f; + if (max < 9 || max > 16) { + strm->msg = (char *)"lzw bits out of range"; + return Z_DATA_ERROR; + } + if (max == 9) /* 9 doesn't really mean 9 */ + max = 10; + flags &= 0x80; /* true if block compress */ + + /* clear table */ + bits = 9; + mask = 0x1ff; + end = flags ? 256 : 255; + + /* set up: get first 9-bit code, which is the first decompressed byte, but + don't create a table entry until the next code */ + if (NEXT() == -1) /* no compressed data is ok */ + return Z_OK; + final = prev = (unsigned)last; /* low 8 bits of code */ + if (NEXT() == -1) /* missing a bit */ + return Z_BUF_ERROR; + if (last & 1) { /* code must be < 256 */ + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + rem = (unsigned)last >> 1; /* remaining 7 bits */ + left = 7; + chunk = bits - 2; /* 7 bytes left in this chunk */ + outbuf[0] = (unsigned char)final; /* write first decompressed byte */ + outcnt = 1; + + /* decode codes */ + stack = 0; + for (;;) { + /* if the table will be full after this, increment the code size */ + if (end >= mask && bits < max) { + FLUSHCODE(); + bits++; + mask <<= 1; + mask++; + } + + /* get a code of length bits */ + if (chunk == 0) /* decrement chunk modulo bits */ + chunk = bits; + code = rem; /* low bits of code */ + if (NEXT() == -1) { /* EOF is end of compressed data */ + /* write remaining buffered output */ + if (outcnt && out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + return Z_OK; + } + code += (unsigned)last << left; /* middle (or high) bits of code */ + left += 8; + chunk--; + if (bits > left) { /* need more bits */ + if (NEXT() == -1) /* can't end in middle of code */ + return Z_BUF_ERROR; + code += (unsigned)last << left; /* high bits of code */ + left += 8; + chunk--; + } + code &= mask; /* mask to current code length */ + left -= bits; /* number of unused bits */ + rem = (unsigned)last >> (8 - left); /* unused bits from last byte */ + + /* process clear code (256) */ + if (code == 256 && flags) { + FLUSHCODE(); + bits = 9; /* initialize bits and mask */ + mask = 0x1ff; + end = 255; /* empty table */ + continue; /* get next code */ + } + + /* special code to reuse last match */ + temp = code; /* save the current code */ + if (code > end) { + /* Be picky on the allowed code here, and make sure that the code + we drop through (prev) will be a valid index so that random + input does not cause an exception. The code != end + 1 check is + empirically derived, and not checked in the original uncompress + code. If this ever causes a problem, that check could be safely + removed. Leaving this check in greatly improves gun's ability + to detect random or corrupted input after a compress header. + In any case, the prev > end check must be retained. */ + if (code != end + 1 || prev > end) { + strm->msg = (char *)"invalid lzw code"; + return Z_DATA_ERROR; + } + match[stack++] = (unsigned char)final; + code = prev; + } + + /* walk through linked list to generate output in reverse order */ + while (code >= 256) { + match[stack++] = suffix[code]; + code = prefix[code]; + } + match[stack++] = (unsigned char)code; + final = code; + + /* link new table entry */ + if (end < mask) { + end++; + prefix[end] = (unsigned short)prev; + suffix[end] = (unsigned char)final; + } + + /* set previous code for next iteration */ + prev = temp; + + /* write output in forward order */ + while (stack > SIZE - outcnt) { + while (outcnt < SIZE) + outbuf[outcnt++] = match[--stack]; + if (out(&outd, outbuf, outcnt)) { + strm->next_in = outbuf; /* signal write error */ + return Z_BUF_ERROR; + } + outcnt = 0; + } + do { + outbuf[outcnt++] = match[--stack]; + } while (stack); + + /* loop for next code with final and prev as the last match, rem and + left provide the first 0..7 bits of the next code, end is the last + valid table entry */ + } +} + +/* Decompress a gzip file from infile to outfile. strm is assumed to have been + successfully initialized with inflateBackInit(). The input file may consist + of a series of gzip streams, in which case all of them will be decompressed + to the output file. If outfile is -1, then the gzip stream(s) integrity is + checked and nothing is written. + + The return value is a zlib error code: Z_MEM_ERROR if out of memory, + Z_DATA_ERROR if the header or the compressed data is invalid, or if the + trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends + prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip + stream) follows a valid gzip stream. + */ +local int gunpipe(z_stream *strm, int infile, int outfile) +{ + int ret, first, last; + unsigned have, flags, len; + unsigned char *next; + struct ind ind, *indp; + struct outd outd; + + /* setup input buffer */ + ind.infile = infile; + ind.inbuf = inbuf; + indp = &ind; + + /* decompress concatenated gzip streams */ + have = 0; /* no input data read in yet */ + first = 1; /* looking for first gzip header */ + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + for (;;) { + /* look for the two magic header bytes for a gzip stream */ + if (NEXT() == -1) { + ret = Z_OK; + break; /* empty gzip stream is ok */ + } + if (last != 31 || (NEXT() != 139 && last != 157)) { + strm->msg = (char *)"incorrect header check"; + ret = first ? Z_DATA_ERROR : Z_ERRNO; + break; /* not a gzip or compress header */ + } + first = 0; /* next non-header is junk */ + + /* process a compress (LZW) file -- can't be concatenated after this */ + if (last == 157) { + ret = lunpipe(have, next, indp, outfile, strm); + break; + } + + /* process remainder of gzip header */ + ret = Z_BUF_ERROR; + if (NEXT() != 8) { /* only deflate method allowed */ + if (last == -1) break; + strm->msg = (char *)"unknown compression method"; + ret = Z_DATA_ERROR; + break; + } + flags = NEXT(); /* header flags */ + NEXT(); /* discard mod time, xflgs, os */ + NEXT(); + NEXT(); + NEXT(); + NEXT(); + NEXT(); + if (last == -1) break; + if (flags & 0xe0) { + strm->msg = (char *)"unknown header flags set"; + ret = Z_DATA_ERROR; + break; + } + if (flags & 4) { /* extra field */ + len = NEXT(); + len += (unsigned)(NEXT()) << 8; + if (last == -1) break; + while (len > have) { + len -= have; + have = 0; + if (NEXT() == -1) break; + len--; + } + if (last == -1) break; + have -= len; + next += len; + } + if (flags & 8) /* file name */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 16) /* comment */ + while (NEXT() != 0 && last != -1) + ; + if (flags & 2) { /* header crc */ + NEXT(); + NEXT(); + } + if (last == -1) break; + + /* set up output */ + outd.outfile = outfile; + outd.check = 1; + outd.crc = crc32(0L, Z_NULL, 0); + outd.total = 0; + + /* decompress data to output */ + strm->next_in = next; + strm->avail_in = have; + ret = inflateBack(strm, in, indp, out, &outd); + if (ret != Z_STREAM_END) break; + next = strm->next_in; + have = strm->avail_in; + strm->next_in = Z_NULL; /* so Z_BUF_ERROR means EOF */ + + /* check trailer */ + ret = Z_BUF_ERROR; + if (NEXT() != (outd.crc & 0xff) || + NEXT() != ((outd.crc >> 8) & 0xff) || + NEXT() != ((outd.crc >> 16) & 0xff) || + NEXT() != ((outd.crc >> 24) & 0xff)) { + /* crc error */ + if (last != -1) { + strm->msg = (char *)"incorrect data check"; + ret = Z_DATA_ERROR; + } + break; + } + if (NEXT() != (outd.total & 0xff) || + NEXT() != ((outd.total >> 8) & 0xff) || + NEXT() != ((outd.total >> 16) & 0xff) || + NEXT() != ((outd.total >> 24) & 0xff)) { + /* length error */ + if (last != -1) { + strm->msg = (char *)"incorrect length check"; + ret = Z_DATA_ERROR; + } + break; + } + + /* go back and look for another gzip stream */ + } + + /* clean up and return */ + return ret; +} + +/* Copy file attributes, from -> to, as best we can. This is best effort, so + no errors are reported. The mode bits, including suid, sgid, and the sticky + bit are copied (if allowed), the owner's user id and group id are copied + (again if allowed), and the access and modify times are copied. */ +local void copymeta(char *from, char *to) +{ + struct stat was; + struct utimbuf when; + + /* get all of from's Unix meta data, return if not a regular file */ + if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG) + return; + + /* set to's mode bits, ignore errors */ + (void)chmod(to, was.st_mode & 07777); + + /* copy owner's user and group, ignore errors */ + (void)chown(to, was.st_uid, was.st_gid); + + /* copy access and modify times, ignore errors */ + when.actime = was.st_atime; + when.modtime = was.st_mtime; + (void)utime(to, &when); +} + +/* Decompress the file inname to the file outnname, of if test is true, just + decompress without writing and check the gzip trailer for integrity. If + inname is NULL or an empty string, read from stdin. If outname is NULL or + an empty string, write to stdout. strm is a pre-initialized inflateBack + structure. When appropriate, copy the file attributes from inname to + outname. + + gunzip() returns 1 if there is an out-of-memory error or an unexpected + return code from gunpipe(). Otherwise it returns 0. + */ +local int gunzip(z_stream *strm, char *inname, char *outname, int test) +{ + int ret; + int infile, outfile; + + /* open files */ + if (inname == NULL || *inname == 0) { + inname = "-"; + infile = 0; /* stdin */ + } + else { + infile = open(inname, O_RDONLY, 0); + if (infile == -1) { + fprintf(stderr, "gun cannot open %s\n", inname); + return 0; + } + } + if (test) + outfile = -1; + else if (outname == NULL || *outname == 0) { + outname = "-"; + outfile = 1; /* stdout */ + } + else { + outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666); + if (outfile == -1) { + close(infile); + fprintf(stderr, "gun cannot create %s\n", outname); + return 0; + } + } + errno = 0; + + /* decompress */ + ret = gunpipe(strm, infile, outfile); + if (outfile > 2) close(outfile); + if (infile > 2) close(infile); + + /* interpret result */ + switch (ret) { + case Z_OK: + case Z_ERRNO: + if (infile > 2 && outfile > 2) { + copymeta(inname, outname); /* copy attributes */ + unlink(inname); + } + if (ret == Z_ERRNO) + fprintf(stderr, "gun warning: trailing garbage ignored in %s\n", + inname); + break; + case Z_DATA_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg); + break; + case Z_MEM_ERROR: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + case Z_BUF_ERROR: + if (outfile > 2) unlink(outname); + if (strm->next_in != Z_NULL) { + fprintf(stderr, "gun write error on %s: %s\n", + outname, strerror(errno)); + } + else if (errno) { + fprintf(stderr, "gun read error on %s: %s\n", + inname, strerror(errno)); + } + else { + fprintf(stderr, "gun unexpected end of file on %s\n", + inname); + } + break; + default: + if (outfile > 2) unlink(outname); + fprintf(stderr, "gun internal error--aborting\n"); + return 1; + } + return 0; +} + +/* Process the gun command line arguments. See the command syntax near the + beginning of this source file. */ +int main(int argc, char **argv) +{ + int ret, len, test; + char *outname; + unsigned char *window; + z_stream strm; + + /* initialize inflateBack state for repeated use */ + window = match; /* reuse LZW match buffer */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = inflateBackInit(&strm, 15, window); + if (ret != Z_OK) { + fprintf(stderr, "gun out of memory error--aborting\n"); + return 1; + } + + /* decompress each file to the same name with the suffix removed */ + argc--; + argv++; + test = 0; + if (argc && strcmp(*argv, "-h") == 0) { + fprintf(stderr, "gun 1.3 (12 Jun 2005)\n"); + fprintf(stderr, "Copyright (c) 2005 Mark Adler\n"); + fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n"); + return 0; + } + if (argc && strcmp(*argv, "-t") == 0) { + test = 1; + argc--; + argv++; + } + if (argc) + do { + if (test) + outname = NULL; + else { + len = (int)strlen(*argv); + if (strcmp(*argv + len - 3, ".gz") == 0 || + strcmp(*argv + len - 3, "-gz") == 0) + len -= 3; + else if (strcmp(*argv + len - 2, ".z") == 0 || + strcmp(*argv + len - 2, "-z") == 0 || + strcmp(*argv + len - 2, "_z") == 0 || + strcmp(*argv + len - 2, ".Z") == 0) + len -= 2; + else { + fprintf(stderr, "gun error: no gz type on %s--skipping\n", + *argv); + continue; + } + outname = malloc(len + 1); + if (outname == NULL) { + fprintf(stderr, "gun out of memory error--aborting\n"); + ret = 1; + break; + } + memcpy(outname, *argv, len); + outname[len] = 0; + } + ret = gunzip(&strm, *argv, outname, test); + if (outname != NULL) free(outname); + if (ret) break; + } while (argv++, --argc); + else + ret = gunzip(&strm, NULL, NULL, test); + + /* clean up */ + inflateBackEnd(&strm); + return ret; +} diff --git a/zlib/examples/gzappend.c b/zlib/examples/gzappend.c new file mode 100644 index 0000000..e9e878e --- /dev/null +++ b/zlib/examples/gzappend.c @@ -0,0 +1,500 @@ +/* gzappend -- command to append to a gzip file + + Copyright (C) 2003 Mark Adler, all rights reserved + version 1.1, 4 Nov 2003 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 19 Oct 2003 - First version + * 1.1 4 Nov 2003 - Expand and clarify some comments and notes + * - Add version and copyright to help + * - Send help to stdout instead of stderr + * - Add some preemptive typecasts + * - Add L to constants in lseek() calls + * - Remove some debugging information in error messages + * - Use new data_type definition for zlib 1.2.1 + * - Simplfy and unify file operations + * - Finish off gzip file in gztack() + * - Use deflatePrime() instead of adding empty blocks + * - Keep gzip file clean on appended file read errors + * - Use in-place rotate instead of auxiliary buffer + * (Why you ask? Because it was fun to write!) + */ + +/* + gzappend takes a gzip file and appends to it, compressing files from the + command line or data from stdin. The gzip file is written to directly, to + avoid copying that file, in case it's large. Note that this results in the + unfriendly behavior that if gzappend fails, the gzip file is corrupted. + + This program was written to illustrate the use of the new Z_BLOCK option of + zlib 1.2.x's inflate() function. This option returns from inflate() at each + block boundary to facilitate locating and modifying the last block bit at + the start of the final deflate block. Also whether using Z_BLOCK or not, + another required feature of zlib 1.2.x is that inflate() now provides the + number of unusued bits in the last input byte used. gzappend will not work + with versions of zlib earlier than 1.2.1. + + gzappend first decompresses the gzip file internally, discarding all but + the last 32K of uncompressed data, and noting the location of the last block + bit and the number of unused bits in the last byte of the compressed data. + The gzip trailer containing the CRC-32 and length of the uncompressed data + is verified. This trailer will be later overwritten. + + Then the last block bit is cleared by seeking back in the file and rewriting + the byte that contains it. Seeking forward, the last byte of the compressed + data is saved along with the number of unused bits to initialize deflate. + + A deflate process is initialized, using the last 32K of the uncompressed + data from the gzip file to initialize the dictionary. If the total + uncompressed data was less than 32K, then all of it is used to initialize + the dictionary. The deflate output bit buffer is also initialized with the + last bits from the original deflate stream. From here on, the data to + append is simply compressed using deflate, and written to the gzip file. + When that is complete, the new CRC-32 and uncompressed length are written + as the trailer of the gzip file. + */ + +#include +#include +#include +#include +#include +#include "zlib.h" + +#define local static +#define LGCHUNK 14 +#define CHUNK (1U << LGCHUNK) +#define DSIZE 32768U + +/* print an error message and terminate with extreme prejudice */ +local void bye(char *msg1, char *msg2) +{ + fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2); + exit(1); +} + +/* return the greatest common divisor of a and b using Euclid's algorithm, + modified to be fast when one argument much greater than the other, and + coded to avoid unnecessary swapping */ +local unsigned gcd(unsigned a, unsigned b) +{ + unsigned c; + + while (a && b) + if (a > b) { + c = b; + while (a - c >= c) + c <<= 1; + a -= c; + } + else { + c = a; + while (b - c >= c) + c <<= 1; + b -= c; + } + return a + b; +} + +/* rotate list[0..len-1] left by rot positions, in place */ +local void rotate(unsigned char *list, unsigned len, unsigned rot) +{ + unsigned char tmp; + unsigned cycles; + unsigned char *start, *last, *to, *from; + + /* normalize rot and handle degenerate cases */ + if (len < 2) return; + if (rot >= len) rot %= len; + if (rot == 0) return; + + /* pointer to last entry in list */ + last = list + (len - 1); + + /* do simple left shift by one */ + if (rot == 1) { + tmp = *list; + memcpy(list, list + 1, len - 1); + *last = tmp; + return; + } + + /* do simple right shift by one */ + if (rot == len - 1) { + tmp = *last; + memmove(list + 1, list, len - 1); + *list = tmp; + return; + } + + /* otherwise do rotate as a set of cycles in place */ + cycles = gcd(len, rot); /* number of cycles */ + do { + start = from = list + cycles; /* start index is arbitrary */ + tmp = *from; /* save entry to be overwritten */ + for (;;) { + to = from; /* next step in cycle */ + from += rot; /* go right rot positions */ + if (from > last) from -= len; /* (pointer better not wrap) */ + if (from == start) break; /* all but one shifted */ + *to = *from; /* shift left */ + } + *to = tmp; /* complete the circle */ + } while (--cycles); +} + +/* structure for gzip file read operations */ +typedef struct { + int fd; /* file descriptor */ + int size; /* 1 << size is bytes in buf */ + unsigned left; /* bytes available at next */ + unsigned char *buf; /* buffer */ + unsigned char *next; /* next byte in buffer */ + char *name; /* file name for error messages */ +} file; + +/* reload buffer */ +local int readin(file *in) +{ + int len; + + len = read(in->fd, in->buf, 1 << in->size); + if (len == -1) bye("error reading ", in->name); + in->left = (unsigned)len; + in->next = in->buf; + return len; +} + +/* read from file in, exit if end-of-file */ +local int readmore(file *in) +{ + if (readin(in) == 0) bye("unexpected end of ", in->name); + return 0; +} + +#define read1(in) (in->left == 0 ? readmore(in) : 0, \ + in->left--, *(in->next)++) + +/* skip over n bytes of in */ +local void skip(file *in, unsigned n) +{ + unsigned bypass; + + if (n > in->left) { + n -= in->left; + bypass = n & ~((1U << in->size) - 1); + if (bypass) { + if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1) + bye("seeking ", in->name); + n -= bypass; + } + readmore(in); + if (n > in->left) + bye("unexpected end of ", in->name); + } + in->left -= n; + in->next += n; +} + +/* read a four-byte unsigned integer, little-endian, from in */ +unsigned long read4(file *in) +{ + unsigned long val; + + val = read1(in); + val += (unsigned)read1(in) << 8; + val += (unsigned long)read1(in) << 16; + val += (unsigned long)read1(in) << 24; + return val; +} + +/* skip over gzip header */ +local void gzheader(file *in) +{ + int flags; + unsigned n; + + if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file"); + if (read1(in) != 8) bye("unknown compression method in", in->name); + flags = read1(in); + if (flags & 0xe0) bye("unknown header flags set in", in->name); + skip(in, 6); + if (flags & 4) { + n = read1(in); + n += (unsigned)(read1(in)) << 8; + skip(in, n); + } + if (flags & 8) while (read1(in) != 0) ; + if (flags & 16) while (read1(in) != 0) ; + if (flags & 2) skip(in, 2); +} + +/* decompress gzip file "name", return strm with a deflate stream ready to + continue compression of the data in the gzip file, and return a file + descriptor pointing to where to write the compressed data -- the deflate + stream is initialized to compress using level "level" */ +local int gzscan(char *name, z_stream *strm, int level) +{ + int ret, lastbit, left, full; + unsigned have; + unsigned long crc, tot; + unsigned char *window; + off_t lastoff, end; + file gz; + + /* open gzip file */ + gz.name = name; + gz.fd = open(name, O_RDWR, 0); + if (gz.fd == -1) bye("cannot open ", name); + gz.buf = malloc(CHUNK); + if (gz.buf == NULL) bye("out of memory", ""); + gz.size = LGCHUNK; + gz.left = 0; + + /* skip gzip header */ + gzheader(&gz); + + /* prepare to decompress */ + window = malloc(DSIZE); + if (window == NULL) bye("out of memory", ""); + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = inflateInit2(strm, -15); + if (ret != Z_OK) bye("out of memory", " or library mismatch"); + + /* decompress the deflate stream, saving append information */ + lastbit = 0; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + left = 0; + strm->avail_in = gz.left; + strm->next_in = gz.next; + crc = crc32(0L, Z_NULL, 0); + have = full = 0; + do { + /* if needed, get more input */ + if (strm->avail_in == 0) { + readmore(&gz); + strm->avail_in = gz.left; + strm->next_in = gz.next; + } + + /* set up output to next available section of sliding window */ + strm->avail_out = DSIZE - have; + strm->next_out = window + have; + + /* inflate and check for errors */ + ret = inflate(strm, Z_BLOCK); + if (ret == Z_STREAM_ERROR) bye("internal stream error!", ""); + if (ret == Z_MEM_ERROR) bye("out of memory", ""); + if (ret == Z_DATA_ERROR) + bye("invalid compressed data--format violated in", name); + + /* update crc and sliding window pointer */ + crc = crc32(crc, window + have, DSIZE - have - strm->avail_out); + if (strm->avail_out) + have = DSIZE - strm->avail_out; + else { + have = 0; + full = 1; + } + + /* process end of block */ + if (strm->data_type & 128) { + if (strm->data_type & 64) + left = strm->data_type & 0x1f; + else { + lastbit = strm->data_type & 0x1f; + lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in; + } + } + } while (ret != Z_STREAM_END); + inflateEnd(strm); + gz.left = strm->avail_in; + gz.next = strm->next_in; + + /* save the location of the end of the compressed data */ + end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left; + + /* check gzip trailer and save total for deflate */ + if (crc != read4(&gz)) + bye("invalid compressed data--crc mismatch in ", name); + tot = strm->total_out; + if ((tot & 0xffffffffUL) != read4(&gz)) + bye("invalid compressed data--length mismatch in", name); + + /* if not at end of file, warn */ + if (gz.left || readin(&gz)) + fprintf(stderr, + "gzappend warning: junk at end of gzip file overwritten\n"); + + /* clear last block bit */ + lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7))); + lseek(gz.fd, -1L, SEEK_CUR); + if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name); + + /* if window wrapped, build dictionary from window by rotating */ + if (full) { + rotate(window, DSIZE, have); + have = DSIZE; + } + + /* set up deflate stream with window, crc, total_in, and leftover bits */ + ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) bye("out of memory", ""); + deflateSetDictionary(strm, window, have); + strm->adler = crc; + strm->total_in = tot; + if (left) { + lseek(gz.fd, --end, SEEK_SET); + if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name); + deflatePrime(strm, 8 - left, *gz.buf); + } + lseek(gz.fd, end, SEEK_SET); + + /* clean up and return */ + free(window); + free(gz.buf); + return gz.fd; +} + +/* append file "name" to gzip file gd using deflate stream strm -- if last + is true, then finish off the deflate stream at the end */ +local void gztack(char *name, int gd, z_stream *strm, int last) +{ + int fd, len, ret; + unsigned left; + unsigned char *in, *out; + + /* open file to compress and append */ + fd = 0; + if (name != NULL) { + fd = open(name, O_RDONLY, 0); + if (fd == -1) + fprintf(stderr, "gzappend warning: %s not found, skipping ...\n", + name); + } + + /* allocate buffers */ + in = fd == -1 ? NULL : malloc(CHUNK); + out = malloc(CHUNK); + if (out == NULL) bye("out of memory", ""); + + /* compress input file and append to gzip file */ + do { + /* get more input */ + len = fd == -1 ? 0 : read(fd, in, CHUNK); + if (len == -1) { + fprintf(stderr, + "gzappend warning: error reading %s, skipping rest ...\n", + name); + len = 0; + } + strm->avail_in = (unsigned)len; + strm->next_in = in; + if (len) strm->adler = crc32(strm->adler, in, (unsigned)len); + + /* compress and write all available output */ + do { + strm->avail_out = CHUNK; + strm->next_out = out; + ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH); + left = CHUNK - strm->avail_out; + while (left) { + len = write(gd, out + CHUNK - strm->avail_out - left, left); + if (len == -1) bye("writing gzip file", ""); + left -= (unsigned)len; + } + } while (strm->avail_out == 0 && ret != Z_STREAM_END); + } while (len != 0); + + /* write trailer after last entry */ + if (last) { + deflateEnd(strm); + out[0] = (unsigned char)(strm->adler); + out[1] = (unsigned char)(strm->adler >> 8); + out[2] = (unsigned char)(strm->adler >> 16); + out[3] = (unsigned char)(strm->adler >> 24); + out[4] = (unsigned char)(strm->total_in); + out[5] = (unsigned char)(strm->total_in >> 8); + out[6] = (unsigned char)(strm->total_in >> 16); + out[7] = (unsigned char)(strm->total_in >> 24); + len = 8; + do { + ret = write(gd, out + 8 - len, len); + if (ret == -1) bye("writing gzip file", ""); + len -= ret; + } while (len); + close(gd); + } + + /* clean up and return */ + free(out); + if (in != NULL) free(in); + if (fd > 0) close(fd); +} + +/* process the compression level option if present, scan the gzip file, and + append the specified files, or append the data from stdin if no other file + names are provided on the command line -- the gzip file must be writable + and seekable */ +int main(int argc, char **argv) +{ + int gd, level; + z_stream strm; + + /* ignore command name */ + argv++; + + /* provide usage if no arguments */ + if (*argv == NULL) { + printf("gzappend 1.1 (4 Nov 2003) Copyright (C) 2003 Mark Adler\n"); + printf( + "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n"); + return 0; + } + + /* set compression level */ + level = Z_DEFAULT_COMPRESSION; + if (argv[0][0] == '-') { + if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0) + bye("invalid compression level", ""); + level = argv[0][1] - '0'; + if (*++argv == NULL) bye("no gzip file name after options", ""); + } + + /* prepare to append to gzip file */ + gd = gzscan(*argv++, &strm, level); + + /* append files on command line, or from stdin if none */ + if (*argv == NULL) + gztack(NULL, gd, &strm, 1); + else + do { + gztack(*argv, gd, &strm, argv[1] == NULL); + } while (*++argv != NULL); + return 0; +} diff --git a/zlib/examples/gzjoin.c b/zlib/examples/gzjoin.c new file mode 100644 index 0000000..129347c --- /dev/null +++ b/zlib/examples/gzjoin.c @@ -0,0 +1,448 @@ +/* gzjoin -- command to join gzip files into one gzip file + + Copyright (C) 2004 Mark Adler, all rights reserved + version 1.0, 11 Dec 2004 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + * Change history: + * + * 1.0 11 Dec 2004 - First version + * 1.1 12 Jun 2005 - Changed ssize_t to long for portability + */ + +/* + gzjoin takes one or more gzip files on the command line and writes out a + single gzip file that will uncompress to the concatenation of the + uncompressed data from the individual gzip files. gzjoin does this without + having to recompress any of the data and without having to calculate a new + crc32 for the concatenated uncompressed data. gzjoin does however have to + decompress all of the input data in order to find the bits in the compressed + data that need to be modified to concatenate the streams. + + gzjoin does not do an integrity check on the input gzip files other than + checking the gzip header and decompressing the compressed data. They are + otherwise assumed to be complete and correct. + + Each joint between gzip files removes at least 18 bytes of previous trailer + and subsequent header, and inserts an average of about three bytes to the + compressed data in order to connect the streams. The output gzip file + has a minimal ten-byte gzip header with no file name or modification time. + + This program was written to illustrate the use of the Z_BLOCK option of + inflate() and the crc32_combine() function. gzjoin will not compile with + versions of zlib earlier than 1.2.3. + */ + +#include /* fputs(), fprintf(), fwrite(), putc() */ +#include /* exit(), malloc(), free() */ +#include /* open() */ +#include /* close(), read(), lseek() */ +#include "zlib.h" + /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */ + +#define local static + +/* exit with an error (return a value to allow use in an expression) */ +local int bail(char *why1, char *why2) +{ + fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2); + exit(1); + return 0; +} + +/* -- simple buffered file input with access to the buffer -- */ + +#define CHUNK 32768 /* must be a power of two and fit in unsigned */ + +/* bin buffered input file type */ +typedef struct { + char *name; /* name of file for error messages */ + int fd; /* file descriptor */ + unsigned left; /* bytes remaining at next */ + unsigned char *next; /* next byte to read */ + unsigned char *buf; /* allocated buffer of length CHUNK */ +} bin; + +/* close a buffered file and free allocated memory */ +local void bclose(bin *in) +{ + if (in != NULL) { + if (in->fd != -1) + close(in->fd); + if (in->buf != NULL) + free(in->buf); + free(in); + } +} + +/* open a buffered file for input, return a pointer to type bin, or NULL on + failure */ +local bin *bopen(char *name) +{ + bin *in; + + in = malloc(sizeof(bin)); + if (in == NULL) + return NULL; + in->buf = malloc(CHUNK); + in->fd = open(name, O_RDONLY, 0); + if (in->buf == NULL || in->fd == -1) { + bclose(in); + return NULL; + } + in->left = 0; + in->next = in->buf; + in->name = name; + return in; +} + +/* load buffer from file, return -1 on read error, 0 or 1 on success, with + 1 indicating that end-of-file was reached */ +local int bload(bin *in) +{ + long len; + + if (in == NULL) + return -1; + if (in->left != 0) + return 0; + in->next = in->buf; + do { + len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left); + if (len < 0) + return -1; + in->left += (unsigned)len; + } while (len != 0 && in->left < CHUNK); + return len == 0 ? 1 : 0; +} + +/* get a byte from the file, bail if end of file */ +#define bget(in) (in->left ? 0 : bload(in), \ + in->left ? (in->left--, *(in->next)++) : \ + bail("unexpected end of file on ", in->name)) + +/* get a four-byte little-endian unsigned integer from file */ +local unsigned long bget4(bin *in) +{ + unsigned long val; + + val = bget(in); + val += (unsigned long)(bget(in)) << 8; + val += (unsigned long)(bget(in)) << 16; + val += (unsigned long)(bget(in)) << 24; + return val; +} + +/* skip bytes in file */ +local void bskip(bin *in, unsigned skip) +{ + /* check pointer */ + if (in == NULL) + return; + + /* easy case -- skip bytes in buffer */ + if (skip <= in->left) { + in->left -= skip; + in->next += skip; + return; + } + + /* skip what's in buffer, discard buffer contents */ + skip -= in->left; + in->left = 0; + + /* seek past multiples of CHUNK bytes */ + if (skip > CHUNK) { + unsigned left; + + left = skip & (CHUNK - 1); + if (left == 0) { + /* exact number of chunks: seek all the way minus one byte to check + for end-of-file with a read */ + lseek(in->fd, skip - 1, SEEK_CUR); + if (read(in->fd, in->buf, 1) != 1) + bail("unexpected end of file on ", in->name); + return; + } + + /* skip the integral chunks, update skip with remainder */ + lseek(in->fd, skip - left, SEEK_CUR); + skip = left; + } + + /* read more input and skip remainder */ + bload(in); + if (skip > in->left) + bail("unexpected end of file on ", in->name); + in->left -= skip; + in->next += skip; +} + +/* -- end of buffered input functions -- */ + +/* skip the gzip header from file in */ +local void gzhead(bin *in) +{ + int flags; + + /* verify gzip magic header and compression method */ + if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8) + bail(in->name, " is not a valid gzip file"); + + /* get and verify flags */ + flags = bget(in); + if ((flags & 0xe0) != 0) + bail("unknown reserved bits set in ", in->name); + + /* skip modification time, extra flags, and os */ + bskip(in, 6); + + /* skip extra field if present */ + if (flags & 4) { + unsigned len; + + len = bget(in); + len += (unsigned)(bget(in)) << 8; + bskip(in, len); + } + + /* skip file name if present */ + if (flags & 8) + while (bget(in) != 0) + ; + + /* skip comment if present */ + if (flags & 16) + while (bget(in) != 0) + ; + + /* skip header crc if present */ + if (flags & 2) + bskip(in, 2); +} + +/* write a four-byte little-endian unsigned integer to out */ +local void put4(unsigned long val, FILE *out) +{ + putc(val & 0xff, out); + putc((val >> 8) & 0xff, out); + putc((val >> 16) & 0xff, out); + putc((val >> 24) & 0xff, out); +} + +/* Load up zlib stream from buffered input, bail if end of file */ +local void zpull(z_streamp strm, bin *in) +{ + if (in->left == 0) + bload(in); + if (in->left == 0) + bail("unexpected end of file on ", in->name); + strm->avail_in = in->left; + strm->next_in = in->next; +} + +/* Write header for gzip file to out and initialize trailer. */ +local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out) +{ + fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out); + *crc = crc32(0L, Z_NULL, 0); + *tot = 0; +} + +/* Copy the compressed data from name, zeroing the last block bit of the last + block if clr is true, and adding empty blocks as needed to get to a byte + boundary. If clr is false, then the last block becomes the last block of + the output, and the gzip trailer is written. crc and tot maintains the + crc and length (modulo 2^32) of the output for the trailer. The resulting + gzip file is written to out. gzinit() must be called before the first call + of gzcopy() to write the gzip header and to initialize crc and tot. */ +local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot, + FILE *out) +{ + int ret; /* return value from zlib functions */ + int pos; /* where the "last block" bit is in byte */ + int last; /* true if processing the last block */ + bin *in; /* buffered input file */ + unsigned char *start; /* start of compressed data in buffer */ + unsigned char *junk; /* buffer for uncompressed data -- discarded */ + z_off_t len; /* length of uncompressed data (support > 4 GB) */ + z_stream strm; /* zlib inflate stream */ + + /* open gzip file and skip header */ + in = bopen(name); + if (in == NULL) + bail("could not open ", name); + gzhead(in); + + /* allocate buffer for uncompressed data and initialize raw inflate + stream */ + junk = malloc(CHUNK); + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); + if (junk == NULL || ret != Z_OK) + bail("out of memory", ""); + + /* inflate and copy compressed data, clear last-block bit if requested */ + len = 0; + zpull(&strm, in); + start = strm.next_in; + last = start[0] & 1; + if (last && clr) + start[0] &= ~1; + strm.avail_out = 0; + for (;;) { + /* if input used and output done, write used input and get more */ + if (strm.avail_in == 0 && strm.avail_out != 0) { + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + + /* decompress -- return early when end-of-block reached */ + strm.avail_out = CHUNK; + strm.next_out = junk; + ret = inflate(&strm, Z_BLOCK); + switch (ret) { + case Z_MEM_ERROR: + bail("out of memory", ""); + case Z_DATA_ERROR: + bail("invalid compressed data in ", in->name); + } + + /* update length of uncompressed data */ + len += CHUNK - strm.avail_out; + + /* check for block boundary (only get this when block copied out) */ + if (strm.data_type & 128) { + /* if that was the last block, then done */ + if (last) + break; + + /* number of unused bits in last byte */ + pos = strm.data_type & 7; + + /* find the next last-block bit */ + if (pos != 0) { + /* next last-block bit is in last used byte */ + pos = 0x100 >> pos; + last = strm.next_in[-1] & pos; + if (last && clr) + strm.next_in[-1] &= ~pos; + } + else { + /* next last-block bit is in next unused byte */ + if (strm.avail_in == 0) { + /* don't have that byte yet -- get it */ + fwrite(start, 1, strm.next_in - start, out); + start = in->buf; + in->left = 0; + zpull(&strm, in); + } + last = strm.next_in[0] & 1; + if (last && clr) + strm.next_in[0] &= ~1; + } + } + } + + /* update buffer with unused input */ + in->left = strm.avail_in; + in->next = strm.next_in; + + /* copy used input, write empty blocks to get to byte boundary */ + pos = strm.data_type & 7; + fwrite(start, 1, in->next - start - 1, out); + last = in->next[-1]; + if (pos == 0 || !clr) + /* already at byte boundary, or last file: write last byte */ + putc(last, out); + else { + /* append empty blocks to last byte */ + last &= ((0x100 >> pos) - 1); /* assure unused bits are zero */ + if (pos & 1) { + /* odd -- append an empty stored block */ + putc(last, out); + if (pos == 1) + putc(0, out); /* two more bits in block header */ + fwrite("\0\0\xff\xff", 1, 4, out); + } + else { + /* even -- append 1, 2, or 3 empty fixed blocks */ + switch (pos) { + case 6: + putc(last | 8, out); + last = 0; + case 4: + putc(last | 0x20, out); + last = 0; + case 2: + putc(last | 0x80, out); + putc(0, out); + } + } + } + + /* update crc and tot */ + *crc = crc32_combine(*crc, bget4(in), len); + *tot += (unsigned long)len; + + /* clean up */ + inflateEnd(&strm); + free(junk); + bclose(in); + + /* write trailer if this is the last gzip file */ + if (!clr) { + put4(*crc, out); + put4(*tot, out); + } +} + +/* join the gzip files on the command line, write result to stdout */ +int main(int argc, char **argv) +{ + unsigned long crc, tot; /* running crc and total uncompressed length */ + + /* skip command name */ + argc--; + argv++; + + /* show usage if no arguments */ + if (argc == 0) { + fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n", + stderr); + return 0; + } + + /* join gzip files on command line and write to stdout */ + gzinit(&crc, &tot, stdout); + while (argc--) + gzcopy(*argv++, argc, &crc, &tot, stdout); + + /* done */ + return 0; +} diff --git a/zlib/examples/gzlog.c b/zlib/examples/gzlog.c new file mode 100644 index 0000000..f71f817 --- /dev/null +++ b/zlib/examples/gzlog.c @@ -0,0 +1,413 @@ +/* + * gzlog.c + * Copyright (C) 2004 Mark Adler + * For conditions of distribution and use, see copyright notice in gzlog.h + * version 1.0, 26 Nov 2004 + * + */ + +#include /* memcmp() */ +#include /* malloc(), free(), NULL */ +#include /* size_t, off_t */ +#include /* read(), close(), sleep(), ftruncate(), */ + /* lseek() */ +#include /* open() */ +#include /* flock() */ +#include "zlib.h" /* deflateInit2(), deflate(), deflateEnd() */ + +#include "gzlog.h" /* interface */ +#define local static + +/* log object structure */ +typedef struct { + int id; /* object identifier */ + int fd; /* log file descriptor */ + off_t extra; /* offset of extra "ap" subfield */ + off_t mark_off; /* offset of marked data */ + off_t last_off; /* offset of last block */ + unsigned long crc; /* uncompressed crc */ + unsigned long len; /* uncompressed length (modulo 2^32) */ + unsigned stored; /* length of current stored block */ +} gz_log; + +#define GZLOGID 19334 /* gz_log object identifier */ + +#define LOCK_RETRY 1 /* retry lock once a second */ +#define LOCK_PATIENCE 1200 /* try about twenty minutes before forcing */ + +/* acquire a lock on a file */ +local int lock(int fd) +{ + int patience; + + /* try to lock every LOCK_RETRY seconds for LOCK_PATIENCE seconds */ + patience = LOCK_PATIENCE; + do { + if (flock(fd, LOCK_EX + LOCK_NB) == 0) + return 0; + (void)sleep(LOCK_RETRY); + patience -= LOCK_RETRY; + } while (patience > 0); + + /* we've run out of patience -- give up */ + return -1; +} + +/* release lock */ +local void unlock(int fd) +{ + (void)flock(fd, LOCK_UN); +} + +/* release a log object */ +local void log_clean(gz_log *log) +{ + unlock(log->fd); + (void)close(log->fd); + free(log); +} + +/* read an unsigned long from a byte buffer little-endian */ +local unsigned long make_ulg(unsigned char *buf) +{ + int n; + unsigned long val; + + val = (unsigned long)(*buf++); + for (n = 8; n < 32; n += 8) + val += (unsigned long)(*buf++) << n; + return val; +} + +/* read an off_t from a byte buffer little-endian */ +local off_t make_off(unsigned char *buf) +{ + int n; + off_t val; + + val = (off_t)(*buf++); + for (n = 8; n < 64; n += 8) + val += (off_t)(*buf++) << n; + return val; +} + +/* write an unsigned long little-endian to byte buffer */ +local void dice_ulg(unsigned long val, unsigned char *buf) +{ + int n; + + for (n = 0; n < 4; n++) { + *buf++ = val & 0xff; + val >>= 8; + } +} + +/* write an off_t little-endian to byte buffer */ +local void dice_off(off_t val, unsigned char *buf) +{ + int n; + + for (n = 0; n < 8; n++) { + *buf++ = val & 0xff; + val >>= 8; + } +} + +/* initial, empty gzip file for appending */ +local char empty_gz[] = { + 0x1f, 0x8b, /* magic gzip id */ + 8, /* compression method is deflate */ + 4, /* there is an extra field */ + 0, 0, 0, 0, /* no modification time provided */ + 0, 0xff, /* no extra flags, no OS */ + 20, 0, 'a', 'p', 16, 0, /* extra field with "ap" subfield */ + 32, 0, 0, 0, 0, 0, 0, 0, /* offset of uncompressed data */ + 32, 0, 0, 0, 0, 0, 0, 0, /* offset of last block */ + 1, 0, 0, 0xff, 0xff, /* empty stored block (last) */ + 0, 0, 0, 0, /* crc */ + 0, 0, 0, 0 /* uncompressed length */ +}; + +/* initialize a log object with locking */ +void *gzlog_open(char *path) +{ + unsigned xlen; + unsigned char temp[20]; + unsigned sub_len; + int good; + gz_log *log; + + /* allocate log structure */ + log = malloc(sizeof(gz_log)); + if (log == NULL) + return NULL; + log->id = GZLOGID; + + /* open file, creating it if necessary, and locking it */ + log->fd = open(path, O_RDWR | O_CREAT, 0600); + if (log->fd < 0) { + free(log); + return NULL; + } + if (lock(log->fd)) { + close(log->fd); + free(log); + return NULL; + } + + /* if file is empty, write new gzip stream */ + if (lseek(log->fd, 0, SEEK_END) == 0) { + if (write(log->fd, empty_gz, sizeof(empty_gz)) != sizeof(empty_gz)) { + log_clean(log); + return NULL; + } + } + + /* check gzip header */ + (void)lseek(log->fd, 0, SEEK_SET); + if (read(log->fd, temp, 12) != 12 || temp[0] != 0x1f || + temp[1] != 0x8b || temp[2] != 8 || (temp[3] & 4) == 0) { + log_clean(log); + return NULL; + } + + /* process extra field to find "ap" sub-field */ + xlen = temp[10] + (temp[11] << 8); + good = 0; + while (xlen) { + if (xlen < 4 || read(log->fd, temp, 4) != 4) + break; + sub_len = temp[2]; + sub_len += temp[3] << 8; + xlen -= 4; + if (memcmp(temp, "ap", 2) == 0 && sub_len == 16) { + good = 1; + break; + } + if (xlen < sub_len) + break; + (void)lseek(log->fd, sub_len, SEEK_CUR); + xlen -= sub_len; + } + if (!good) { + log_clean(log); + return NULL; + } + + /* read in "ap" sub-field */ + log->extra = lseek(log->fd, 0, SEEK_CUR); + if (read(log->fd, temp, 16) != 16) { + log_clean(log); + return NULL; + } + log->mark_off = make_off(temp); + log->last_off = make_off(temp + 8); + + /* get crc, length of gzip file */ + (void)lseek(log->fd, log->last_off, SEEK_SET); + if (read(log->fd, temp, 13) != 13 || + memcmp(temp, "\001\000\000\377\377", 5) != 0) { + log_clean(log); + return NULL; + } + log->crc = make_ulg(temp + 5); + log->len = make_ulg(temp + 9); + + /* set up to write over empty last block */ + (void)lseek(log->fd, log->last_off + 5, SEEK_SET); + log->stored = 0; + return (void *)log; +} + +/* maximum amount to put in a stored block before starting a new one */ +#define MAX_BLOCK 16384 + +/* write a block to a log object */ +int gzlog_write(void *obj, char *data, size_t len) +{ + size_t some; + unsigned char temp[5]; + gz_log *log; + + /* check object */ + log = (gz_log *)obj; + if (log == NULL || log->id != GZLOGID) + return 1; + + /* write stored blocks until all of the input is written */ + do { + some = MAX_BLOCK - log->stored; + if (some > len) + some = len; + if (write(log->fd, data, some) != some) + return 1; + log->crc = crc32(log->crc, data, some); + log->len += some; + len -= some; + data += some; + log->stored += some; + + /* if the stored block is full, end it and start another */ + if (log->stored == MAX_BLOCK) { + (void)lseek(log->fd, log->last_off, SEEK_SET); + temp[0] = 0; + dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16), + temp + 1); + if (write(log->fd, temp, 5) != 5) + return 1; + log->last_off = lseek(log->fd, log->stored, SEEK_CUR); + (void)lseek(log->fd, 5, SEEK_CUR); + log->stored = 0; + } + } while (len); + return 0; +} + +/* recompress the remaining stored deflate data in place */ +local int recomp(gz_log *log) +{ + z_stream strm; + size_t len, max; + unsigned char *in; + unsigned char *out; + unsigned char temp[16]; + + /* allocate space and read it all in (it's around 1 MB) */ + len = log->last_off - log->mark_off; + max = len + (len >> 12) + (len >> 14) + 11; + out = malloc(max); + if (out == NULL) + return 1; + in = malloc(len); + if (in == NULL) { + free(out); + return 1; + } + (void)lseek(log->fd, log->mark_off, SEEK_SET); + if (read(log->fd, in, len) != len) { + free(in); + free(out); + return 1; + } + + /* recompress in memory, decoding stored data as we go */ + /* note: this assumes that unsigned is four bytes or more */ + /* consider not making that assumption */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + if (deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, -15, 8, + Z_DEFAULT_STRATEGY) != Z_OK) { + free(in); + free(out); + return 1; + } + strm.next_in = in; + strm.avail_out = max; + strm.next_out = out; + while (len >= 5) { + if (strm.next_in[0] != 0) + break; + strm.avail_in = strm.next_in[1] + (strm.next_in[2] << 8); + strm.next_in += 5; + len -= 5; + if (strm.avail_in != 0) { + if (len < strm.avail_in) + break; + len -= strm.avail_in; + (void)deflate(&strm, Z_NO_FLUSH); + if (strm.avail_in != 0 || strm.avail_out == 0) + break; + } + } + (void)deflate(&strm, Z_SYNC_FLUSH); + (void)deflateEnd(&strm); + free(in); + if (len != 0 || strm.avail_out == 0) { + free(out); + return 1; + } + + /* overwrite stored data with compressed data */ + (void)lseek(log->fd, log->mark_off, SEEK_SET); + len = max - strm.avail_out; + if (write(log->fd, out, len) != len) { + free(out); + return 1; + } + free(out); + + /* write last empty block, crc, and length */ + log->mark_off = log->last_off = lseek(log->fd, 0, SEEK_CUR); + temp[0] = 1; + dice_ulg(0xffffL << 16, temp + 1); + dice_ulg(log->crc, temp + 5); + dice_ulg(log->len, temp + 9); + if (write(log->fd, temp, 13) != 13) + return 1; + + /* truncate file to discard remaining stored data and old trailer */ + ftruncate(log->fd, lseek(log->fd, 0, SEEK_CUR)); + + /* update extra field to point to new last empty block */ + (void)lseek(log->fd, log->extra, SEEK_SET); + dice_off(log->mark_off, temp); + dice_off(log->last_off, temp + 8); + if (write(log->fd, temp, 16) != 16) + return 1; + return 0; +} + +/* maximum accumulation of stored blocks before compressing */ +#define MAX_STORED 1048576 + +/* close log object */ +int gzlog_close(void *obj) +{ + unsigned char temp[8]; + gz_log *log; + + /* check object */ + log = (gz_log *)obj; + if (log == NULL || log->id != GZLOGID) + return 1; + + /* go to start of most recent block being written */ + (void)lseek(log->fd, log->last_off, SEEK_SET); + + /* if some stuff was put there, update block */ + if (log->stored) { + temp[0] = 0; + dice_ulg(log->stored + ((unsigned long)(~log->stored) << 16), + temp + 1); + if (write(log->fd, temp, 5) != 5) + return 1; + log->last_off = lseek(log->fd, log->stored, SEEK_CUR); + } + + /* write last block (empty) */ + if (write(log->fd, "\001\000\000\377\377", 5) != 5) + return 1; + + /* write updated crc and uncompressed length */ + dice_ulg(log->crc, temp); + dice_ulg(log->len, temp + 4); + if (write(log->fd, temp, 8) != 8) + return 1; + + /* put offset of that last block in gzip extra block */ + (void)lseek(log->fd, log->extra + 8, SEEK_SET); + dice_off(log->last_off, temp); + if (write(log->fd, temp, 8) != 8) + return 1; + + /* if more than 1 MB stored, then time to compress it */ + if (log->last_off - log->mark_off > MAX_STORED) { + if (recomp(log)) + return 1; + } + + /* unlock and close file */ + log_clean(log); + return 0; +} diff --git a/zlib/examples/gzlog.h b/zlib/examples/gzlog.h new file mode 100644 index 0000000..a800bd5 --- /dev/null +++ b/zlib/examples/gzlog.h @@ -0,0 +1,58 @@ +/* gzlog.h + Copyright (C) 2004 Mark Adler, all rights reserved + version 1.0, 26 Nov 2004 + + This software is provided 'as-is', without any express or implied + warranty. In no event will the author be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Mark Adler madler@alumni.caltech.edu + */ + +/* + The gzlog object allows writing short messages to a gzipped log file, + opening the log file locked for small bursts, and then closing it. The log + object works by appending stored data to the gzip file until 1 MB has been + accumulated. At that time, the stored data is compressed, and replaces the + uncompressed data in the file. The log file is truncated to its new size at + that time. After closing, the log file is always valid gzip file that can + decompressed to recover what was written. + + A gzip header "extra" field contains two file offsets for appending. The + first points to just after the last compressed data. The second points to + the last stored block in the deflate stream, which is empty. All of the + data between those pointers is uncompressed. + */ + +/* Open a gzlog object, creating the log file if it does not exist. Return + NULL on error. Note that gzlog_open() could take a long time to return if + there is difficulty in locking the file. */ +void *gzlog_open(char *path); + +/* Write to a gzlog object. Return non-zero on error. This function will + simply write data to the file uncompressed. Compression of the data + will not occur until gzlog_close() is called. It is expected that + gzlog_write() is used for a short message, and then gzlog_close() is + called. If a large amount of data is to be written, then the application + should write no more than 1 MB at a time with gzlog_write() before + calling gzlog_close() and then gzlog_open() again. */ +int gzlog_write(void *log, char *data, size_t len); + +/* Close a gzlog object. Return non-zero on error. The log file is locked + until this function is called. This function will compress stored data + at the end of the gzip file if at least 1 MB has been accumulated. Note + that the file will not be a valid gzip file until this function completes. + */ +int gzlog_close(void *log); diff --git a/zlib/examples/zlib_how.html b/zlib/examples/zlib_how.html new file mode 100644 index 0000000..40998db --- /dev/null +++ b/zlib/examples/zlib_how.html @@ -0,0 +1,523 @@ + + + + +zlib Usage Example + + + +

zlib Usage Example

+We often get questions about how the deflate() and inflate() functions should be used. +Users wonder when they should provide more input, when they should use more output, +what to do with a Z_BUF_ERROR, how to make sure the process terminates properly, and +so on. So for those who have read zlib.h (a few times), and +would like further edification, below is an annotated example in C of simple routines to compress and decompress +from an input file to an output file using deflate() and inflate() respectively. The +annotations are interspersed between lines of the code. So please read between the lines. +We hope this helps explain some of the intricacies of zlib. +

+Without further adieu, here is the program zpipe.c: +


+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.2  9 November 2004  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+ */
+
+We now include the header files for the required definitions. From +stdio.h we use fopen(), fread(), fwrite(), +feof(), ferror(), and fclose() for file i/o, and +fputs() for error messages. From string.h we use +strcmp() for command line argument processing. +From assert.h we use the assert() macro. +From zlib.h +we use the basic compression functions deflateInit(), +deflate(), and deflateEnd(), and the basic decompression +functions inflateInit(), inflate(), and +inflateEnd(). +

+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+CHUNK is simply the buffer size for feeding data to and pulling data +from the zlib routines. Larger buffer sizes would be more efficient, +especially for inflate(). If the memory is available, buffers sizes +on the order of 128K or 256K bytes should be used. +

+#define CHUNK 16384
+
+The def() routine compresses data from an input file to an output file. The output data +will be in the zlib format, which is different from the gzip or zip +formats. The zlib format has a very small header of only two bytes to identify it as +a zlib stream and to provide decoding information, and a four-byte trailer with a fast +check value to verify the integrity of the uncompressed data after decoding. +

+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+
+Here are the local variables for def(). ret will be used for zlib +return codes. flush will keep track of the current flushing state for deflate(), +which is either no flushing, or flush to completion after the end of the input file is reached. +have is the amount of data returned from deflate(). The strm structure +is used to pass information to and from the zlib routines, and to maintain the +deflate() state. in and out are the input and output buffers for +deflate(). +

+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    char in[CHUNK];
+    char out[CHUNK];
+
+The first thing we do is to initialize the zlib state for compression using +deflateInit(). This must be done before the first use of deflate(). +The zalloc, zfree, and opaque fields in the strm +structure must be initialized before calling deflateInit(). Here they are +set to the zlib constant Z_NULL to request that zlib use +the default memory allocation routines. An application may also choose to provide +custom memory allocation routines here. deflateInit() will allocate on the +order of 256K bytes for the internal state. +(See zlib Technical Details.) +

+deflateInit() is called with a pointer to the structure to be initialized and +the compression level, which is an integer in the range of -1 to 9. Lower compression +levels result in faster execution, but less compression. Higher levels result in +greater compression, but slower execution. The zlib constant Z_DEFAULT_COMPRESSION, +equal to -1, +provides a good compromise between compression and speed and is equivalent to level 6. +Level 0 actually does no compression at all, and in fact expands the data slightly to produce +the zlib format (it is not a byte-for-byte copy of the input). +More advanced applications of zlib +may use deflateInit2() here instead. Such an application may want to reduce how +much memory will be used, at some price in compression. Or it may need to request a +gzip header and trailer instead of a zlib header and trailer, or raw +encoding with no header or trailer at all. +

+We must check the return value of deflateInit() against the zlib constant +Z_OK to make sure that it was able to +allocate memory for the internal state, and that the provided arguments were valid. +deflateInit() will also check that the version of zlib that the zlib.h +file came from matches the version of zlib actually linked with the program. This +is especially important for environments in which zlib is a shared library. +

+Note that an application can initialize multiple, independent zlib streams, which can +operate in parallel. The state information maintained in the structure allows the zlib +routines to be reentrant. +


+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+With the pleasantries out of the way, now we can get down to business. The outer do-loop +reads all of the input file and exits at the bottom of the loop once end-of-file is reached. +This loop contains the only call of deflate(). So we must make sure that all of the +input data has been processed and that all of the output data has been generated and consumed +before we fall out of the loop at the bottom. +

+    /* compress until end of file */
+    do {
+
+We start off by reading data from the input file. The number of bytes read is put directly +into avail_in, and a pointer to those bytes is put into next_in. We also +check to see if end-of-file on the input has been reached. If we are at the end of file, then flush is set to the +zlib constant Z_FINISH, which is later passed to deflate() to +indicate that this is the last chunk of input data to compress. We need to use feof() +to check for end-of-file as opposed to seeing if fewer than CHUNK bytes have been read. The +reason is that if the input file length is an exact multiple of CHUNK, we will miss +the fact that we got to the end-of-file, and not know to tell deflate() to finish +up the compressed stream. If we are not yet at the end of the input, then the zlib +constant Z_NO_FLUSH will be passed to deflate to indicate that we are still +in the middle of the uncompressed data. +

+If there is an error in reading from the input file, the process is aborted with +deflateEnd() being called to free the allocated zlib state before returning +the error. We wouldn't want a memory leak, now would we? deflateEnd() can be called +at any time after the state has been initialized. Once that's done, deflateInit() (or +deflateInit2()) would have to be called to start a new compression process. There is +no point here in checking the deflateEnd() return code. The deallocation can't fail. +


+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+The inner do-loop passes our chunk of input data to deflate(), and then +keeps calling deflate() until it is done producing output. Once there is no more +new output, deflate() is guaranteed to have consumed all of the input, i.e., +avail_in will be zero. +

+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+
+Output space is provided to deflate() by setting avail_out to the number +of available output bytes and next_out to a pointer to that space. +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we call the compression engine itself, deflate(). It takes as many of the +avail_in bytes at next_in as it can process, and writes as many as +avail_out bytes to next_out. Those counters and pointers are then +updated past the input data consumed and the output data written. It is the amount of +output space available that may limit how much input is consumed. +Hence the inner loop to make sure that +all of the input is consumed by providing more output space each time. Since avail_in +and next_in are updated by deflate(), we don't have to mess with those +between deflate() calls until it's all used up. +

+The parameters to deflate() are a pointer to the strm structure containing +the input and output information and the internal compression engine state, and a parameter +indicating whether and how to flush data to the output. Normally deflate will consume +several K bytes of input data before producing any output (except for the header), in order +to accumulate statistics on the data for optimum compression. It will then put out a burst of +compressed data, and proceed to consume more input before the next burst. Eventually, +deflate() +must be told to terminate the stream, complete the compression with provided input data, and +write out the trailer check value. deflate() will continue to compress normally as long +as the flush parameter is Z_NO_FLUSH. Once the Z_FINISH parameter is provided, +deflate() will begin to complete the compressed output stream. However depending on how +much output space is provided, deflate() may have to be called several times until it +has provided the complete compressed stream, even after it has consumed all of the input. The flush +parameter must continue to be Z_FINISH for those subsequent calls. +

+There are other values of the flush parameter that are used in more advanced applications. You can +force deflate() to produce a burst of output that encodes all of the input data provided +so far, even if it wouldn't have otherwise, for example to control data latency on a link with +compressed data. You can also ask that deflate() do that as well as erase any history up to +that point so that what follows can be decompressed independently, for example for random access +applications. Both requests will degrade compression by an amount depending on how often such +requests are made. +

+deflate() has a return value that can indicate errors, yet we do not check it here. Why +not? Well, it turns out that deflate() can do no wrong here. Let's go through +deflate()'s return values and dispense with them one by one. The possible values are +Z_OK, Z_STREAM_END, Z_STREAM_ERROR, or Z_BUF_ERROR. Z_OK +is, well, ok. Z_STREAM_END is also ok and will be returned for the last call of +deflate(). This is already guaranteed by calling deflate() with Z_FINISH +until it has no more output. Z_STREAM_ERROR is only possible if the stream is not +initialized properly, but we did initialize it properly. There is no harm in checking for +Z_STREAM_ERROR here, for example to check for the possibility that some +other part of the application inadvertently clobbered the memory containing the zlib state. +Z_BUF_ERROR will be explained further below, but +suffice it to say that this is simply an indication that deflate() could not consume +more input or produce more output. deflate() can be called again with more output space +or more available input, which it will be in this code. +


+            ret = deflate(&strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+
+Now we compute how much output deflate() provided on the last call, which is the +difference between how much space was provided before the call, and how much output space +is still available after the call. Then that data, if any, is written to the output file. +We can then reuse the output buffer for the next call of deflate(). Again if there +is a file i/o error, we call deflateEnd() before returning to avoid a memory leak. +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop is repeated until the last deflate() call fails to fill the +provided output buffer. Then we know that deflate() has done as much as it can with +the provided input, and that all of that input has been consumed. We can then fall out of this +loop and reuse the input buffer. +

+The way we tell that deflate() has no more output is by seeing that it did not fill +the output buffer, leaving avail_out greater than zero. However suppose that +deflate() has no more output, but just so happened to exactly fill the output buffer! +avail_out is zero, and we can't tell that deflate() has done all it can. +As far as we know, deflate() +has more output for us. So we call it again. But now deflate() produces no output +at all, and avail_out remains unchanged as CHUNK. That deflate() call +wasn't able to do anything, either consume input or produce output, and so it returns +Z_BUF_ERROR. (See, I told you I'd cover this later.) However this is not a problem at +all. Now we finally have the desired indication that deflate() is really done, +and so we drop out of the inner loop to provide more input to deflate(). +

+With flush set to Z_FINISH, this final set of deflate() calls will +complete the output stream. Once that is done, subsequent calls of deflate() would return +Z_STREAM_ERROR if the flush parameter is not Z_FINISH, and do no more processing +until the state is reinitialized. +

+Some applications of zlib have two loops that call deflate() +instead of the single inner loop we have here. The first loop would call +without flushing and feed all of the data to deflate(). The second loop would call +deflate() with no more +data and the Z_FINISH parameter to complete the process. As you can see from this +example, that can be avoided by simply keeping track of the current flush state. +


+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+
+Now we check to see if we have already processed all of the input file. That information was +saved in the flush variable, so we see if that was set to Z_FINISH. If so, +then we're done and we fall out of the outer loop. We're guaranteed to get Z_STREAM_END +from the last deflate() call, since we ran it until the last chunk of input was +consumed and all of the output was generated. +

+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+
+The process is complete, but we still need to deallocate the state to avoid a memory leak +(or rather more like a memory hemorrhage if you didn't do this). Then +finally we can return with a happy return value. +

+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+Now we do the same thing for decompression in the inf() routine. inf() +decompresses what is hopefully a valid zlib stream from the input file and writes the +uncompressed data to the output file. Much of the discussion above for def() +applies to inf() as well, so the discussion here will focus on the differences between +the two. +

+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+
+The local variables have the same functionality as they do for def(). The +only difference is that there is no flush variable, since inflate() +can tell from the zlib stream itself when the stream is complete. +

+    int ret;
+    unsigned have;
+    z_stream strm;
+    char in[CHUNK];
+    char out[CHUNK];
+
+The initialization of the state is the same, except that there is no compression level, +of course, and two more elements of the structure are initialized. avail_in +and next_in must be initialized before calling inflateInit(). This +is because the application has the option to provide the start of the zlib stream in +order for inflateInit() to have access to information about the compression +method to aid in memory allocation. In the current implementation of zlib +(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of +inflate() anyway. However those fields must be initialized since later versions +of zlib that provide more compression methods may take advantage of this interface. +In any case, no decompression is performed by inflateInit(), so the +avail_out and next_out fields do not need to be initialized before calling. +

+Here avail_in is set to zero and next_in is set to Z_NULL to +indicate that no input data is being provided. +


+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+The outer do-loop decompresses input until inflate() indicates +that it has reached the end of the compressed data and has produced all of the uncompressed +output. This is in contrast to def() which processes all of the input file. +If end-of-file is reached before the compressed data self-terminates, then the compressed +data is incomplete and an error is returned. +

+    /* decompress until deflate stream ends or end of file */
+    do {
+
+We read input data and set the strm structure accordingly. If we've reached the +end of the input file, then we leave the outer loop and report an error, since the +compressed data is incomplete. Note that we may read more data than is eventually consumed +by inflate(), if the input file continues past the zlib stream. +For applications where zlib streams are embedded in other data, this routine would +need to be modified to return the unused data, or at least indicate how much of the input +data was not used, so the application would know where to pick up after the zlib stream. +

+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+The inner do-loop has the same function it did in def(), which is to +keep calling inflate() until has generated all of the output it can with the +provided input. +

+        /* run inflate() on input until output buffer not full */
+        do {
+
+Just like in def(), the same output space is provided for each call of inflate(). +

+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+
+Now we run the decompression engine itself. There is no need to adjust the flush parameter, since +the zlib format is self-terminating. The main difference here is that there are +return values that we need to pay attention to. Z_DATA_ERROR +indicates that inflate() detected an error in the zlib compressed data format, +which means that either the data is not a zlib stream to begin with, or that the data was +corrupted somewhere along the way since it was compressed. The other error to be processed is +Z_MEM_ERROR, which can occur since memory allocation is deferred until inflate() +needs it, unlike deflate(), whose memory is allocated at the start by deflateInit(). +

+Advanced applications may use +deflateSetDictionary() to prime deflate() with a set of likely data to improve the +first 32K or so of compression. This is noted in the zlib header, so inflate() +requests that that dictionary be provided before it can start to decompress. Without the dictionary, +correct decompression is not possible. For this routine, we have no idea what the dictionary is, +so the Z_NEED_DICT indication is converted to a Z_DATA_ERROR. +

+inflate() can also return Z_STREAM_ERROR, which should not be possible here, +but could be checked for as noted above for def(). Z_BUF_ERROR does not need to be +checked for here, for the same reasons noted for def(). Z_STREAM_END will be +checked for later. +


+            ret = inflate(&strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&strm);
+                return ret;
+            }
+
+The output of inflate() is handled identically to that of deflate(). +

+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&strm);
+                return Z_ERRNO;
+            }
+
+The inner do-loop ends when inflate() has no more output as indicated +by not filling the output buffer, just as for deflate(). In this case, we cannot +assert that strm.avail_in will be zero, since the deflate stream may end before the file +does. +

+        } while (strm.avail_out == 0);
+
+The outer do-loop ends when inflate() reports that it has reached the +end of the input zlib stream, has completed the decompression and integrity +check, and has provided all of the output. This is indicated by the inflate() +return value Z_STREAM_END. The inner loop is guaranteed to leave ret +equal to Z_STREAM_END if the last chunk of the input file read contained the end +of the zlib stream. So if the return value is not Z_STREAM_END, the +loop continues to read more input. +

+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+At this point, decompression successfully completed, or we broke out of the loop due to no +more data being available from the input file. If the last inflate() return value +is not Z_STREAM_END, then the zlib stream was incomplete and a data error +is returned. Otherwise, we return with a happy return value. Of course, inflateEnd() +is called first to avoid a memory leak. +

+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+That ends the routines that directly use zlib. The following routines make this +a command-line program by running data through the above routines from stdin to +stdout, and handling any errors reported by def() or inf(). +

+zerr() is used to interpret the possible error codes from def() +and inf(), as detailed in their comments above, and print out an error message. +Note that these are only a subset of the possible return values from deflate() +and inflate(). +


+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+
+Here is the main() routine used to test def() and inf(). The +zpipe command is simply a compression pipe from stdin to stdout, if +no arguments are given, or it is a decompression pipe if zpipe -d is used. If any other +arguments are provided, no compression or decompression is performed. Instead a usage +message is displayed. Examples are zpipe < foo.txt > foo.txt.z to compress, and +zpipe -d < foo.txt.z > foo.txt to decompress. +

+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
+        return 1;
+    }
+}
+
+
+Copyright (c) 2004 by Mark Adler
Last modified 13 November 2004
+ + diff --git a/zlib/examples/zpipe.c b/zlib/examples/zpipe.c new file mode 100644 index 0000000..26abb56 --- /dev/null +++ b/zlib/examples/zpipe.c @@ -0,0 +1,191 @@ +/* zpipe.c: example of proper use of zlib's inflate() and deflate() + Not copyrighted -- provided to the public domain + Version 1.2 9 November 2004 Mark Adler */ + +/* Version history: + 1.0 30 Oct 2004 First version + 1.1 8 Nov 2004 Add void casting for unused return values + Use switch statement for inflate() return values + 1.2 9 Nov 2004 Add assertions to document zlib guarantees + 1.3 6 Apr 2005 Remove incorrect assertion in inf() + */ + +#include +#include +#include +#include "zlib.h" + +#define CHUNK 16384 + +/* Compress from file source to file dest until EOF on source. + def() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +int def(FILE *source, FILE *dest, int level) +{ + int ret, flush; + unsigned have; + z_stream strm; + char in[CHUNK]; + char out[CHUNK]; + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + ret = deflateInit(&strm, level); + if (ret != Z_OK) + return ret; + + /* compress until end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = deflate(&strm, flush); /* no bad return value */ + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)deflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + assert(strm.avail_in == 0); /* all input will be used */ + + /* done when last data in file processed */ + } while (flush != Z_FINISH); + assert(ret == Z_STREAM_END); /* stream will be complete */ + + /* clean up and return */ + (void)deflateEnd(&strm); + return Z_OK; +} + +/* Decompress from file source to file dest until stream ends or EOF. + inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_DATA_ERROR if the deflate data is + invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and + the version of the library linked do not match, or Z_ERRNO if there + is an error reading or writing the files. */ +int inf(FILE *source, FILE *dest) +{ + int ret; + unsigned have; + z_stream strm; + char in[CHUNK]; + char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +/* report a zlib or i/o error */ +void zerr(int ret) +{ + fputs("zpipe: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + } +} + +/* compress or decompress from stdin to stdout */ +int main(int argc, char **argv) +{ + int ret; + + /* do compression if no arguments */ + if (argc == 1) { + ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* do decompression if -d specified */ + else if (argc == 2 && strcmp(argv[1], "-d") == 0) { + ret = inf(stdin, stdout); + if (ret != Z_OK) + zerr(ret); + return ret; + } + + /* otherwise, report usage */ + else { + fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr); + return 1; + } +} diff --git a/zlib/examples/zran.c b/zlib/examples/zran.c new file mode 100644 index 0000000..8c7717e --- /dev/null +++ b/zlib/examples/zran.c @@ -0,0 +1,404 @@ +/* zran.c -- example of zlib/gzip stream indexing and random access + * Copyright (C) 2005 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + Version 1.0 29 May 2005 Mark Adler */ + +/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary() + for random access of a compressed file. A file containing a zlib or gzip + stream is provided on the command line. The compressed stream is decoded in + its entirety, and an index built with access points about every SPAN bytes + in the uncompressed output. The compressed file is left open, and can then + be read randomly, having to decompress on the average SPAN/2 uncompressed + bytes before getting to the desired block of data. + + An access point can be created at the start of any deflate block, by saving + the starting file offset and bit of that block, and the 32K bytes of + uncompressed data that precede that block. Also the uncompressed offset of + that block is saved to provide a referece for locating a desired starting + point in the uncompressed stream. build_index() works by decompressing the + input zlib or gzip stream a block at a time, and at the end of each block + deciding if enough uncompressed data has gone by to justify the creation of + a new access point. If so, that point is saved in a data structure that + grows as needed to accommodate the points. + + To use the index, an offset in the uncompressed data is provided, for which + the latest accees point at or preceding that offset is located in the index. + The input file is positioned to the specified location in the index, and if + necessary the first few bits of the compressed data is read from the file. + inflate is initialized with those bits and the 32K of uncompressed data, and + the decompression then proceeds until the desired offset in the file is + reached. Then the decompression continues to read the desired uncompressed + data from the file. + + Another approach would be to generate the index on demand. In that case, + requests for random access reads from the compressed data would try to use + the index, but if a read far enough past the end of the index is required, + then further index entries would be generated and added. + + There is some fair bit of overhead to starting inflation for the random + access, mainly copying the 32K byte dictionary. So if small pieces of the + file are being accessed, it would make sense to implement a cache to hold + some lookahead and avoid many calls to extract() for small lengths. + + Another way to build an index would be to use inflateCopy(). That would + not be constrained to have access points at block boundaries, but requires + more memory per access point, and also cannot be saved to file due to the + use of pointers in the state. The approach here allows for storage of the + index in a file. + */ + +#include +#include +#include +#include "zlib.h" + +#define local static + +#define SPAN 1048576L /* desired distance between access points */ +#define WINSIZE 32768U /* sliding window size */ +#define CHUNK 16384 /* file input buffer size */ + +/* access point entry */ +struct point { + off_t out; /* corresponding offset in uncompressed data */ + off_t in; /* offset in input file of first full byte */ + int bits; /* number of bits (1-7) from byte at in - 1, or 0 */ + unsigned char window[WINSIZE]; /* preceding 32K of uncompressed data */ +}; + +/* access point list */ +struct access { + int have; /* number of list entries filled in */ + int size; /* number of list entries allocated */ + struct point *list; /* allocated list */ +}; + +/* Deallocate an index built by build_index() */ +local void free_index(struct access *index) +{ + if (index != NULL) { + free(index->list); + free(index); + } +} + +/* Add an entry to the access point list. If out of memory, deallocate the + existing list and return NULL. */ +local struct access *addpoint(struct access *index, int bits, + off_t in, off_t out, unsigned left, unsigned char *window) +{ + struct point *next; + + /* if list is empty, create it (start with eight points) */ + if (index == NULL) { + index = malloc(sizeof(struct access)); + if (index == NULL) return NULL; + index->list = malloc(sizeof(struct point) << 3); + if (index->list == NULL) { + free(index); + return NULL; + } + index->size = 8; + index->have = 0; + } + + /* if list is full, make it bigger */ + else if (index->have == index->size) { + index->size <<= 1; + next = realloc(index->list, sizeof(struct point) * index->size); + if (next == NULL) { + free_index(index); + return NULL; + } + index->list = next; + } + + /* fill in entry and increment how many we have */ + next = index->list + index->have; + next->bits = bits; + next->in = in; + next->out = out; + if (left) + memcpy(next->window, window + WINSIZE - left, left); + if (left < WINSIZE) + memcpy(next->window + left, window, WINSIZE - left); + index->have++; + + /* return list, possibly reallocated */ + return index; +} + +/* Make one entire pass through the compressed stream and build an index, with + access points about every span bytes of uncompressed output -- span is + chosen to balance the speed of random access against the memory requirements + of the list, about 32K bytes per access point. Note that data after the end + of the first zlib or gzip stream in the file is ignored. build_index() + returns the number of access points on success (>= 1), Z_MEM_ERROR for out + of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a + file read error. On success, *built points to the resulting index. */ +local int build_index(FILE *in, off_t span, struct access **built) +{ + int ret; + off_t totin, totout; /* our own total counters to avoid 4GB limit */ + off_t last; /* totout value of last access point */ + struct access *index; /* access points being generated */ + z_stream strm; + unsigned char input[CHUNK]; + unsigned char window[WINSIZE]; + + /* initialize inflate */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, 47); /* automatic zlib or gzip decoding */ + if (ret != Z_OK) + return ret; + + /* inflate the input, maintain a sliding window, and build an index -- this + also validates the integrity of the compressed data using the check + information at the end of the gzip or zlib stream */ + totin = totout = last = 0; + index = NULL; /* will be allocated by first addpoint() */ + strm.avail_out = 0; + do { + /* get some compressed data from input file */ + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto build_index_error; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto build_index_error; + } + strm.next_in = input; + + /* process all of that, or until end of stream */ + do { + /* reset sliding window if necessary */ + if (strm.avail_out == 0) { + strm.avail_out = WINSIZE; + strm.next_out = window; + } + + /* inflate until out of input, output, or at end of block -- + update the total input and output counters */ + totin += strm.avail_in; + totout += strm.avail_out; + ret = inflate(&strm, Z_BLOCK); /* return at end of block */ + totin -= strm.avail_in; + totout -= strm.avail_out; + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto build_index_error; + if (ret == Z_STREAM_END) + break; + + /* if at end of block, consider adding an index entry (note that if + data_type indicates an end-of-block, then all of the + uncompressed data from that block has been delivered, and none + of the compressed data after that block has been consumed, + except for up to seven bits) -- the totout == 0 provides an + entry point after the zlib or gzip header, and assures that the + index always has at least one access point; we avoid creating an + access point after the last block by checking bit 6 of data_type + */ + if ((strm.data_type & 128) && !(strm.data_type & 64) && + (totout == 0 || totout - last > span)) { + index = addpoint(index, strm.data_type & 7, totin, + totout, strm.avail_out, window); + if (index == NULL) { + ret = Z_MEM_ERROR; + goto build_index_error; + } + last = totout; + } + } while (strm.avail_in != 0); + } while (ret != Z_STREAM_END); + + /* clean up and return index (release unused entries in list) */ + (void)inflateEnd(&strm); + index = realloc(index, sizeof(struct point) * index->have); + index->size = index->have; + *built = index; + return index->size; + + /* return error */ + build_index_error: + (void)inflateEnd(&strm); + if (index != NULL) + free_index(index); + return ret; +} + +/* Use the index to read len bytes from offset into buf, return bytes read or + negative for error (Z_DATA_ERROR or Z_MEM_ERROR). If data is requested past + the end of the uncompressed data, then extract() will return a value less + than len, indicating how much as actually read into buf. This function + should not return a data error unless the file was modified since the index + was generated. extract() may also return Z_ERRNO if there is an error on + reading or seeking the input file. */ +local int extract(FILE *in, struct access *index, off_t offset, + unsigned char *buf, int len) +{ + int ret, skip; + z_stream strm; + struct point *here; + unsigned char input[CHUNK]; + unsigned char discard[WINSIZE]; + + /* proceed only if something reasonable to do */ + if (len < 0) + return 0; + + /* find where in stream to start */ + here = index->list; + ret = index->have; + while (--ret && here[1].out <= offset) + here++; + + /* initialize file and inflate state to start there */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit2(&strm, -15); /* raw inflate */ + if (ret != Z_OK) + return ret; + ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET); + if (ret == -1) + goto extract_ret; + if (here->bits) { + ret = getc(in); + if (ret == -1) { + ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR; + goto extract_ret; + } + (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits)); + } + (void)inflateSetDictionary(&strm, here->window, WINSIZE); + + /* skip uncompressed bytes until offset reached, then satisfy request */ + offset -= here->out; + strm.avail_in = 0; + skip = 1; /* while skipping to offset */ + do { + /* define where to put uncompressed data, and how much */ + if (offset == 0 && skip) { /* at offset now */ + strm.avail_out = len; + strm.next_out = buf; + skip = 0; /* only do this once */ + } + if (offset > WINSIZE) { /* skip WINSIZE bytes */ + strm.avail_out = WINSIZE; + strm.next_out = discard; + offset -= WINSIZE; + } + else if (offset != 0) { /* last skip */ + strm.avail_out = (unsigned)offset; + strm.next_out = discard; + offset = 0; + } + + /* uncompress until avail_out filled, or end of stream */ + do { + if (strm.avail_in == 0) { + strm.avail_in = fread(input, 1, CHUNK, in); + if (ferror(in)) { + ret = Z_ERRNO; + goto extract_ret; + } + if (strm.avail_in == 0) { + ret = Z_DATA_ERROR; + goto extract_ret; + } + strm.next_in = input; + } + ret = inflate(&strm, Z_NO_FLUSH); /* normal inflate */ + if (ret == Z_NEED_DICT) + ret = Z_DATA_ERROR; + if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR) + goto extract_ret; + if (ret == Z_STREAM_END) + break; + } while (strm.avail_out != 0); + + /* if reach end of stream, then don't keep trying to get more */ + if (ret == Z_STREAM_END) + break; + + /* do until offset reached and requested data read, or stream ends */ + } while (skip); + + /* compute number of uncompressed bytes read after offset */ + ret = skip ? 0 : len - strm.avail_out; + + /* clean up and return bytes read or error */ + extract_ret: + (void)inflateEnd(&strm); + return ret; +} + +/* Demonstrate the use of build_index() and extract() by processing the file + provided on the command line, and the extracting 16K from about 2/3rds of + the way through the uncompressed output, and writing that to stdout. */ +int main(int argc, char **argv) +{ + int len; + off_t offset; + FILE *in; + struct access *index; + unsigned char buf[CHUNK]; + + /* open input file */ + if (argc != 2) { + fprintf(stderr, "usage: zran file.gz\n"); + return 1; + } + in = fopen(argv[1], "rb"); + if (in == NULL) { + fprintf(stderr, "zran: could not open %s for reading\n", argv[1]); + return 1; + } + + /* build index */ + len = build_index(in, SPAN, &index); + if (len < 0) { + fclose(in); + switch (len) { + case Z_MEM_ERROR: + fprintf(stderr, "zran: out of memory\n"); + break; + case Z_DATA_ERROR: + fprintf(stderr, "zran: compressed data error in %s\n", argv[1]); + break; + case Z_ERRNO: + fprintf(stderr, "zran: read error on %s\n", argv[1]); + break; + default: + fprintf(stderr, "zran: error %d while building index\n", len); + } + return 1; + } + fprintf(stderr, "zran: built index with %d access points\n", len); + + /* use index by reading some bytes from an arbitrary offset */ + offset = (index->list[index->have - 1].out << 1) / 3; + len = extract(in, index, offset, buf, CHUNK); + if (len < 0) + fprintf(stderr, "zran: extraction failed: %s error\n", + len == Z_MEM_ERROR ? "out of memory" : "input corrupted"); + else { + fwrite(buf, 1, len, stdout); + fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset); + } + + /* clean up and exit */ + free_index(index); + fclose(in); + return 0; +} diff --git a/zlib/make_vms.com b/zlib/make_vms.com new file mode 100644 index 0000000..c2a1fb5 --- /dev/null +++ b/zlib/make_vms.com @@ -0,0 +1,461 @@ +$! make libz under VMS written by +$! Martin P.J. Zinser +$! +$! +$ on error then goto err_exit +$! +$! +$! Just some general constants... +$! +$ true = 1 +$ false = 0 +$ tmpnam = "temp_" + f$getjpi("","pid") +$ SAY = "WRITE SYS$OUTPUT" +$! +$! Setup variables holding "config" information +$! +$ Make = "" +$ name = "Zlib" +$ version = "?.?.?" +$ v_string = "ZLIB_VERSION" +$ v_file = "zlib.h" +$ ccopt = "" +$ lopts = "" +$ linkonly = false +$ optfile = name + ".opt" +$ its_decc = false +$ its_vaxc = false +$ its_gnuc = false +$ axp = f$getsyi("HW_MODEL").ge.1024 +$ s_case = false +$! Check for MMK/MMS +$! +$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" +$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" +$! +$! +$ gosub find_version +$! +$ gosub check_opts +$! +$! Look for the compiler used +$! +$ gosub check_compiler +$ if its_decc +$ then +$ ccopt = "/prefix=all" + ccopt +$ if f$trnlnm("SYS") .eqs. "" +$ then +$ if axp +$ then +$ define sys sys$library: +$ else +$ ccopt = "/decc" + ccopt +$ define sys decc$library_include: +$ endif +$ endif +$ endif +$ if its_vaxc .or. its_gnuc +$ then +$ if f$trnlnm("SYS").eqs."" then define sys sys$library: +$ endif +$! +$! Build the thing plain or with mms +$! +$ write sys$output "Compiling Zlib sources ..." +$ if make.eqs."" +$ then +$ dele example.obj;*,minigzip.obj;* +$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - + adler32.c zlib.h zconf.h +$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - + compress.c zlib.h zconf.h +$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - + crc32.c zlib.h zconf.h +$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - + deflate.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - + gzio.c zutil.h zlib.h zconf.h +$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - + infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - + inffast.c zutil.h zlib.h zconf.h inffast.h +$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - + inflate.c zutil.h zlib.h zconf.h infblock.h +$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - + inftrees.c zutil.h zlib.h zconf.h inftrees.h +$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - + trees.c deflate.h zutil.h zlib.h zconf.h +$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - + uncompr.c zlib.h zconf.h +$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - + zutil.c zutil.h zlib.h zconf.h +$ write sys$output "Building Zlib ..." +$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ +$ write sys$output "Building example..." +$ CALL MAKE example.OBJ "CC ''CCOPT' example" - + example.c zlib.h zconf.h +$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb +$ if f$search("x11vms:xvmsutils.olb") .nes. "" +$ then +$ write sys$output "Building minigzip..." +$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - + minigzip.c zlib.h zconf.h +$ call make minigzip.exe - + "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - + minigzip.obj libz.olb +$ endif +$ else +$ gosub crea_mms +$ SAY "Make ''name' ''version' with ''Make' " +$ 'make' +$ endif +$! +$! Alpha gets a shareable image +$! +$ If axp +$ Then +$ gosub crea_olist +$ write sys$output "Creating libzshr.exe" +$ call anal_obj_axp modules.opt _link.opt +$ if s_case +$ then +$ open/append optf modules.opt +$ write optf "case_sensitive=YES" +$ close optf +$ endif +$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt +$ endif +$ write sys$output "Zlib build completed" +$ exit +$CC_ERR: +$ write sys$output "C compiler required to build ''name'" +$ goto err_exit +$ERR_EXIT: +$ set message/facil/ident/sever/text +$ write sys$output "Exiting..." +$ exit 2 +$! +$! +$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES +$ V = 'F$Verify(0) +$! P1 = What we are trying to make +$! P2 = Command to make it +$! P3 - P8 What it depends on +$ +$ If F$Search(P1) .Eqs. "" Then Goto Makeit +$ Time = F$CvTime(F$File(P1,"RDT")) +$arg=3 +$Loop: +$ Argument = P'arg +$ If Argument .Eqs. "" Then Goto Exit +$ El=0 +$Loop2: +$ File = F$Element(El," ",Argument) +$ If File .Eqs. " " Then Goto Endl +$ AFile = "" +$Loop3: +$ OFile = AFile +$ AFile = F$Search(File) +$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl +$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit +$ Goto Loop3 +$NextEL: +$ El = El + 1 +$ Goto Loop2 +$EndL: +$ arg=arg+1 +$ If arg .Le. 8 Then Goto Loop +$ Goto Exit +$ +$Makeit: +$ VV=F$VERIFY(0) +$ write sys$output P2 +$ 'P2 +$ VV='F$Verify(VV) +$Exit: +$ If V Then Set Verify +$ENDSUBROUTINE +$!------------------------------------------------------------------------------ +$! +$! Check command line options and set symbols accordingly +$! +$ CHECK_OPTS: +$ i = 1 +$ OPT_LOOP: +$ if i .lt. 9 +$ then +$ cparm = f$edit(p'i',"upcase") +$ if cparm .eqs. "DEBUG" +$ then +$ ccopt = ccopt + "/noopt/deb" +$ lopts = lopts + "/deb" +$ endif +$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ ccopt = ccopt + f$extract(start,len,cparm) +$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - + then s_case = true +$ endif +$ if cparm .eqs. "LINK" then linkonly = true +$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ lopts = lopts + f$extract(start,len,cparm) +$ endif +$ if f$locate("CC=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ cc_com = f$extract(start,len,cparm) + if (cc_com .nes. "DECC") .and. - + (cc_com .nes. "VAXC") .and. - + (cc_com .nes. "GNUC") +$ then +$ write sys$output "Unsupported compiler choice ''cc_com' ignored" +$ write sys$output "Use DECC, VAXC, or GNUC instead" +$ else +$ if cc_com .eqs. "DECC" then its_decc = true +$ if cc_com .eqs. "VAXC" then its_vaxc = true +$ if cc_com .eqs. "GNUC" then its_gnuc = true +$ endif +$ endif +$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) +$ then +$ start = f$locate("=",cparm) + 1 +$ len = f$length(cparm) - start +$ mmks = f$extract(start,len,cparm) +$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") +$ then +$ make = mmks +$ else +$ write sys$output "Unsupported make choice ''mmks' ignored" +$ write sys$output "Use MMK or MMS instead" +$ endif +$ endif +$ i = i + 1 +$ goto opt_loop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Look for the compiler used +$! +$CHECK_COMPILER: +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then +$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") +$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") +$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") +$ endif +$! +$! Exit if no compiler available +$! +$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) +$ then goto CC_ERR +$ else +$ if its_decc then write sys$output "CC compiler check ... Compaq C" +$ if its_vaxc then write sys$output "CC compiler check ... VAX C" +$ if its_gnuc then write sys$output "CC compiler check ... GNU C" +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! If MMS/MMK are available dump out the descrip.mms if required +$! +$CREA_MMS: +$ write sys$output "Creating descrip.mms..." +$ create descrip.mms +$ open/append out descrip.mms +$ copy sys$input: out +$ deck +# descrip.mms: MMS description file for building zlib on VMS +# written by Martin P.J. Zinser +# + +OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj, infback.obj\ + deflate.obj, trees.obj, zutil.obj, inflate.obj, \ + inftrees.obj, inffast.obj + +$ eod +$ write out "CFLAGS=", ccopt +$ write out "LOPTS=", lopts +$ copy sys$input: out +$ deck + +all : example.exe minigzip.exe libz.olb + @ write sys$output " Example applications available" + +libz.olb : libz.olb($(OBJS)) + @ write sys$output " libz available" + +example.exe : example.obj libz.olb + link $(LOPTS) example,libz.olb/lib + +minigzip.exe : minigzip.obj libz.olb + link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib + +clean : + delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* + + +# Other dependencies. +adler32.obj : adler32.c zutil.h zlib.h zconf.h +compress.obj : compress.c zlib.h zconf.h +crc32.obj : crc32.c zutil.h zlib.h zconf.h +deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h +example.obj : example.c zlib.h zconf.h +gzio.obj : gzio.c zutil.h zlib.h zconf.h +inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h +inflate.obj : inflate.c zutil.h zlib.h zconf.h +inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h +minigzip.obj : minigzip.c zlib.h zconf.h +trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h +uncompr.obj : uncompr.c zlib.h zconf.h +zutil.obj : zutil.c zutil.h zlib.h zconf.h +infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h +$ eod +$ close out +$ return +$!------------------------------------------------------------------------------ +$! +$! Read list of core library sources from makefile.in and create options +$! needed to build shareable image +$! +$CREA_OLIST: +$ open/read min makefile.in +$ open/write mod modules.opt +$ src_check = "OBJS =" +$MRLOOP: +$ read/end=mrdone min rec +$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop +$ rec = rec - src_check +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone +$MRSLOOP: +$ read/end=mrdone min rec +$ gosub extra_filnam +$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop +$MRDONE: +$ close min +$ close mod +$ return +$!------------------------------------------------------------------------------ +$! +$! Take record extracted in crea_olist and split it into single filenames +$! +$EXTRA_FILNAM: +$ myrec = f$edit(rec - "\", "trim,compress") +$ i = 0 +$FELOOP: +$ srcfil = f$element(i," ", myrec) +$ if (srcfil .nes. " ") +$ then +$ write mod f$parse(srcfil,,,"NAME"), ".obj" +$ i = i + 1 +$ goto feloop +$ endif +$ return +$!------------------------------------------------------------------------------ +$! +$! Find current Zlib version number +$! +$FIND_VERSION: +$ open/read h_in 'v_file' +$hloop: +$ read/end=hdone h_in rec +$ rec = f$edit(rec,"TRIM") +$ if (f$extract(0,1,rec) .nes. "#") then goto hloop +$ rec = f$edit(rec - "#", "TRIM") +$ if f$element(0," ",rec) .nes. "define" then goto hloop +$ if f$element(1," ",rec) .eqs. v_string +$ then +$ version = 'f$element(2," ",rec)' +$ goto hdone +$ endif +$ goto hloop +$hdone: +$ close h_in +$ return +$!------------------------------------------------------------------------------ +$! +$! Analyze Object files for OpenVMS AXP to extract Procedure and Data +$! information to build a symbol vector for a shareable image +$! All the "brains" of this logic was suggested by Hartmut Becker +$! (Hartmut.Becker@compaq.com). All the bugs were introduced by me +$! (zinser@decus.de), so if you do have problem reports please do not +$! bother Hartmut/HP, but get in touch with me +$! +$ ANAL_OBJ_AXP: Subroutine +$ V = 'F$Verify(0) +$ SAY := "WRITE_ SYS$OUTPUT" +$ +$ IF F$SEARCH("''P1'") .EQS. "" +$ THEN +$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available" +$ goto exit_aa +$ ENDIF +$ IF "''P2'" .EQS. "" +$ THEN +$ SAY "ANAL_OBJ_AXP: Error, no output file provided" +$ goto exit_aa +$ ENDIF +$ +$ open/read in 'p1 +$ create a.tmp +$ open/append atmp a.tmp +$ loop: +$ read/end=end_loop in line +$ f= f$search(line) +$ if f .eqs. "" +$ then +$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'" +$ goto loop +$ endif +$ define/user sys$output nl: +$ define/user sys$error nl: +$ anal/obj/gsd 'f /out=x.tmp +$ open/read xtmp x.tmp +$ XLOOP: +$ read/end=end_xloop xtmp xline +$ xline = f$edit(xline,"compress") +$ write atmp xline +$ goto xloop +$ END_XLOOP: +$ close xtmp +$ goto loop +$ end_loop: +$ close in +$ close atmp +$ if f$search("a.tmp") .eqs. "" - + then $ exit +$ ! all global definitions +$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp +$ ! all procedures +$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp +$ search c.tmp "symbol:"/out=d.tmp +$ define/user sys$output nl: +$ edito/edt/command=sys$input d.tmp +sub/symbol: "/symbol_vector=(/whole +sub/"/=PROCEDURE)/whole +exit +$ ! all data +$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp +$ search e.tmp "symbol:"/out=f.tmp +$ define/user sys$output nl: +$ edito/edt/command=sys$input f.tmp +sub/symbol: "/symbol_vector=(/whole +sub/"/=DATA)/whole +exit +$ sort/nodupl d.tmp,f.tmp 'p2' +$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;* +$ if f$search("x.tmp") .nes. "" - + then $ delete x.tmp;* +$! +$ EXIT_AA: +$ if V then set verify +$ endsubroutine +$!------------------------------------------------------------------------------ diff --git a/zlib/old/visual-basic.txt b/zlib/old/visual-basic.txt new file mode 100644 index 0000000..57efe58 --- /dev/null +++ b/zlib/old/visual-basic.txt @@ -0,0 +1,160 @@ +See below some functions declarations for Visual Basic. + +Frequently Asked Question: + +Q: Each time I use the compress function I get the -5 error (not enough + room in the output buffer). + +A: Make sure that the length of the compressed buffer is passed by + reference ("as any"), not by value ("as long"). Also check that + before the call of compress this length is equal to the total size of + the compressed buffer and not zero. + + +From: "Jon Caruana" +Subject: Re: How to port zlib declares to vb? +Date: Mon, 28 Oct 1996 18:33:03 -0600 + +Got the answer! (I haven't had time to check this but it's what I got, and +looks correct): + +He has the following routines working: + compress + uncompress + gzopen + gzwrite + gzread + gzclose + +Declares follow: (Quoted from Carlos Rios , in Vb4 form) + +#If Win16 Then 'Use Win16 calls. +Declare Function compress Lib "ZLIB.DLL" (ByVal compr As + String, comprLen As Any, ByVal buf As String, ByVal buflen + As Long) As Integer +Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr + As String, uncomprLen As Any, ByVal compr As String, ByVal + lcompr As Long) As Integer +Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As + String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As + Long, ByVal uncompr As String, ByVal uncomprLen As Integer) + As Integer +Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As + Long) As Integer +#Else +Declare Function compress Lib "ZLIB32.DLL" + (ByVal compr As String, comprLen As Any, ByVal buf As + String, ByVal buflen As Long) As Integer +Declare Function uncompress Lib "ZLIB32.DLL" + (ByVal uncompr As String, uncomprLen As Any, ByVal compr As + String, ByVal lcompr As Long) As Long +Declare Function gzopen Lib "ZLIB32.DLL" + (ByVal file As String, ByVal mode As String) As Long +Declare Function gzread Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzwrite Lib "ZLIB32.DLL" + (ByVal file As Long, ByVal uncompr As String, ByVal + uncomprLen As Long) As Long +Declare Function gzclose Lib "ZLIB32.DLL" + (ByVal file As Long) As Long +#End If + +-Jon Caruana +jon-net@usa.net +Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member + + +Here is another example from Michael that he +says conforms to the VB guidelines, and that solves the problem of not +knowing the uncompressed size by storing it at the end of the file: + +'Calling the functions: +'bracket meaning: [optional] {Range of possible values} +'Call subCompressFile( [, , [level of compression {1..9}]]) +'Call subUncompressFile() + +Option Explicit +Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller' +Private Const SUCCESS As Long = 0 +Private Const strFilExt As String = ".cpr" +Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long, +ByVal level As Integer) As Long +Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef +dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) +As Long + +Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal +strargCprFilPth As String, Optional ByVal intLvl As Integer = 9) + Dim strCprPth As String + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim bytaryOri() As Byte + Dim bytaryCpr() As Byte + lngOriSiz = FileLen(strargOriFilPth) + ReDim bytaryOri(lngOriSiz - 1) + Open strargOriFilPth For Binary Access Read As #1 + Get #1, , bytaryOri() + Close #1 + strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth) +'Select file path and name + strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) = +strFilExt, "", strFilExt) 'Add file extension if not exists + lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit +more space then original file size + ReDim bytaryCpr(lngCprSiz - 1) + If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) = +SUCCESS Then + lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100 + ReDim Preserve bytaryCpr(lngCprSiz - 1) + Open strCprPth For Binary Access Write As #1 + Put #1, , bytaryCpr() + Put #1, , lngOriSiz 'Add the the original size value to the end +(last 4 bytes) + Close #1 + Else + MsgBox "Compression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub + +Public Sub subUncompressFile(ByVal strargFilPth As String) + Dim bytaryCpr() As Byte + Dim bytaryOri() As Byte + Dim lngOriSiz As Long + Dim lngCprSiz As Long + Dim strOriPth As String + lngCprSiz = FileLen(strargFilPth) + ReDim bytaryCpr(lngCprSiz - 1) + Open strargFilPth For Binary Access Read As #1 + Get #1, , bytaryCpr() + Close #1 + 'Read the original file size value: + lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _ + + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _ + + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _ + + bytaryCpr(lngCprSiz - 4) + ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value + ReDim bytaryOri(lngOriSiz - 1) + If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS +Then + strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt)) + Open strOriPth For Binary Access Write As #1 + Put #1, , bytaryOri() + Close #1 + Else + MsgBox "Uncompression error" + End If + Erase bytaryCpr + Erase bytaryOri +End Sub +Public Property Get lngPercentSmaller() As Long + lngPercentSmaller = lngpvtPcnSml +End Property diff --git a/zlib/projects/README.projects b/zlib/projects/README.projects new file mode 100644 index 0000000..1c029e4 --- /dev/null +++ b/zlib/projects/README.projects @@ -0,0 +1,41 @@ +This directory contains project files for building zlib under various +Integrated Development Environments (IDE). + +If you wish to submit a new project to this directory, you should comply +to the following requirements. Otherwise (e.g. if you wish to integrate +a custom piece of code that changes the zlib interface or its behavior), +please consider submitting the project to the contrib directory. + + +Requirements +============ + +- The project must build zlib using the source files from the official + zlib source distribution, exclusively. + +- If the project produces redistributable builds (e.g. shared objects + or DLL files), these builds must be compatible to those produced by + makefiles, if such makefiles exist in the zlib distribution. + In particular, if the project produces a DLL build for the Win32 + platform, this build must comply to the officially-ammended Win32 DLL + Application Binary Interface (ABI), described in win32/DLL_FAQ.txt. + +- The project may provide additional build targets, which depend on + 3rd-party (unofficially-supported) software, present in the contrib + directory. For example, it is possible to provide an "ASM build", + besides the officially-supported build, and have ASM source files + among its dependencies. + +- If there are significant differences between the project files created + by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name + of the project directory should contain the version number of the IDE + for which the project is intended (e.g. "visualc6" for Visual C++ 6.0, + or "visualc7" for Visual C++ 7.0 and 7.1). + + +Current projects +================ + +visualc6/ by Simon-Pierre Cadieux + and Cosmin Truta + Project for Microsoft Visual C++ 6.0 diff --git a/zlib/projects/visualc6/README.txt b/zlib/projects/visualc6/README.txt new file mode 100644 index 0000000..d0296c2 --- /dev/null +++ b/zlib/projects/visualc6/README.txt @@ -0,0 +1,73 @@ +Microsoft Developer Studio Project Files, Format Version 6.00 for zlib. + +Copyright (C) 2000-2004 Simon-Pierre Cadieux. +Copyright (C) 2004 Cosmin Truta. +For conditions of distribution and use, see copyright notice in zlib.h. + + +This project builds the zlib binaries as follows: + +* Win32_DLL_Release\zlib1.dll DLL build +* Win32_DLL_Debug\zlib1d.dll DLL build (debug version) +* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code +* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version) +* Win32_LIB_Release\zlib.lib static build +* Win32_LIB_Debug\zlibd.lib static build (debug version) +* Win32_LIB_ASM_Release\zlib.lib static build using ASM code +* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version) + + +For more information regarding the DLL builds, please see the DLL FAQ +in ..\..\win32\DLL_FAQ.txt. + + +To build and test: + +1) On the main menu, select "File | Open Workspace". + Open "zlib.dsw". + +2) Select "Build | Set Active Configuration". + Choose the configuration you wish to build. + +3) Select "Build | Clean". + +4) Select "Build | Build ... (F7)". Ignore warning messages about + not being able to find certain include files (e.g. alloc.h). + +5) If you built one of the sample programs (example or minigzip), + select "Build | Execute ... (Ctrl+F5)". + + +To use: + +1) Select "Project | Settings (Alt+F7)". + Make note of the configuration names used in your project. + Usually, these names are "Win32 Release" and "Win32 Debug". + +2) In the Workspace window, select the "FileView" tab. + Right-click on the root item "Workspace '...'". + Select "Insert Project into Workspace". + Switch on the checkbox "Dependency of:", and select the name + of your project. Open "zlib.dsp". + +3) Select "Build | Configurations". + For each configuration of your project: + 3.1) Choose the zlib configuration you wish to use. + 3.2) Click on "Add". + 3.3) Set the new zlib configuration name to the name used by + the configuration from the current iteration. + +4) Select "Build | Set Active Configuration". + Choose the configuration you wish to build. + +5) Select "Build | Build ... (F7)". + +6) If you built an executable program, select + "Build | Execute ... (Ctrl+F5)". + + +Note: + +To build the ASM-enabled code, you need Microsoft Assembler +(ML.EXE). You can get it by downloading and installing the +latest Processor Pack for Visual C++ 6.0. diff --git a/zlib/projects/visualc6/example.dsp b/zlib/projects/visualc6/example.dsp new file mode 100644 index 0000000..e072a37 --- /dev/null +++ b/zlib/projects/visualc6/example.dsp @@ -0,0 +1,278 @@ +# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=example - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "example.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "example - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "example___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "example___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "example - Win32 DLL Release" +# Name "example - Win32 DLL Debug" +# Name "example - Win32 DLL ASM Release" +# Name "example - Win32 DLL ASM Debug" +# Name "example - Win32 LIB Release" +# Name "example - Win32 LIB Debug" +# Name "example - Win32 LIB ASM Release" +# Name "example - Win32 LIB ASM Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\example.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# End Group +# End Target +# End Project diff --git a/zlib/projects/visualc6/minigzip.dsp b/zlib/projects/visualc6/minigzip.dsp new file mode 100644 index 0000000..f32024e --- /dev/null +++ b/zlib/projects/visualc6/minigzip.dsp @@ -0,0 +1,278 @@ +# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=minigzip - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "minigzip.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application") +!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "minigzip - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "minigzip - Win32 DLL Release" +# Name "minigzip - Win32 DLL Debug" +# Name "minigzip - Win32 DLL ASM Release" +# Name "minigzip - Win32 DLL ASM Debug" +# Name "minigzip - Win32 LIB Release" +# Name "minigzip - Win32 LIB Debug" +# Name "minigzip - Win32 LIB ASM Release" +# Name "minigzip - Win32 LIB ASM Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\minigzip.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# End Group +# End Target +# End Project diff --git a/zlib/projects/visualc6/zlib.dsp b/zlib/projects/visualc6/zlib.dsp new file mode 100644 index 0000000..0fe0604 --- /dev/null +++ b/zlib/projects/visualc6/zlib.dsp @@ -0,0 +1,609 @@ +# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=zlib - Win32 LIB Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library") +!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_DLL_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_Release" +# PROP Intermediate_Dir "Win32_DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_DLL_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_Debug" +# PROP Intermediate_Dir "Win32_DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_DLL_ASM_Release" +# PROP Intermediate_Dir "Win32_DLL_ASM_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_DLL_ASM_Debug" +# PROP Intermediate_Dir "Win32_DLL_ASM_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +MTL=midl.exe +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_LIB_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_Release" +# PROP Intermediate_Dir "Win32_LIB_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_LIB_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_Debug" +# PROP Intermediate_Dir "Win32_LIB_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib" + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Win32_LIB_ASM_Release" +# PROP Intermediate_Dir "Win32_LIB_ASM_Release" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug" +# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Win32_LIB_ASM_Debug" +# PROP Intermediate_Dir "Win32_LIB_ASM_Debug" +# PROP Target_Dir "" +CPP=cl.exe +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c +# SUBTRACT BASE CPP /YX /Yc /Yu +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c +# SUBTRACT CPP /YX /Yc /Yu +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib" + +!ENDIF + +# Begin Target + +# Name "zlib - Win32 DLL Release" +# Name "zlib - Win32 DLL Debug" +# Name "zlib - Win32 DLL ASM Release" +# Name "zlib - Win32 DLL ASM Debug" +# Name "zlib - Win32 LIB Release" +# Name "zlib - Win32 LIB Debug" +# Name "zlib - Win32 LIB ASM Release" +# Name "zlib - Win32 LIB ASM Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\adler32.c +# End Source File +# Begin Source File + +SOURCE=..\..\compress.c +# End Source File +# Begin Source File + +SOURCE=..\..\crc32.c +# End Source File +# Begin Source File + +SOURCE=..\..\deflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\gzio.c +# End Source File +# Begin Source File + +SOURCE=..\..\infback.c +# End Source File +# Begin Source File + +SOURCE=..\..\inffast.c +# End Source File +# Begin Source File + +SOURCE=..\..\inflate.c +# End Source File +# Begin Source File + +SOURCE=..\..\inftrees.c +# End Source File +# Begin Source File + +SOURCE=..\..\trees.c +# End Source File +# Begin Source File + +SOURCE=..\..\uncompr.c +# End Source File +# Begin Source File + +SOURCE=..\..\win32\zlib.def + +!IF "$(CFG)" == "zlib - Win32 DLL Release" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\zutil.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=..\..\crc32.h +# End Source File +# Begin Source File + +SOURCE=..\..\deflate.h +# End Source File +# Begin Source File + +SOURCE=..\..\inffast.h +# End Source File +# Begin Source File + +SOURCE=..\..\inffixed.h +# End Source File +# Begin Source File + +SOURCE=..\..\inflate.h +# End Source File +# Begin Source File + +SOURCE=..\..\inftrees.h +# End Source File +# Begin Source File + +SOURCE=..\..\trees.h +# End Source File +# Begin Source File + +SOURCE=..\..\zconf.h +# End Source File +# Begin Source File + +SOURCE=..\..\zlib.h +# End Source File +# Begin Source File + +SOURCE=..\..\zutil.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=..\..\win32\zlib1.rc +# End Source File +# End Group +# Begin Group "Assembler Files (Unsupported)" + +# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx" +# Begin Source File + +SOURCE=..\..\contrib\masmx86\gvmat32.asm + +!IF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Release +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Debug +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Release +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Debug +InputPath=..\..\contrib\masmx86\gvmat32.asm +InputName=gvmat32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\contrib\masmx86\gvmat32c.c + +!IF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# ADD CPP /I "..\.." + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# ADD CPP /I "..\.." + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=..\..\contrib\masmx86\inffas32.asm + +!IF "$(CFG)" == "zlib - Win32 DLL Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Release +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_DLL_ASM_Debug +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Release +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug" + +# Begin Custom Build - Assembling... +IntDir=.\Win32_LIB_ASM_Debug +InputPath=..\..\contrib\masmx86\inffas32.asm +InputName=inffas32 + +"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + ml.exe /nologo /c /coff /Cx /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)" + +# End Custom Build + +!ENDIF + +# End Source File +# End Group +# Begin Source File + +SOURCE=.\README.txt +# End Source File +# End Target +# End Project diff --git a/zlib/projects/visualc6/zlib.dsw b/zlib/projects/visualc6/zlib.dsw new file mode 100644 index 0000000..3a771fc --- /dev/null +++ b/zlib/projects/visualc6/zlib.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "example"=.\example.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "minigzip"=.\minigzip.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name zlib + End Project Dependency +}}} + +############################################################################### + +Project: "zlib"=.\zlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/zlib/win32/VisualC.txt b/zlib/win32/VisualC.txt new file mode 100644 index 0000000..579a5fc --- /dev/null +++ b/zlib/win32/VisualC.txt @@ -0,0 +1,3 @@ + +To build zlib using the Microsoft Visual C++ environment, +use the appropriate project from the projects/ directory. -- 2.7.4