Commit 3ec980b1 by Tom Tromey

This commit was generated by cvs2svn to compensate for changes in r104181,

which included commits to RCS files with non-trunk default branches.

From-SVN: r104182
parent 303ae446
...@@ -118,6 +118,6 @@ ...@@ -118,6 +118,6 @@
&MODLIB/INFTREES &MODLIB/TREES + &MODLIB/INFTREES &MODLIB/TREES +
&MODLIB/UNCOMPR &MODLIB/ZUTIL) + &MODLIB/UNCOMPR &MODLIB/ZUTIL) +
SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) + SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC) +
TEXT('ZLIB 1.2.1') TGTRLS(V4R4M0) TEXT('ZLIB 1.2.3') TGTRLS(V4R4M0)
ENDPGM ENDPGM
ZLIB version 1.2.1 for AS400 installation instructions ZLIB version 1.2.3 for AS400 installation instructions
I) From an AS400 *SAVF file: I) From an AS400 *SAVF file:
......
* ZLIB.INC - Interface to the general purpose compression library * ZLIB.INC - Interface to the general purpose compression library
* *
* ILE RPG400 version by Patrick Monnerat, DATASPHERE. * ILE RPG400 version by Patrick Monnerat, DATASPHERE.
* Version 1.2.1 * Version 1.2.3
* *
* *
* WARNING: * WARNING:
...@@ -20,8 +20,12 @@ ...@@ -20,8 +20,12 @@
* Constants * Constants
************************************************************************** **************************************************************************
* *
D ZLIB_VERSION C '1.2.1' Header's version * Versioning information.
D ZLIB_VERNUM C X'1210' *
D ZLIB_VERSION C '1.2.3'
D ZLIB_VERNUM C X'1230'
*
* Other equates.
* *
D Z_NO_FLUSH C 0 D Z_NO_FLUSH C 0
D Z_SYNC_FLUSH C 2 D Z_SYNC_FLUSH C 2
......
...@@ -5,10 +5,10 @@ ...@@ -5,10 +5,10 @@
-- -- -- --
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- Continuous test for ZLib multithreading. If the test is fail -- Continuous test for ZLib multithreading. If the test would fail
-- Wou should provide thread safe allocation routines for the Z_Stream. -- we should provide thread safe allocation routines for the Z_Stream.
-- --
-- $Id: mtest.adb,v 1.2 2003/08/12 12:11:05 vagul Exp $ -- $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
with ZLib; with ZLib;
with Ada.Streams; with Ada.Streams;
...@@ -148,6 +148,9 @@ procedure MTest is ...@@ -148,6 +148,9 @@ procedure MTest is
pragma Unreferenced (Test); pragma Unreferenced (Test);
Dummy : Character;
begin begin
null; Ada.Text_IO.Get_Immediate (Dummy);
Stop := True;
end MTest; end MTest;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: read.adb,v 1.7 2003/08/12 12:12:35 vagul Exp $ -- $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
-- Test/demo program for the generic read interface. -- Test/demo program for the generic read interface.
...@@ -68,7 +68,11 @@ procedure Read is ...@@ -68,7 +68,11 @@ procedure Read is
-- ZLib.Read -- ZLib.Read
-- reading data from the File_In. -- reading data from the File_In.
procedure Read is new ZLib.Read (Read, Read_Buffer, Read_First, Read_Last); procedure Read is new ZLib.Read
(Read,
Read_Buffer,
Rest_First => Read_First,
Rest_Last => Read_Last);
---------- ----------
-- Read -- -- Read --
...@@ -103,6 +107,7 @@ procedure Read is ...@@ -103,6 +107,7 @@ procedure Read is
Pack_Size := 0; Pack_Size := 0;
Offset := 1; Offset := 1;
Read_First := Read_Buffer'Last + 1; Read_First := Read_Buffer'Last + 1;
Read_Last := Read_Buffer'Last;
end Reset; end Reset;
begin begin
......
ZLib for Ada thick binding (ZLib.Ada)
ZLib for Ada thick binding (ZLib.Ada) Release 1.3
Release 1.2
ZLib.Ada is a thick binding interface to the popular ZLib data ZLib.Ada is a thick binding interface to the popular ZLib data
compression library, available at http://www.gzip.org/zlib/. compression library, available at http://www.gzip.org/zlib/.
It provides Ada-style access to the ZLib C library. It provides Ada-style access to the ZLib C library.
Here are the main changes since ZLib.Ada 1.1: Here are the main changes since ZLib.Ada 1.2:
- Attension: ZLib.Read generic routine have a initialization requirement
for Read_Last parameter now. It is a bit incompartible with previous version,
but extends functionality, we could use new parameters Allow_Read_Some and
Flush now.
- Added Is_Open routines to ZLib and ZLib.Streams packages.
- The default header type has a name "Default" now. Auto is used only for - Add pragma Assert to check Stream_Element is 8 bit.
automatic GZip/ZLib header detection.
- Added test for multitasking mtest.adb. - Fix extraction to buffer with exact known decompressed size. Error reported by
Steve Sangwine.
- Added GNAT project file zlib.gpr. - Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
computers. Patch provided by Pascal Obry.
- Add Status_Error exception definition.
How to build ZLib.Ada under GNAT - Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
How to build ZLib.Ada under GNAT
You should have the ZLib library already build on your computer, before You should have the ZLib library already build on your computer, before
building ZLib.Ada. Make the directory of ZLib.Ada sources current and building ZLib.Ada. Make the directory of ZLib.Ada sources current and
...@@ -30,7 +41,7 @@ Or use the GNAT project file build for GNAT 3.15 or later: ...@@ -30,7 +41,7 @@ Or use the GNAT project file build for GNAT 3.15 or later:
gnatmake -Pzlib.gpr -L<directory where libz.a is> gnatmake -Pzlib.gpr -L<directory where libz.a is>
How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2 How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
1. Make a project with all *.ads and *.adb files from the distribution. 1. Make a project with all *.ads and *.adb files from the distribution.
2. Build the libz.a library from the ZLib C sources. 2. Build the libz.a library from the ZLib C sources.
...@@ -40,7 +51,7 @@ Or use the GNAT project file build for GNAT 3.15 or later: ...@@ -40,7 +51,7 @@ Or use the GNAT project file build for GNAT 3.15 or later:
6. Build the executable using test.adb as a main procedure. 6. Build the executable using test.adb as a main procedure.
How to use ZLib.Ada How to use ZLib.Ada
The source files test.adb and read.adb are small demo programs that show The source files test.adb and read.adb are small demo programs that show
the main functionality of ZLib.Ada. the main functionality of ZLib.Ada.
...@@ -50,3 +61,5 @@ The routines from the package specifications are commented. ...@@ -50,3 +61,5 @@ The routines from the package specifications are commented.
Homepage: http://zlib-ada.sourceforge.net/ Homepage: http://zlib-ada.sourceforge.net/
Author: Dmitriy Anisimkov <anisimkov@yahoo.com> Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-streams.adb,v 1.9 2003/08/12 13:15:31 vagul Exp $ -- $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
with Ada.Unchecked_Deallocation; with Ada.Unchecked_Deallocation;
...@@ -90,6 +90,7 @@ package body ZLib.Streams is ...@@ -90,6 +90,7 @@ package body ZLib.Streams is
Stream.Buffer := new Buffer_Subtype; Stream.Buffer := new Buffer_Subtype;
Stream.Rest_First := Stream.Buffer'Last + 1; Stream.Rest_First := Stream.Buffer'Last + 1;
Stream.Rest_Last := Stream.Buffer'Last;
end if; end if;
end Create; end Create;
...@@ -113,6 +114,15 @@ package body ZLib.Streams is ...@@ -113,6 +114,15 @@ package body ZLib.Streams is
end loop; end loop;
end Flush; end Flush;
-------------
-- Is_Open --
-------------
function Is_Open (Stream : Stream_Type) return Boolean is
begin
return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
end Is_Open;
---------- ----------
-- Read -- -- Read --
---------- ----------
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-streams.ads,v 1.11 2003/08/12 13:15:31 vagul Exp $ -- $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
package ZLib.Streams is package ZLib.Streams is
...@@ -77,6 +77,8 @@ package ZLib.Streams is ...@@ -77,6 +77,8 @@ package ZLib.Streams is
-- !!! When the Need_Header is False ZLib-Ada is using undocumented -- !!! When the Need_Header is False ZLib-Ada is using undocumented
-- ZLib 1.1.4 functionality to do not create/wait for ZLib headers. -- ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
function Is_Open (Stream : Stream_Type) return Boolean;
procedure Close (Stream : in out Stream_Type); procedure Close (Stream : in out Stream_Type);
private private
......
...@@ -6,12 +6,11 @@ ...@@ -6,12 +6,11 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-thin.adb,v 1.6 2003/01/21 15:26:37 vagul Exp $ -- $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
package body ZLib.Thin is package body ZLib.Thin is
ZLIB_VERSION : constant Chars_Ptr := ZLIB_VERSION : constant Chars_Ptr := zlibVersion;
Interfaces.C.Strings.New_String ("1.1.4");
Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit; Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
...@@ -38,14 +37,6 @@ package body ZLib.Thin is ...@@ -38,14 +37,6 @@ package body ZLib.Thin is
------------------ ------------------
function Deflate_Init function Deflate_Init
(strm : in Z_Streamp;
level : in Int := Z_DEFAULT_COMPRESSION)
return Int is
begin
return deflateInit (strm, level, ZLIB_VERSION, Z_Stream_Size);
end Deflate_Init;
function Deflate_Init
(strm : Z_Streamp; (strm : Z_Streamp;
level : Int; level : Int;
method : Int; method : Int;
...@@ -69,16 +60,15 @@ package body ZLib.Thin is ...@@ -69,16 +60,15 @@ package body ZLib.Thin is
-- Inflate_Init -- -- Inflate_Init --
------------------ ------------------
function Inflate_Init (strm : Z_Streamp) return Int is
begin
return inflateInit (strm, ZLIB_VERSION, Z_Stream_Size);
end Inflate_Init;
function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
begin begin
return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size); return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
end Inflate_Init; end Inflate_Init;
------------------------
-- Last_Error_Message --
------------------------
function Last_Error_Message (Strm : in Z_Stream) return String is function Last_Error_Message (Strm : in Z_Stream) return String is
use Interfaces.C.Strings; use Interfaces.C.Strings;
begin begin
...@@ -89,54 +79,28 @@ package body ZLib.Thin is ...@@ -89,54 +79,28 @@ package body ZLib.Thin is
end if; end if;
end Last_Error_Message; end Last_Error_Message;
-------------
-- Need_In --
-------------
function Need_In (strm : Z_Stream) return Boolean is
begin
return strm.Avail_In = 0;
end Need_In;
--------------
-- Need_Out --
--------------
function Need_Out (strm : Z_Stream) return Boolean is
begin
return strm.Avail_Out = 0;
end Need_Out;
------------ ------------
-- Set_In -- -- Set_In --
------------ ------------
procedure Set_In procedure Set_In
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Byte_Access; Buffer : in Voidp;
Size : in UInt) is Size : in UInt) is
begin begin
Strm.Next_In := Buffer; Strm.Next_In := Buffer;
Strm.Avail_In := Size; Strm.Avail_In := Size;
end Set_In; end Set_In;
procedure Set_In
(Strm : in out Z_Stream;
Buffer : in Voidp;
Size : in UInt) is
begin
Set_In (Strm, Bytes.To_Pointer (Buffer), Size);
end Set_In;
------------------ ------------------
-- Set_Mem_Func -- -- Set_Mem_Func --
------------------ ------------------
procedure Set_Mem_Func procedure Set_Mem_Func
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Opaque : in Voidp; Opaque : in Voidp;
Alloc : in alloc_func; Alloc : in alloc_func;
Free : in free_func) is Free : in free_func) is
begin begin
Strm.opaque := Opaque; Strm.opaque := Opaque;
Strm.zalloc := Alloc; Strm.zalloc := Alloc;
...@@ -149,21 +113,13 @@ package body ZLib.Thin is ...@@ -149,21 +113,13 @@ package body ZLib.Thin is
procedure Set_Out procedure Set_Out
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Byte_Access; Buffer : in Voidp;
Size : in UInt) is Size : in UInt) is
begin begin
Strm.Next_Out := Buffer; Strm.Next_Out := Buffer;
Strm.Avail_Out := Size; Strm.Avail_Out := Size;
end Set_Out; end Set_Out;
procedure Set_Out
(Strm : in out Z_Stream;
Buffer : in Voidp;
Size : in UInt) is
begin
Set_Out (Strm, Bytes.To_Pointer (Buffer), Size);
end Set_Out;
-------------- --------------
-- Total_In -- -- Total_In --
-------------- --------------
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib-thin.ads,v 1.8 2003/08/12 13:16:51 vagul Exp $ -- $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
with Interfaces.C.Strings; with Interfaces.C.Strings;
with System.Address_To_Access_Conversions;
with System;
private package ZLib.Thin is private package ZLib.Thin is
...@@ -36,18 +37,18 @@ private package ZLib.Thin is ...@@ -36,18 +37,18 @@ private package ZLib.Thin is
-- zconf.h:216 -- zconf.h:216
type Int is new Interfaces.C.int; type Int is new Interfaces.C.int;
type ULong is new Interfaces.C.unsigned; -- 32 bits or more type ULong is new Interfaces.C.unsigned_long; -- 32 bits or more
-- zconf.h:217 -- zconf.h:217
subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr; subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
type ULong_Access is access ULong; type ULong_Access is access ULong;
type Int_Access is access Int; type Int_Access is access Int;
subtype Voidp is System.Address; -- zconf.h:232
package Bytes is new System.Address_To_Access_Conversions (Byte); subtype Voidp is System.Address; -- zconf.h:232
subtype Byte_Access is Bytes.Object_Pointer; subtype Byte_Access is Voidp;
Nul : constant Voidp := System.Null_Address;
-- end from zconf -- end from zconf
Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125 Z_NO_FLUSH : constant := 8#0000#; -- zlib.h:125
...@@ -251,12 +252,6 @@ private package ZLib.Thin is ...@@ -251,12 +252,6 @@ private package ZLib.Thin is
stream_size : Int) stream_size : Int)
return Int; return Int;
function Deflate_Init
(strm : in Z_Streamp;
level : in Int := Z_DEFAULT_COMPRESSION)
return Int;
pragma Inline (Deflate_Init);
function deflateInit2 function deflateInit2
(strm : Z_Streamp; (strm : Z_Streamp;
level : Int; level : Int;
...@@ -284,9 +279,6 @@ private package ZLib.Thin is ...@@ -284,9 +279,6 @@ private package ZLib.Thin is
stream_size : Int) stream_size : Int)
return Int; return Int;
function Inflate_Init (strm : Z_Streamp) return Int;
pragma Inline (Inflate_Init);
function inflateInit2 function inflateInit2
(strm : in Z_Streamp; (strm : in Z_Streamp;
windowBits : in Int; windowBits : in Int;
...@@ -318,20 +310,6 @@ private package ZLib.Thin is ...@@ -318,20 +310,6 @@ private package ZLib.Thin is
-- has dropped to zero. The application must initialize zalloc, zfree and -- has dropped to zero. The application must initialize zalloc, zfree and
-- opaque before calling the init function. -- opaque before calling the init function.
function Need_In (strm : in Z_Stream) return Boolean;
-- return true when we do not need to setup Next_In and Avail_In fields.
pragma Inline (Need_In);
function Need_Out (strm : in Z_Stream) return Boolean;
-- return true when we do not need to setup Next_Out and Avail_Out field.
pragma Inline (Need_Out);
procedure Set_In
(Strm : in out Z_Stream;
Buffer : in Byte_Access;
Size : in UInt);
pragma Inline (Set_In);
procedure Set_In procedure Set_In
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Voidp; Buffer : in Voidp;
...@@ -340,12 +318,6 @@ private package ZLib.Thin is ...@@ -340,12 +318,6 @@ private package ZLib.Thin is
procedure Set_Out procedure Set_Out
(Strm : in out Z_Stream; (Strm : in out Z_Stream;
Buffer : in Byte_Access;
Size : in UInt);
pragma Inline (Set_Out);
procedure Set_Out
(Strm : in out Z_Stream;
Buffer : in Voidp; Buffer : in Voidp;
Size : in UInt); Size : in UInt);
pragma Inline (Set_Out); pragma Inline (Set_Out);
...@@ -388,19 +360,13 @@ private package ZLib.Thin is ...@@ -388,19 +360,13 @@ private package ZLib.Thin is
function zlibCompileFlags return ULong; function zlibCompileFlags return ULong;
function deflatePrime
(strm : Z_Streamp;
bits : Int;
value : Int)
return Int;
private private
type Z_Stream is record -- zlib.h:68 type Z_Stream is record -- zlib.h:68
Next_In : Byte_Access; -- next input byte Next_In : Voidp := Nul; -- next input byte
Avail_In : UInt := 0; -- number of bytes available at next_in Avail_In : UInt := 0; -- number of bytes available at next_in
Total_In : ULong := 0; -- total nb of input bytes read so far Total_In : ULong := 0; -- total nb of input bytes read so far
Next_Out : Byte_Access; -- next output byte should be put there Next_Out : Voidp := Nul; -- next output byte should be put there
Avail_Out : UInt := 0; -- remaining free space at next_out Avail_Out : UInt := 0; -- remaining free space at next_out
Total_Out : ULong := 0; -- total nb of bytes output so far Total_Out : ULong := 0; -- total nb of bytes output so far
msg : Chars_Ptr; -- last error message, NULL if no error msg : Chars_Ptr; -- last error message, NULL if no error
...@@ -460,14 +426,13 @@ private ...@@ -460,14 +426,13 @@ private
pragma Import (C, inflateSyncPoint, "inflateSyncPoint"); pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
pragma Import (C, get_crc_table, "get_crc_table"); pragma Import (C, get_crc_table, "get_crc_table");
-- added in zlib 1.2.1: -- since zlib 1.2.0:
pragma Import (C, inflateCopy, "inflateCopy"); pragma Import (C, inflateCopy, "inflateCopy");
pragma Import (C, compressBound, "compressBound"); pragma Import (C, compressBound, "compressBound");
pragma Import (C, deflateBound, "deflateBound"); pragma Import (C, deflateBound, "deflateBound");
pragma Import (C, gzungetc, "gzungetc"); pragma Import (C, gzungetc, "gzungetc");
pragma Import (C, zlibCompileFlags, "zlibCompileFlags"); pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
pragma Import (C, deflatePrime, "deflatePrime");
pragma Import (C, inflateBackInit, "inflateBackInit_"); pragma Import (C, inflateBackInit, "inflateBackInit_");
......
---------------------------------------------------------------- ----------------------------------------------------------------
-- ZLib for Ada thick binding. -- -- ZLib for Ada thick binding. --
-- -- -- --
-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
-- -- -- --
-- Open source license information is in the zlib.ads file. -- -- Open source license information is in the zlib.ads file. --
---------------------------------------------------------------- ----------------------------------------------------------------
-- $Id: zlib.adb,v 1.19 2003/07/13 16:02:19 vagul Exp $ -- $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
with Ada.Exceptions; with Ada.Exceptions;
with Ada.Unchecked_Conversion; with Ada.Unchecked_Conversion;
...@@ -34,7 +34,7 @@ package body ZLib is ...@@ -34,7 +34,7 @@ package body ZLib is
VERSION_ERROR); VERSION_ERROR);
type Flate_Step_Function is access type Flate_Step_Function is access
function (Strm : Thin.Z_Streamp; flush : Thin.Int) return Thin.Int; function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
pragma Convention (C, Flate_Step_Function); pragma Convention (C, Flate_Step_Function);
type Flate_End_Function is access type Flate_End_Function is access
...@@ -82,13 +82,13 @@ package body ZLib is ...@@ -82,13 +82,13 @@ package body ZLib is
Flush_Finish : constant array (Boolean) of Flush_Mode Flush_Finish : constant array (Boolean) of Flush_Mode
:= (True => Finish, False => No_Flush); := (True => Finish, False => No_Flush);
procedure Raise_Error (Stream : Z_Stream); procedure Raise_Error (Stream : in Z_Stream);
pragma Inline (Raise_Error); pragma Inline (Raise_Error);
procedure Raise_Error (Message : String); procedure Raise_Error (Message : in String);
pragma Inline (Raise_Error); pragma Inline (Raise_Error);
procedure Check_Error (Stream : Z_Stream; Code : Thin.Int); procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
procedure Free is new Ada.Unchecked_Deallocation procedure Free is new Ada.Unchecked_Deallocation
(Z_Stream, Z_Stream_Access); (Z_Stream, Z_Stream_Access);
...@@ -118,7 +118,7 @@ package body ZLib is ...@@ -118,7 +118,7 @@ package body ZLib is
-- Check_Error -- -- Check_Error --
----------------- -----------------
procedure Check_Error (Stream : Z_Stream; Code : Thin.Int) is procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
use type Thin.Int; use type Thin.Int;
begin begin
if Code /= Thin.Z_OK then if Code /= Thin.Z_OK then
...@@ -138,10 +138,11 @@ package body ZLib is ...@@ -138,10 +138,11 @@ package body ZLib is
is is
Code : Thin.Int; Code : Thin.Int;
begin begin
Code := Flate (Filter.Compression).Done if not Ignore_Error and then not Is_Open (Filter) then
(To_Thin_Access (Filter.Strm)); raise Status_Error;
end if;
Filter.Opened := False; Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
if Ignore_Error or else Code = Thin.Z_OK then if Ignore_Error or else Code = Thin.Z_OK then
Free (Filter.Strm); Free (Filter.Strm);
...@@ -154,7 +155,7 @@ package body ZLib is ...@@ -154,7 +155,7 @@ package body ZLib is
Ada.Exceptions.Raise_Exception Ada.Exceptions.Raise_Exception
(ZLib_Error'Identity, (ZLib_Error'Identity,
Return_Code_Enum'Image (Return_Code (Code)) Return_Code_Enum'Image (Return_Code (Code))
& ": " & Error_Message); & ": " & Error_Message);
end; end;
end if; end if;
end Close; end Close;
...@@ -170,10 +171,9 @@ package body ZLib is ...@@ -170,10 +171,9 @@ package body ZLib is
is is
use Thin; use Thin;
begin begin
return Unsigned_32 (crc32 return Unsigned_32 (crc32 (ULong (CRC),
(ULong (CRC), Data'Address,
Bytes.To_Pointer (Data'Address), Data'Length));
Data'Length));
end CRC32; end CRC32;
procedure CRC32 procedure CRC32
...@@ -192,13 +192,17 @@ package body ZLib is ...@@ -192,13 +192,17 @@ package body ZLib is
Level : in Compression_Level := Default_Compression; Level : in Compression_Level := Default_Compression;
Strategy : in Strategy_Type := Default_Strategy; Strategy : in Strategy_Type := Default_Strategy;
Method : in Compression_Method := Deflated; Method : in Compression_Method := Deflated;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Memory_Level : in Memory_Level_Type := 8; Memory_Level : in Memory_Level_Type := Default_Memory_Level;
Header : in Header_Type := Default) Header : in Header_Type := Default)
is is
use type Thin.Int; use type Thin.Int;
Win_Bits : Thin.Int := Thin.Int (Window_Bits); Win_Bits : Thin.Int := Thin.Int (Window_Bits);
begin begin
if Is_Open (Filter) then
raise Status_Error;
end if;
-- We allow ZLib to make header only in case of default header type. -- We allow ZLib to make header only in case of default header type.
-- Otherwise we would either do header by ourselfs, or do not do -- Otherwise we would either do header by ourselfs, or do not do
-- header at all. -- header at all.
...@@ -216,10 +220,9 @@ package body ZLib is ...@@ -216,10 +220,9 @@ package body ZLib is
Filter.Offset := Simple_GZip_Header'Last + 1; Filter.Offset := Simple_GZip_Header'Last + 1;
end if; end if;
Filter.Strm := new Z_Stream; Filter.Strm := new Z_Stream;
Filter.Compression := True; Filter.Compression := True;
Filter.Stream_End := False; Filter.Stream_End := False;
Filter.Opened := True;
Filter.Header := Header; Filter.Header := Header;
if Thin.Deflate_Init if Thin.Deflate_Init
...@@ -255,18 +258,18 @@ package body ZLib is ...@@ -255,18 +258,18 @@ package body ZLib is
----------------------- -----------------------
procedure Generic_Translate procedure Generic_Translate
(Filter : in out ZLib.Filter_Type; (Filter : in out ZLib.Filter_Type;
In_Buffer_Size : Integer := Default_Buffer_Size; In_Buffer_Size : in Integer := Default_Buffer_Size;
Out_Buffer_Size : Integer := Default_Buffer_Size) Out_Buffer_Size : in Integer := Default_Buffer_Size)
is is
In_Buffer : Stream_Element_Array In_Buffer : Stream_Element_Array
(1 .. Stream_Element_Offset (In_Buffer_Size)); (1 .. Stream_Element_Offset (In_Buffer_Size));
Out_Buffer : Stream_Element_Array Out_Buffer : Stream_Element_Array
(1 .. Stream_Element_Offset (Out_Buffer_Size)); (1 .. Stream_Element_Offset (Out_Buffer_Size));
Last : Stream_Element_Offset; Last : Stream_Element_Offset;
In_Last : Stream_Element_Offset; In_Last : Stream_Element_Offset;
In_First : Stream_Element_Offset; In_First : Stream_Element_Offset;
Out_Last : Stream_Element_Offset; Out_Last : Stream_Element_Offset;
begin begin
Main : loop Main : loop
Data_In (In_Buffer, Last); Data_In (In_Buffer, Last);
...@@ -275,18 +278,21 @@ package body ZLib is ...@@ -275,18 +278,21 @@ package body ZLib is
loop loop
Translate Translate
(Filter, (Filter => Filter,
In_Buffer (In_First .. Last), In_Data => In_Buffer (In_First .. Last),
In_Last, In_Last => In_Last,
Out_Buffer, Out_Data => Out_Buffer,
Out_Last, Out_Last => Out_Last,
Flush_Finish (Last < In_Buffer'First)); Flush => Flush_Finish (Last < In_Buffer'First));
Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last)); if Out_Buffer'First <= Out_Last then
Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
end if;
exit Main when Stream_End (Filter); exit Main when Stream_End (Filter);
-- The end of in buffer. -- The end of in buffer.
exit when In_Last = Last; exit when In_Last = Last;
In_First := In_Last + 1; In_First := In_Last + 1;
...@@ -301,7 +307,7 @@ package body ZLib is ...@@ -301,7 +307,7 @@ package body ZLib is
procedure Inflate_Init procedure Inflate_Init
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Header : in Header_Type := Default) Header : in Header_Type := Default)
is is
use type Thin.Int; use type Thin.Int;
...@@ -320,6 +326,10 @@ package body ZLib is ...@@ -320,6 +326,10 @@ package body ZLib is
end Check_Version; end Check_Version;
begin begin
if Is_Open (Filter) then
raise Status_Error;
end if;
case Header is case Header is
when None => when None =>
Check_Version; Check_Version;
...@@ -344,10 +354,9 @@ package body ZLib is ...@@ -344,10 +354,9 @@ package body ZLib is
when Default => null; when Default => null;
end case; end case;
Filter.Strm := new Z_Stream; Filter.Strm := new Z_Stream;
Filter.Compression := False; Filter.Compression := False;
Filter.Stream_End := False; Filter.Stream_End := False;
Filter.Opened := True;
Filter.Header := Header; Filter.Header := Header;
if Thin.Inflate_Init if Thin.Inflate_Init
...@@ -357,16 +366,25 @@ package body ZLib is ...@@ -357,16 +366,25 @@ package body ZLib is
end if; end if;
end Inflate_Init; end Inflate_Init;
-------------
-- Is_Open --
-------------
function Is_Open (Filter : in Filter_Type) return Boolean is
begin
return Filter.Strm /= null;
end Is_Open;
----------------- -----------------
-- Raise_Error -- -- Raise_Error --
----------------- -----------------
procedure Raise_Error (Message : String) is procedure Raise_Error (Message : in String) is
begin begin
Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message); Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
end Raise_Error; end Raise_Error;
procedure Raise_Error (Stream : Z_Stream) is procedure Raise_Error (Stream : in Z_Stream) is
begin begin
Raise_Error (Last_Error_Message (Stream)); Raise_Error (Last_Error_Message (Stream));
end Raise_Error; end Raise_Error;
...@@ -378,21 +396,29 @@ package body ZLib is ...@@ -378,21 +396,29 @@ package body ZLib is
procedure Read procedure Read
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : out Ada.Streams.Stream_Element_Array; Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset) Last : out Ada.Streams.Stream_Element_Offset;
Flush : in Flush_Mode := No_Flush)
is is
In_Last : Stream_Element_Offset; In_Last : Stream_Element_Offset;
Item_First : Ada.Streams.Stream_Element_Offset := Item'First; Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
V_Flush : Flush_Mode := Flush;
begin begin
pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1); pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
loop loop
if Rest_First > Buffer'Last then if Rest_Last = Buffer'First - 1 then
V_Flush := Finish;
elsif Rest_First > Rest_Last then
Read (Buffer, Rest_Last); Read (Buffer, Rest_Last);
Rest_First := Buffer'First; Rest_First := Buffer'First;
end if;
pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last); if Rest_Last < Buffer'First then
V_Flush := Finish;
end if;
end if;
Translate Translate
(Filter => Filter, (Filter => Filter,
...@@ -400,11 +426,13 @@ package body ZLib is ...@@ -400,11 +426,13 @@ package body ZLib is
In_Last => In_Last, In_Last => In_Last,
Out_Data => Item (Item_First .. Item'Last), Out_Data => Item (Item_First .. Item'Last),
Out_Last => Last, Out_Last => Last,
Flush => Flush_Finish (Rest_Last < Rest_First)); Flush => V_Flush);
Rest_First := In_Last + 1; Rest_First := In_Last + 1;
exit when Last = Item'Last or else Stream_End (Filter); exit when Stream_End (Filter)
or else Last = Item'Last
or else (Last >= Item'First and then Allow_Read_Some);
Item_First := Last + 1; Item_First := Last + 1;
end loop; end loop;
...@@ -489,11 +517,11 @@ package body ZLib is ...@@ -489,11 +517,11 @@ package body ZLib is
Code : Thin.Int; Code : Thin.Int;
begin begin
if Filter.Opened = False then if not Is_Open (Filter) then
raise ZLib_Error; raise Status_Error;
end if; end if;
if Out_Data'Length = 0 then if Out_Data'Length = 0 and then In_Data'Length = 0 then
raise Constraint_Error; raise Constraint_Error;
end if; end if;
...@@ -514,7 +542,6 @@ package body ZLib is ...@@ -514,7 +542,6 @@ package body ZLib is
- Stream_Element_Offset (Avail_In (Filter.Strm.all)); - Stream_Element_Offset (Avail_In (Filter.Strm.all));
Out_Last := Out_Data'Last Out_Last := Out_Data'Last
- Stream_Element_Offset (Avail_Out (Filter.Strm.all)); - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
end Translate_Auto; end Translate_Auto;
-------------------- --------------------
...@@ -529,7 +556,7 @@ package body ZLib is ...@@ -529,7 +556,7 @@ package body ZLib is
Out_Last : out Ada.Streams.Stream_Element_Offset; Out_Last : out Ada.Streams.Stream_Element_Offset;
Flush : in Flush_Mode) Flush : in Flush_Mode)
is is
Out_First : Stream_Element_Offset; Out_First : Stream_Element_Offset;
procedure Add_Data (Data : in Stream_Element_Array); procedure Add_Data (Data : in Stream_Element_Array);
-- Add data to stream from the Filter.Offset till necessary, -- Add data to stream from the Filter.Offset till necessary,
...@@ -596,7 +623,7 @@ package body ZLib is ...@@ -596,7 +623,7 @@ package body ZLib is
Add_Data (Simple_GZip_Header); Add_Data (Simple_GZip_Header);
Translate_Auto Translate_Auto
(Filter => Filter, (Filter => Filter,
In_Data => In_Data, In_Data => In_Data,
In_Last => In_Last, In_Last => In_Last,
Out_Data => Out_Data (Out_First .. Out_Data'Last), Out_Data => Out_Data (Out_First .. Out_Data'Last),
...@@ -604,7 +631,6 @@ package body ZLib is ...@@ -604,7 +631,6 @@ package body ZLib is
Flush => Flush); Flush => Flush);
CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last)); CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
end if; end if;
if Filter.Stream_End and then Out_Last <= Out_Data'Last then if Filter.Stream_End and then Out_Last <= Out_Data'Last then
...@@ -642,10 +668,11 @@ package body ZLib is ...@@ -642,10 +668,11 @@ package body ZLib is
procedure Write procedure Write
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : in Ada.Streams.Stream_Element_Array; Item : in Ada.Streams.Stream_Element_Array;
Flush : in Flush_Mode) Flush : in Flush_Mode := No_Flush)
is is
Buffer : Stream_Element_Array (1 .. Buffer_Size); Buffer : Stream_Element_Array (1 .. Buffer_Size);
In_Last, Out_Last : Stream_Element_Offset; In_Last : Stream_Element_Offset;
Out_Last : Stream_Element_Offset;
In_First : Stream_Element_Offset := Item'First; In_First : Stream_Element_Offset := Item'First;
begin begin
if Item'Length = 0 and Flush = No_Flush then if Item'Length = 0 and Flush = No_Flush then
...@@ -654,7 +681,7 @@ package body ZLib is ...@@ -654,7 +681,7 @@ package body ZLib is
loop loop
Translate Translate
(Filter => Filter, (Filter => Filter,
In_Data => Item (In_First .. Item'Last), In_Data => Item (In_First .. Item'Last),
In_Last => In_Last, In_Last => In_Last,
Out_Data => Buffer, Out_Data => Buffer,
......
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- ZLib for Ada thick binding. -- -- ZLib for Ada thick binding. --
-- -- -- --
-- Copyright (C) 2002-2003 Dmitriy Anisimkov -- -- Copyright (C) 2002-2004 Dmitriy Anisimkov --
-- -- -- --
-- This library is free software; you can redistribute it and/or modify -- -- This library is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by -- -- it under the terms of the GNU General Public License as published by --
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
-- covered by the GNU Public License. -- -- covered by the GNU Public License. --
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-- $Id: zlib.ads,v 1.17 2003/08/12 13:19:07 vagul Exp $ -- $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
with Ada.Streams; with Ada.Streams;
...@@ -33,7 +33,8 @@ with Interfaces; ...@@ -33,7 +33,8 @@ with Interfaces;
package ZLib is package ZLib is
ZLib_Error : exception; ZLib_Error : exception;
Status_Error : exception;
type Compression_Level is new Integer range -1 .. 9; type Compression_Level is new Integer range -1 .. 9;
...@@ -55,12 +56,15 @@ package ZLib is ...@@ -55,12 +56,15 @@ package ZLib is
subtype Count is Ada.Streams.Stream_Element_Count; subtype Count is Ada.Streams.Stream_Element_Count;
Default_Memory_Level : constant Memory_Level_Type := 8;
Default_Window_Bits : constant Window_Bits_Type := 15;
---------------------------------- ----------------------------------
-- Compression method constants -- -- Compression method constants --
---------------------------------- ----------------------------------
Deflated : constant Compression_Method; Deflated : constant Compression_Method;
-- Only one method allowed in this ZLib version. -- Only one method allowed in this ZLib version
--------------------------------- ---------------------------------
-- Compression level constants -- -- Compression level constants --
...@@ -79,21 +83,29 @@ package ZLib is ...@@ -79,21 +83,29 @@ package ZLib is
-- Regular way for compression, no flush -- Regular way for compression, no flush
Partial_Flush : constant Flush_Mode; Partial_Flush : constant Flush_Mode;
-- will be removed, use Z_SYNC_FLUSH instead -- Will be removed, use Z_SYNC_FLUSH instead
Sync_Flush : constant Flush_Mode; Sync_Flush : constant Flush_Mode;
-- all pending output is flushed to the output buffer and the output -- All pending output is flushed to the output buffer and the output
-- is aligned on a byte boundary, so that the decompressor can get all -- is aligned on a byte boundary, so that the decompressor can get all
-- input data available so far. (In particular avail_in is zero after the -- input data available so far. (In particular avail_in is zero after the
-- call if enough output space has been provided before the call.) -- call if enough output space has been provided before the call.)
-- Flushing may degrade compression for some compression algorithms and so -- Flushing may degrade compression for some compression algorithms and so
-- it should be used only when necessary. -- it should be used only when necessary.
Block_Flush : constant Flush_Mode;
-- Z_BLOCK requests that inflate() stop
-- if and when it get to the next deflate block boundary. When decoding the
-- zlib or gzip format, this will cause inflate() to return immediately
-- after the header and before the first block. When doing a raw inflate,
-- inflate() will go ahead and process the first block, and will return
-- when it gets to the end of that block, or when it runs out of data.
Full_Flush : constant Flush_Mode; Full_Flush : constant Flush_Mode;
-- all output is flushed as with SYNC_FLUSH, and the compression state -- All output is flushed as with SYNC_FLUSH, and the compression state
-- is reset so that decompression can restart from this point if previous -- is reset so that decompression can restart from this point if previous
-- compressed data has been damaged or if random access is desired. Using -- compressed data has been damaged or if random access is desired. Using
-- FULL_FLUSH too often can seriously degrade the compression. -- Full_Flush too often can seriously degrade the compression.
Finish : constant Flush_Mode; Finish : constant Flush_Mode;
-- Just for tell the compressor that input data is complete. -- Just for tell the compressor that input data is complete.
...@@ -111,7 +123,7 @@ package ZLib is ...@@ -111,7 +123,7 @@ package ZLib is
Default_Buffer_Size : constant := 4096; Default_Buffer_Size : constant := 4096;
type Filter_Type is limited private; type Filter_Type is tagged limited private;
-- The filter is for compression and for decompression. -- The filter is for compression and for decompression.
-- The usage of the type is depend of its initialization. -- The usage of the type is depend of its initialization.
...@@ -124,8 +136,8 @@ package ZLib is ...@@ -124,8 +136,8 @@ package ZLib is
Level : in Compression_Level := Default_Compression; Level : in Compression_Level := Default_Compression;
Strategy : in Strategy_Type := Default_Strategy; Strategy : in Strategy_Type := Default_Strategy;
Method : in Compression_Method := Deflated; Method : in Compression_Method := Deflated;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Memory_Level : in Memory_Level_Type := 8; Memory_Level : in Memory_Level_Type := Default_Memory_Level;
Header : in Header_Type := Default); Header : in Header_Type := Default);
-- Compressor initialization. -- Compressor initialization.
-- When Header parameter is Auto or Default, then default zlib header -- When Header parameter is Auto or Default, then default zlib header
...@@ -136,7 +148,7 @@ package ZLib is ...@@ -136,7 +148,7 @@ package ZLib is
procedure Inflate_Init procedure Inflate_Init
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Window_Bits : in Window_Bits_Type := 15; Window_Bits : in Window_Bits_Type := Default_Window_Bits;
Header : in Header_Type := Default); Header : in Header_Type := Default);
-- Decompressor initialization. -- Decompressor initialization.
-- Default header type mean that ZLib default header is expecting in the -- Default header type mean that ZLib default header is expecting in the
...@@ -146,10 +158,14 @@ package ZLib is ...@@ -146,10 +158,14 @@ package ZLib is
-- input compressed stream. -- input compressed stream.
-- Auto header type mean that header type (GZip or Native) would be -- Auto header type mean that header type (GZip or Native) would be
-- detected automatically in the input stream. -- detected automatically in the input stream.
-- Note that header types parameter values None, GZip and Auto is -- Note that header types parameter values None, GZip and Auto are
-- supporting for inflate routine only in ZLib versions 1.2.0.2 and later. -- supported for inflate routine only in ZLib versions 1.2.0.2 and later.
-- Deflate_Init is supporting all header types. -- Deflate_Init is supporting all header types.
function Is_Open (Filter : in Filter_Type) return Boolean;
pragma Inline (Is_Open);
-- Is the filter opened for compression or decompression.
procedure Close procedure Close
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Ignore_Error : in Boolean := False); Ignore_Error : in Boolean := False);
...@@ -167,31 +183,31 @@ package ZLib is ...@@ -167,31 +183,31 @@ package ZLib is
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
In_Buffer_Size : in Integer := Default_Buffer_Size; In_Buffer_Size : in Integer := Default_Buffer_Size;
Out_Buffer_Size : in Integer := Default_Buffer_Size); Out_Buffer_Size : in Integer := Default_Buffer_Size);
-- Compressing/decompressing data arrived from Data_In routine -- Compress/decompress data fetch from Data_In routine and pass the result
-- to the Data_Out routine. User should provide Data_In and Data_Out -- to the Data_Out routine. User should provide Data_In and Data_Out
-- for compression/decompression data flow. -- for compression/decompression data flow.
-- Compression or decompression depend on initialization of Filter. -- Compression or decompression depend on Filter initialization.
function Total_In (Filter : in Filter_Type) return Count; function Total_In (Filter : in Filter_Type) return Count;
pragma Inline (Total_In); pragma Inline (Total_In);
-- Return total number of input bytes read so far. -- Returns total number of input bytes read so far
function Total_Out (Filter : in Filter_Type) return Count; function Total_Out (Filter : in Filter_Type) return Count;
pragma Inline (Total_Out); pragma Inline (Total_Out);
-- Return total number of bytes output so far. -- Returns total number of bytes output so far
function CRC32 function CRC32
(CRC : in Unsigned_32; (CRC : in Unsigned_32;
Data : in Ada.Streams.Stream_Element_Array) Data : in Ada.Streams.Stream_Element_Array)
return Unsigned_32; return Unsigned_32;
pragma Inline (CRC32); pragma Inline (CRC32);
-- Calculate CRC32, it could be necessary for make gzip format. -- Compute CRC32, it could be necessary for make gzip format
procedure CRC32 procedure CRC32
(CRC : in out Unsigned_32; (CRC : in out Unsigned_32;
Data : in Ada.Streams.Stream_Element_Array); Data : in Ada.Streams.Stream_Element_Array);
pragma Inline (CRC32); pragma Inline (CRC32);
-- Calculate CRC32, it could be necessary for make gzip format. -- Compute CRC32, it could be necessary for make gzip format
------------------------------------------------- -------------------------------------------------
-- Below is more complex low level routines. -- -- Below is more complex low level routines. --
...@@ -204,15 +220,11 @@ package ZLib is ...@@ -204,15 +220,11 @@ package ZLib is
Out_Data : out Ada.Streams.Stream_Element_Array; Out_Data : out Ada.Streams.Stream_Element_Array;
Out_Last : out Ada.Streams.Stream_Element_Offset; Out_Last : out Ada.Streams.Stream_Element_Offset;
Flush : in Flush_Mode); Flush : in Flush_Mode);
-- Compressing/decompressing the datas from In_Data buffer to the -- Compress/decompress the In_Data buffer and place the result into
-- Out_Data buffer. -- Out_Data. In_Last is the index of last element from In_Data accepted by
-- In_Data is incoming data portion, -- the Filter. Out_Last is the last element of the received data from
-- In_Last is the index of last element from In_Data accepted by the -- Filter. To tell the filter that incoming data are complete put the
-- Filter. -- Flush parameter to Finish.
-- Out_Data is the buffer for output data from the filter.
-- Out_Last is the last element of the received data from Filter.
-- To tell the filter that incoming data is complete put the
-- Flush parameter to FINISH.
function Stream_End (Filter : in Filter_Type) return Boolean; function Stream_End (Filter : in Filter_Type) return Boolean;
pragma Inline (Stream_End); pragma Inline (Stream_End);
...@@ -239,10 +251,9 @@ package ZLib is ...@@ -239,10 +251,9 @@ package ZLib is
procedure Write procedure Write
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : in Ada.Streams.Stream_Element_Array; Item : in Ada.Streams.Stream_Element_Array;
Flush : in Flush_Mode); Flush : in Flush_Mode := No_Flush);
-- Compressing/Decompressing data from Item to the -- Compress/Decompress data from Item to the generic parameter procedure
-- generic parameter procedure Write. -- Write. Output buffer size could be set in Buffer_Size generic parameter.
-- Output buffer size could be set in Buffer_Size generic parameter.
generic generic
with procedure Read with procedure Read
...@@ -257,33 +268,41 @@ package ZLib is ...@@ -257,33 +268,41 @@ package ZLib is
Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset; Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
-- Rest_First have to be initialized to Buffer'Last + 1 -- Rest_First have to be initialized to Buffer'Last + 1
-- Rest_Last have to be initialized to Buffer'Last
-- before usage. -- before usage.
Allow_Read_Some : in Boolean := False;
-- Is it allowed to return Last < Item'Last before end of data.
procedure Read procedure Read
(Filter : in out Filter_Type; (Filter : in out Filter_Type;
Item : out Ada.Streams.Stream_Element_Array; Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset); Last : out Ada.Streams.Stream_Element_Offset;
-- Compressing/Decompressing data from generic parameter Flush : in Flush_Mode := No_Flush);
-- procedure Read to the Item. -- Compress/Decompress data from generic parameter procedure Read to the
-- User should provide Buffer for the operation -- Item. User should provide Buffer and initialized Rest_First, Rest_Last
-- and Rest_First variable first time initialized to the Buffer'Last + 1. -- indicators. If Allow_Read_Some is True, Read routines could return
-- Last < Item'Last only at end of stream.
private private
use Ada.Streams; use Ada.Streams;
type Flush_Mode is new Integer range 0 .. 4; pragma Assert (Ada.Streams.Stream_Element'Size = 8);
pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
type Flush_Mode is new Integer range 0 .. 5;
type Compression_Method is new Integer range 8 .. 8; type Compression_Method is new Integer range 8 .. 8;
type Strategy_Type is new Integer range 0 .. 3; type Strategy_Type is new Integer range 0 .. 3;
No_Flush : constant Flush_Mode := 0; No_Flush : constant Flush_Mode := 0;
Partial_Flush : constant Flush_Mode := 1;
Sync_Flush : constant Flush_Mode := 2; Sync_Flush : constant Flush_Mode := 2;
Full_Flush : constant Flush_Mode := 3; Full_Flush : constant Flush_Mode := 3;
Finish : constant Flush_Mode := 4; Finish : constant Flush_Mode := 4;
Partial_Flush : constant Flush_Mode := 1; Block_Flush : constant Flush_Mode := 5;
-- will be removed, use Z_SYNC_FLUSH instead
Filtered : constant Strategy_Type := 1; Filtered : constant Strategy_Type := 1;
Huffman_Only : constant Strategy_Type := 2; Huffman_Only : constant Strategy_Type := 2;
...@@ -296,7 +315,7 @@ private ...@@ -296,7 +315,7 @@ private
type Z_Stream_Access is access all Z_Stream; type Z_Stream_Access is access all Z_Stream;
type Filter_Type is record type Filter_Type is tagged limited record
Strm : Z_Stream_Access; Strm : Z_Stream_Access;
Compression : Boolean; Compression : Boolean;
Stream_End : Boolean; Stream_End : Boolean;
...@@ -304,8 +323,6 @@ private ...@@ -304,8 +323,6 @@ private
CRC : Unsigned_32; CRC : Unsigned_32;
Offset : Stream_Element_Offset; Offset : Stream_Element_Offset;
-- Offset for gzip header/footer output. -- Offset for gzip header/footer output.
Opened : Boolean := False;
end record; end record;
end ZLib; end ZLib;
...@@ -3,10 +3,10 @@ project Zlib is ...@@ -3,10 +3,10 @@ project Zlib is
for Languages use ("Ada"); for Languages use ("Ada");
for Source_Dirs use ("."); for Source_Dirs use (".");
for Object_Dir use "."; for Object_Dir use ".";
for Main use ("test.adb", "mtest.adb", "read.adb"); for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
package Compiler is package Compiler is
for Default_Switches ("ada") use ("-gnatwbcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst"); for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
end Compiler; end Compiler;
package Linker is package Linker is
...@@ -18,4 +18,3 @@ project Zlib is ...@@ -18,4 +18,3 @@ project Zlib is
end Builder; end Builder;
end Zlib; end Zlib;
...@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer; ...@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
const OutBuf: Pointer; BufSize: Integer); const OutBuf: Pointer; BufSize: Integer);
const const
zlib_version = '1.2.1'; zlib_version = '1.2.3';
type type
EZlibError = class(Exception); EZlibError = class(Exception);
...@@ -344,7 +344,7 @@ begin ...@@ -344,7 +344,7 @@ begin
strm.avail_out := OutBytes; strm.avail_out := OutBytes;
DCheck(inflateInit_(strm, zlib_version, sizeof(strm))); DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
try try
while DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END do while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
begin begin
P := OutBuf; P := OutBuf;
Inc(OutBytes, BufInc); Inc(OutBytes, BufInc);
...@@ -510,7 +510,7 @@ begin ...@@ -510,7 +510,7 @@ begin
Result := Count - FZRec.avail_out; Result := Count - FZRec.avail_out;
Exit; Exit;
end; end;
FZRec.next_in := FBuffer; FZRec.next_in := FBuffer;
FStrmPos := FStrm.Position; FStrmPos := FStrm.Position;
Progress(Self); Progress(Self);
end; end;
......
...@@ -430,6 +430,9 @@ void FAR *out_desc; ...@@ -430,6 +430,9 @@ void FAR *out_desc;
} }
} }
/* handle error breaks in while */
if (mode == BAD) break;
/* build code tables */ /* build code tables */
state->next = state->codes; state->next = state->codes;
lencode = (code const FAR *)(state->next); lencode = (code const FAR *)(state->next);
......
...@@ -16,6 +16,10 @@ ...@@ -16,6 +16,10 @@
* zlib.h must be included before this header file. * zlib.h must be included before this header file.
*/ */
#ifdef __cplusplus
extern "C" {
#endif
ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm, ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
in_func in, void FAR *in_desc, in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc)); out_func out, void FAR *out_desc));
...@@ -27,3 +31,7 @@ ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm, ...@@ -27,3 +31,7 @@ ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
#define inflateBack9Init(strm, window) \ #define inflateBack9Init(strm, window) \
inflateBack9Init_((strm), (window), \ inflateBack9Init_((strm), (window), \
ZLIB_VERSION, sizeof(z_stream)) ZLIB_VERSION, sizeof(z_stream))
#ifdef __cplusplus
}
#endif
/* inftree9.c -- generate Huffman trees for efficient decoding /* inftree9.c -- generate Huffman trees for efficient decoding
* Copyright (C) 1995-2003 Mark Adler * Copyright (C) 1995-2005 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#define MAXBITS 15 #define MAXBITS 15
const char inflate9_copyright[] = const char inflate9_copyright[] =
" inflate9 1.2.1 Copyright 1995-2003 Mark Adler "; " inflate9 1.2.3 Copyright 1995-2005 Mark Adler ";
/* /*
If you use the zlib library in a product, an acknowledgment is welcome If you use the zlib library in a product, an acknowledgment is welcome
in the documentation of your product. If for some reason you cannot in the documentation of your product. If for some reason you cannot
...@@ -64,7 +64,7 @@ unsigned short FAR *work; ...@@ -64,7 +64,7 @@ unsigned short FAR *work;
static const unsigned short lext[31] = { /* Length codes 257..285 extra */ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132, 130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
133, 133, 133, 133, 144, 76, 66}; 133, 133, 133, 133, 144, 201, 196};
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */ static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
...@@ -128,7 +128,7 @@ unsigned short FAR *work; ...@@ -128,7 +128,7 @@ unsigned short FAR *work;
left -= count[len]; left -= count[len];
if (left < 0) return -1; /* over-subscribed */ if (left < 0) return -1; /* over-subscribed */
} }
if (left > 0 && (type == CODES || (codes - count[0] != 1))) if (left > 0 && (type == CODES || max != 1))
return -1; /* incomplete set */ return -1; /* incomplete set */
/* generate offsets into symbol table for each length for sorting */ /* generate offsets into symbol table for each length for sorting */
......
...@@ -36,12 +36,12 @@ typedef struct { ...@@ -36,12 +36,12 @@ typedef struct {
*/ */
/* Maximum size of dynamic tree. The maximum found in a long but non- /* Maximum size of dynamic tree. The maximum found in a long but non-
exhaustive search was 1004 code structures (850 for length/literals exhaustive search was 1444 code structures (852 for length/literals
and 154 for distances, the latter actually the result of an and 592 for distances, the latter actually the result of an
exhaustive search). The true maximum is not known, but the value exhaustive search). The true maximum is not known, but the value
below is more than safe. */ below is more than safe. */
#define ENOUGH 1440 #define ENOUGH 2048
#define MAXD 154 #define MAXD 592
/* Type of code to build for inftable() */ /* Type of code to build for inftable() */
typedef enum { typedef enum {
......
...@@ -7,6 +7,15 @@ ...@@ -7,6 +7,15 @@
* Copyright (C) 2003 Chris Anderson <christop@charm.net> * Copyright (C) 2003 Chris Anderson <christop@charm.net>
* Please use the copyright conditions above. * Please use the copyright conditions above.
* *
* 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 * 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 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, * the moment. I have successfully compiled and tested this code with gcc2.96,
...@@ -65,33 +74,44 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -65,33 +74,44 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
{ {
struct inflate_state FAR *state; struct inflate_state FAR *state;
struct inffast_ar { struct inffast_ar {
void *esp; /* esp save */ /* 64 32 x86 x86_64 */
unsigned char FAR *in; /* local strm->next_in */ /* ar offset register */
unsigned char FAR *last; /* while in < last, enough input available */ /* 0 0 */ void *esp; /* esp save */
unsigned char FAR *out; /* local strm->next_out */ /* 8 4 */ void *ebp; /* ebp save */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ /* 16 8 */ unsigned char FAR *in; /* esi rsi local strm->next_in */
unsigned char FAR *end; /* while out < end, enough space available */ /* 24 12 */ unsigned char FAR *last; /* r9 while in < last */
unsigned wsize; /* window size or zero if not using window */ /* 32 16 */ unsigned char FAR *out; /* edi rdi local strm->next_out */
unsigned write; /* window write index */ /* 40 20 */ unsigned char FAR *beg; /* inflate()'s init next_out */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ /* 48 24 */ unsigned char FAR *end; /* r10 while out < end */
unsigned long hold; /* local strm->hold */ /* 56 28 */ unsigned char FAR *window;/* size of window, wsize!=0 */
unsigned bits; /* local strm->bits */ /* 64 32 */ code const FAR *lcode; /* ebp rbp local strm->lencode */
code const FAR *lcode; /* local strm->lencode */ /* 72 36 */ code const FAR *dcode; /* r11 local strm->distcode */
code const FAR *dcode; /* local strm->distcode */ /* 80 40 */ unsigned long hold; /* edx rdx local strm->hold */
unsigned lmask; /* mask for first level of length codes */ /* 88 44 */ unsigned bits; /* ebx rbx local strm->bits */
unsigned dmask; /* mask for first level of distance codes */ /* 92 48 */ unsigned wsize; /* window size */
unsigned len; /* match length, unused bytes */ /* 96 52 */ unsigned write; /* window write index */
unsigned dist; /* match distance */ /*100 56 */ unsigned lmask; /* r12 mask for lcode */
unsigned status; /* this is set when state changes */ /*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*/
} ar; } ar;
#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
#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 */ /* copy state to local variables */
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
ar.in = strm->next_in; ar.in = strm->next_in;
ar.last = ar.in + (strm->avail_in - 5); ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
ar.out = strm->next_out; ar.out = strm->next_out;
ar.beg = ar.out - (start - strm->avail_out); ar.beg = ar.out - (start - strm->avail_out);
ar.end = ar.out + (strm->avail_out - 257); ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
ar.wsize = state->wsize; ar.wsize = state->wsize;
ar.write = state->write; ar.write = state->write;
ar.window = state->window; ar.window = state->window;
...@@ -105,32 +125,368 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -105,32 +125,368 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
/* decode literals and length/distances until end-of-block or not enough /* decode literals and length/distances until end-of-block or not enough
input data or output space */ input data or output space */
/* align in on 2 byte boundary */ /* align in on 1/2 hold size boundary */
if (((unsigned long)(void *)ar.in & 0x1) != 0) { while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
ar.hold += (unsigned long)*ar.in++ << ar.bits; ar.hold += (unsigned long)*ar.in++ << ar.bits;
ar.bits += 8; ar.bits += 8;
} }
#if defined( __GNUC__ ) || defined( __ICC ) #if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
__asm__ __volatile__ (
" leaq %0, %%rax\n"
" movq %%rbp, 8(%%rax)\n" /* save regs rbp and rsp */
" movq %%rsp, (%%rax)\n"
" movq %%rax, %%rsp\n" /* make rsp point to &ar */
" movq 16(%%rsp), %%rsi\n" /* rsi = in */
" movq 32(%%rsp), %%rdi\n" /* rdi = out */
" movq 24(%%rsp), %%r9\n" /* r9 = last */
" movq 48(%%rsp), %%r10\n" /* r10 = end */
" movq 64(%%rsp), %%rbp\n" /* rbp = lcode */
" movq 72(%%rsp), %%r11\n" /* r11 = dcode */
" movq 80(%%rsp), %%rdx\n" /* rdx = hold */
" movl 88(%%rsp), %%ebx\n" /* ebx = bits */
" movl 100(%%rsp), %%r12d\n" /* r12d = lmask */
" movl 104(%%rsp), %%r13d\n" /* r13d = dmask */
/* r14d = len */
/* r15d = dist */
" cld\n"
" cmpq %%rdi, %%r10\n"
" je .L_one_time\n" /* if only one decode left */
" cmpq %%rsi, %%r9\n"
" je .L_one_time\n"
" jmp .L_do_loop\n"
".L_one_time:\n"
" movq %%r12, %%r8\n" /* r8 = lmask */
" cmpb $32, %%bl\n"
" ja .L_get_length_code_one_time\n"
" lodsl\n" /* eax = *(uint *)in++ */
" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
" addb $32, %%bl\n" /* bits += 32 */
" shlq %%cl, %%rax\n"
" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
" jmp .L_get_length_code_one_time\n"
".align 32,0x90\n"
".L_while_test:\n"
" cmpq %%rdi, %%r10\n"
" jbe .L_break_loop\n"
" cmpq %%rsi, %%r9\n"
" jbe .L_break_loop\n"
".L_do_loop:\n"
" movq %%r12, %%r8\n" /* r8 = lmask */
" cmpb $32, %%bl\n"
" ja .L_get_length_code\n" /* if (32 < bits) */
" lodsl\n" /* eax = *(uint *)in++ */
" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
" addb $32, %%bl\n" /* bits += 32 */
" shlq %%cl, %%rax\n"
" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
".L_get_length_code:\n"
" andq %%rdx, %%r8\n" /* r8 &= hold */
" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
" movb %%ah, %%cl\n" /* cl = this.bits */
" subb %%ah, %%bl\n" /* bits -= this.bits */
" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
" testb %%al, %%al\n"
" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
" movq %%r12, %%r8\n" /* r8 = lmask */
" shrl $16, %%eax\n" /* output this.val char */
" stosb\n"
".L_get_length_code_one_time:\n"
" andq %%rdx, %%r8\n" /* r8 &= hold */
" movl (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
".L_dolen:\n"
" movb %%ah, %%cl\n" /* cl = this.bits */
" subb %%ah, %%bl\n" /* bits -= this.bits */
" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
" testb %%al, %%al\n"
" jnz .L_test_for_length_base\n" /* if (op != 0) 45.7% */
" shrl $16, %%eax\n" /* output this.val char */
" stosb\n"
" jmp .L_while_test\n"
".align 32,0x90\n"
".L_test_for_length_base:\n"
" movl %%eax, %%r14d\n" /* len = this */
" shrl $16, %%r14d\n" /* len = this.val */
" movb %%al, %%cl\n"
" testb $16, %%al\n"
" jz .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
" andb $15, %%cl\n" /* op &= 15 */
" jz .L_decode_distance\n" /* if (!op) */
".L_add_bits_to_len:\n"
" subb %%cl, %%bl\n"
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n"
" decl %%eax\n"
" andl %%edx, %%eax\n" /* eax &= hold */
" shrq %%cl, %%rdx\n"
" addl %%eax, %%r14d\n" /* len += hold & mask[op] */
".L_decode_distance:\n"
" movq %%r13, %%r8\n" /* r8 = dmask */
" cmpb $32, %%bl\n"
" ja .L_get_distance_code\n" /* if (32 < bits) */
" lodsl\n" /* eax = *(uint *)in++ */
" movb %%bl, %%cl\n" /* cl = bits, needs it for shifting */
" addb $32, %%bl\n" /* bits += 32 */
" shlq %%cl, %%rax\n"
" orq %%rax, %%rdx\n" /* hold |= *((uint *)in)++ << bits */
".L_get_distance_code:\n"
" andq %%rdx, %%r8\n" /* r8 &= hold */
" movl (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
".L_dodist:\n"
" movl %%eax, %%r15d\n" /* dist = this */
" shrl $16, %%r15d\n" /* dist = this.val */
" movb %%ah, %%cl\n"
" subb %%ah, %%bl\n" /* bits -= this.bits */
" shrq %%cl, %%rdx\n" /* hold >>= this.bits */
" movb %%al, %%cl\n" /* cl = this.op */
" testb $16, %%al\n" /* if ((op & 16) == 0) */
" jz .L_test_for_second_level_dist\n"
" andb $15, %%cl\n" /* op &= 15 */
" jz .L_check_dist_one\n"
".L_add_bits_to_dist:\n"
" subb %%cl, %%bl\n"
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n"
" decl %%eax\n" /* (1 << op) - 1 */
" andl %%edx, %%eax\n" /* eax &= hold */
" shrq %%cl, %%rdx\n"
" addl %%eax, %%r15d\n" /* dist += hold & ((1 << op) - 1) */
".L_check_window:\n"
" movq %%rsi, %%r8\n" /* save in so from can use it's reg */
" movq %%rdi, %%rax\n"
" subq 40(%%rsp), %%rax\n" /* nbytes = out - beg */
" cmpl %%r15d, %%eax\n"
" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
" movl %%r14d, %%ecx\n" /* ecx = len */
" movq %%rdi, %%rsi\n"
" subq %%r15, %%rsi\n" /* from = out - dist */
" sarl %%ecx\n"
" jnc .L_copy_two\n" /* if len % 2 == 0 */
" rep movsw\n"
" movb (%%rsi), %%al\n"
" movb %%al, (%%rdi)\n"
" incq %%rdi\n"
" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
" jmp .L_while_test\n"
".L_copy_two:\n"
" rep movsw\n"
" movq %%r8, %%rsi\n" /* move in back to %rsi, toss from */
" jmp .L_while_test\n"
".align 32,0x90\n"
".L_check_dist_one:\n"
" cmpl $1, %%r15d\n" /* if dist 1, is a memset */
" jne .L_check_window\n"
" cmpq %%rdi, 40(%%rsp)\n" /* if out == beg, outside window */
" je .L_check_window\n"
" movl %%r14d, %%ecx\n" /* ecx = len */
" movb -1(%%rdi), %%al\n"
" movb %%al, %%ah\n"
" sarl %%ecx\n"
" jnc .L_set_two\n"
" movb %%al, (%%rdi)\n"
" incq %%rdi\n"
".L_set_two:\n"
" rep stosw\n"
" jmp .L_while_test\n"
".align 32,0x90\n"
".L_test_for_second_level_length:\n"
" testb $64, %%al\n"
" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n"
" decl %%eax\n"
" andl %%edx, %%eax\n" /* eax &= hold */
" addl %%r14d, %%eax\n" /* eax += len */
" movl (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
" jmp .L_dolen\n"
".align 32,0x90\n"
".L_test_for_second_level_dist:\n"
" testb $64, %%al\n"
" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n"
" decl %%eax\n"
" andl %%edx, %%eax\n" /* eax &= hold */
" addl %%r15d, %%eax\n" /* eax += dist */
" movl (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
" jmp .L_dodist\n"
".align 32,0x90\n"
".L_clip_window:\n"
" movl %%eax, %%ecx\n" /* ecx = nbytes */
" movl 92(%%rsp), %%eax\n" /* eax = wsize, prepare for dist cmp */
" negl %%ecx\n" /* nbytes = -nbytes */
" cmpl %%r15d, %%eax\n"
" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
" addl %%r15d, %%ecx\n" /* nbytes = dist - nbytes */
" cmpl $0, 96(%%rsp)\n"
" jne .L_wrap_around_window\n" /* if (write != 0) */
" movq 56(%%rsp), %%rsi\n" /* from = window */
" subl %%ecx, %%eax\n" /* eax -= nbytes */
" addq %%rax, %%rsi\n" /* from += wsize - nbytes */
" movl %%r14d, %%eax\n" /* eax = len */
" cmpl %%ecx, %%r14d\n"
" jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* eax -= nbytes */
" rep movsb\n"
" movq %%rdi, %%rsi\n"
" subq %%r15, %%rsi\n" /* from = &out[ -dist ] */
" jmp .L_do_copy\n"
".align 32,0x90\n"
".L_wrap_around_window:\n"
" movl 96(%%rsp), %%eax\n" /* eax = write */
" cmpl %%eax, %%ecx\n"
" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
" movl 92(%%rsp), %%esi\n" /* from = wsize */
" addq 56(%%rsp), %%rsi\n" /* from += window */
" addq %%rax, %%rsi\n" /* from += write */
" subq %%rcx, %%rsi\n" /* from -= nbytes */
" subl %%eax, %%ecx\n" /* nbytes -= write */
" movl %%r14d, %%eax\n" /* eax = len */
" cmpl %%ecx, %%eax\n"
" jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n"
" movq 56(%%rsp), %%rsi\n" /* from = window */
" movl 96(%%rsp), %%ecx\n" /* nbytes = write */
" cmpl %%ecx, %%eax\n"
" jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n"
" movq %%rdi, %%rsi\n"
" subq %%r15, %%rsi\n" /* from = out - dist */
" jmp .L_do_copy\n"
".align 32,0x90\n"
".L_contiguous_in_window:\n"
" movq 56(%%rsp), %%rsi\n" /* rsi = window */
" addq %%rax, %%rsi\n"
" subq %%rcx, %%rsi\n" /* from += write - nbytes */
" movl %%r14d, %%eax\n" /* eax = len */
" cmpl %%ecx, %%eax\n"
" jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n"
" movq %%rdi, %%rsi\n"
" subq %%r15, %%rsi\n" /* from = out - dist */
" jmp .L_do_copy\n" /* if (nbytes >= len) */
".align 32,0x90\n"
".L_do_copy:\n"
" movl %%eax, %%ecx\n" /* ecx = len */
" rep movsb\n"
" movq %%r8, %%rsi\n" /* move in back to %esi, toss from */
" jmp .L_while_test\n"
".L_test_for_end_of_block:\n"
" testb $32, %%al\n"
" jz .L_invalid_literal_length_code\n"
" movl $1, 116(%%rsp)\n"
" jmp .L_break_loop_with_status\n"
".L_invalid_literal_length_code:\n"
" movl $2, 116(%%rsp)\n"
" jmp .L_break_loop_with_status\n"
".L_invalid_distance_code:\n"
" movl $3, 116(%%rsp)\n"
" jmp .L_break_loop_with_status\n"
".L_invalid_distance_too_far:\n"
" movl $4, 116(%%rsp)\n"
" jmp .L_break_loop_with_status\n"
".L_break_loop:\n"
" movl $0, 116(%%rsp)\n"
".L_break_loop_with_status:\n"
/* put in, out, bits, and hold back into ar and pop esp */
" movq %%rsi, 16(%%rsp)\n" /* in */
" movq %%rdi, 32(%%rsp)\n" /* out */
" movl %%ebx, 88(%%rsp)\n" /* bits */
" movq %%rdx, 80(%%rsp)\n" /* hold */
" movq (%%rsp), %%rax\n" /* restore rbp and rsp */
" movq 8(%%rsp), %%rbp\n"
" movq %%rax, %%rsp\n"
:
: "m" (ar)
: "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
"%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
);
#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
__asm__ __volatile__ ( __asm__ __volatile__ (
" leal %0, %%eax\n" " leal %0, %%eax\n"
" pushf\n" " movl %%esp, (%%eax)\n" /* save esp, ebp */
" pushl %%ebp\n" " movl %%ebp, 4(%%eax)\n"
" movl %%esp, (%%eax)\n"
" movl %%eax, %%esp\n" " movl %%eax, %%esp\n"
" movl 4(%%esp), %%esi\n" /* esi = in */ " movl 8(%%esp), %%esi\n" /* esi = in */
" movl 12(%%esp), %%edi\n" /* edi = out */ " movl 16(%%esp), %%edi\n" /* edi = out */
" movl 36(%%esp), %%edx\n" /* edx = hold */ " movl 40(%%esp), %%edx\n" /* edx = hold */
" movl 40(%%esp), %%ebx\n" /* ebx = bits */ " movl 44(%%esp), %%ebx\n" /* ebx = bits */
" movl 44(%%esp), %%ebp\n" /* ebp = lcode */ " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
" cld\n" " cld\n"
" jmp .L_do_loop\n" " jmp .L_do_loop\n"
".align 32,0x90\n"
".L_while_test:\n" ".L_while_test:\n"
" cmpl %%edi, 20(%%esp)\n" " cmpl %%edi, 24(%%esp)\n" /* out < end */
" jbe .L_break_loop\n" " jbe .L_break_loop\n"
" cmpl %%esi, 8(%%esp)\n" " cmpl %%esi, 12(%%esp)\n" /* in < last */
" jbe .L_break_loop\n" " jbe .L_break_loop\n"
".L_do_loop:\n" ".L_do_loop:\n"
...@@ -145,7 +501,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -145,7 +501,7 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
".L_get_length_code:\n" ".L_get_length_code:\n"
" movl 52(%%esp), %%eax\n" /* eax = lmask */ " movl 56(%%esp), %%eax\n" /* eax = lmask */
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */ " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
...@@ -161,10 +517,11 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -161,10 +517,11 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
" stosb\n" " stosb\n"
" jmp .L_while_test\n" " jmp .L_while_test\n"
".align 32,0x90\n"
".L_test_for_length_base:\n" ".L_test_for_length_base:\n"
" movl %%eax, %%ecx\n" /* len = this */ " movl %%eax, %%ecx\n" /* len = this */
" shrl $16, %%ecx\n" /* len = this.val */ " shrl $16, %%ecx\n" /* len = this.val */
" movl %%ecx, 60(%%esp)\n" /* len = this */ " movl %%ecx, 64(%%esp)\n" /* save len */
" movb %%al, %%cl\n" " movb %%al, %%cl\n"
" testb $16, %%al\n" " testb $16, %%al\n"
...@@ -184,13 +541,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -184,13 +541,14 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
" movb %%ch, %%cl\n" /* move op back to ecx */ " movb %%ch, %%cl\n" /* move op back to ecx */
".L_add_bits_to_len:\n" ".L_add_bits_to_len:\n"
" movl $1, %%eax\n" " subb %%cl, %%bl\n"
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n" " shll %%cl, %%eax\n"
" decl %%eax\n" " decl %%eax\n"
" subb %%cl, %%bl\n"
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" shrl %%cl, %%edx\n" " shrl %%cl, %%edx\n"
" addl %%eax, 60(%%esp)\n" /* len += hold & mask[op] */ " addl %%eax, 64(%%esp)\n" /* len += hold & mask[op] */
".L_decode_distance:\n" ".L_decode_distance:\n"
" cmpb $15, %%bl\n" " cmpb $15, %%bl\n"
...@@ -204,8 +562,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -204,8 +562,8 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
" orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */ " orl %%eax, %%edx\n" /* hold |= *((ushort *)in)++ << bits */
".L_get_distance_code:\n" ".L_get_distance_code:\n"
" movl 56(%%esp), %%eax\n" /* eax = dmask */ " movl 60(%%esp), %%eax\n" /* eax = dmask */
" movl 48(%%esp), %%ecx\n" /* ecx = dcode */ " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */ " movl (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
...@@ -234,223 +592,228 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */ ...@@ -234,223 +592,228 @@ unsigned start; /* inflate()'s starting value for strm->avail_out */
" movb %%ch, %%cl\n" /* move op back to ecx */ " movb %%ch, %%cl\n" /* move op back to ecx */
".L_add_bits_to_dist:\n" ".L_add_bits_to_dist:\n"
" movl $1, %%eax\n" " subb %%cl, %%bl\n"
" xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n" " shll %%cl, %%eax\n"
" decl %%eax\n" /* (1 << op) - 1 */ " decl %%eax\n" /* (1 << op) - 1 */
" subb %%cl, %%bl\n"
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" shrl %%cl, %%edx\n" " shrl %%cl, %%edx\n"
" addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */ " addl %%eax, %%ebp\n" /* dist += hold & ((1 << op) - 1) */
".L_check_window:\n" ".L_check_window:\n"
" movl %%esi, 4(%%esp)\n" /* save in so from can use it's reg */ " movl %%esi, 8(%%esp)\n" /* save in so from can use it's reg */
" movl %%edi, %%eax\n" " movl %%edi, %%eax\n"
" subl 16(%%esp), %%eax\n" /* nbytes = out - beg */ " subl 20(%%esp), %%eax\n" /* nbytes = out - beg */
" cmpl %%ebp, %%eax\n" " cmpl %%ebp, %%eax\n"
" jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */ " jb .L_clip_window\n" /* if (dist > nbytes) 4.2% */
" movl 60(%%esp), %%ecx\n" " movl 64(%%esp), %%ecx\n" /* ecx = len */
" movl %%edi, %%esi\n" " movl %%edi, %%esi\n"
" subl %%ebp, %%esi\n" /* from = out - dist */ " subl %%ebp, %%esi\n" /* from = out - dist */
" subl $3, %%ecx\n" /* copy from to out */ " sarl %%ecx\n"
" jnc .L_copy_two\n" /* if len % 2 == 0 */
" rep movsw\n"
" movb (%%esi), %%al\n" " movb (%%esi), %%al\n"
" movb %%al, (%%edi)\n" " movb %%al, (%%edi)\n"
" movb 1(%%esi), %%al\n" " incl %%edi\n"
" movb 2(%%esi), %%ah\n"
" addl $3, %%esi\n"
" movb %%al, 1(%%edi)\n"
" movb %%ah, 2(%%edi)\n"
" addl $3, %%edi\n"
" rep movsb\n"
" movl 4(%%esp), %%esi\n" /* move in back to %esi, toss from */ " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
" movl 44(%%esp), %%ebp\n" /* ebp = lcode */ " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
" jmp .L_while_test\n" " jmp .L_while_test\n"
".L_copy_two:\n"
" rep movsw\n"
" movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
" movl 32(%%esp), %%ebp\n" /* ebp = lcode */
" jmp .L_while_test\n"
".align 32,0x90\n"
".L_check_dist_one:\n" ".L_check_dist_one:\n"
" cmpl $1, %%ebp\n" /* if dist 1, is a memset */ " cmpl $1, %%ebp\n" /* if dist 1, is a memset */
" jne .L_check_window\n" " jne .L_check_window\n"
" cmpl %%edi, 16(%%esp)\n" " cmpl %%edi, 20(%%esp)\n"
" je .L_check_window\n" " je .L_check_window\n" /* out == beg, if outside window */
" movl 64(%%esp), %%ecx\n" /* ecx = len */
" movb -1(%%edi), %%al\n"
" movb %%al, %%ah\n"
" sarl %%ecx\n"
" jnc .L_set_two\n"
" movb %%al, (%%edi)\n"
" incl %%edi\n"
" decl %%edi\n" ".L_set_two:\n"
" movl 60(%%esp), %%ecx\n" " rep stosw\n"
" movb (%%edi), %%al\n" " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
" subl $3, %%ecx\n"
" movb %%al, 1(%%edi)\n" /* memset out with from[-1] */
" movb %%al, 2(%%edi)\n"
" movb %%al, 3(%%edi)\n"
" addl $4, %%edi\n"
" rep stosb\n"
" movl 44(%%esp), %%ebp\n" /* ebp = lcode */
" jmp .L_while_test\n" " jmp .L_while_test\n"
".align 32,0x90\n"
".L_test_for_second_level_length:\n" ".L_test_for_second_level_length:\n"
" testb $64, %%al\n" " testb $64, %%al\n"
" jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */ " jnz .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
" movl $1, %%eax\n" " xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n" " shll %%cl, %%eax\n"
" decl %%eax\n" " decl %%eax\n"
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" addl 60(%%esp), %%eax\n" /* eax += this.val */ " addl 64(%%esp), %%eax\n" /* eax += len */
" movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/ " movl (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
" jmp .L_dolen\n" " jmp .L_dolen\n"
".align 32,0x90\n"
".L_test_for_second_level_dist:\n" ".L_test_for_second_level_dist:\n"
" testb $64, %%al\n" " testb $64, %%al\n"
" jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */ " jnz .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
" movl $1, %%eax\n" " xorl %%eax, %%eax\n"
" incl %%eax\n"
" shll %%cl, %%eax\n" " shll %%cl, %%eax\n"
" decl %%eax\n" " decl %%eax\n"
" andl %%edx, %%eax\n" /* eax &= hold */ " andl %%edx, %%eax\n" /* eax &= hold */
" addl %%ebp, %%eax\n" /* eax += this.val */ " addl %%ebp, %%eax\n" /* eax += dist */
" movl 48(%%esp), %%ecx\n" /* ecx = dcode */ " movl 36(%%esp), %%ecx\n" /* ecx = dcode */
" movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/ " movl (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
" jmp .L_dodist\n" " jmp .L_dodist\n"
".align 32,0x90\n"
".L_clip_window:\n" ".L_clip_window:\n"
" movl %%eax, %%ecx\n" " movl %%eax, %%ecx\n"
" movl 24(%%esp), %%eax\n" /* prepare for dist compare */ " movl 48(%%esp), %%eax\n" /* eax = wsize */
" negl %%ecx\n" /* nbytes = -nbytes */ " negl %%ecx\n" /* nbytes = -nbytes */
" movl 32(%%esp), %%esi\n" /* from = window */ " movl 28(%%esp), %%esi\n" /* from = window */
" cmpl %%ebp, %%eax\n" " cmpl %%ebp, %%eax\n"
" jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */ " jb .L_invalid_distance_too_far\n" /* if (dist > wsize) */
" addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */ " addl %%ebp, %%ecx\n" /* nbytes = dist - nbytes */
" cmpl $0, 28(%%esp)\n" " cmpl $0, 52(%%esp)\n"
" jne .L_wrap_around_window\n" /* if (write != 0) */ " jne .L_wrap_around_window\n" /* if (write != 0) */
" subl %%ecx, %%eax\n" " subl %%ecx, %%eax\n"
" addl %%eax, %%esi\n" /* from += wsize - nbytes */ " addl %%eax, %%esi\n" /* from += wsize - nbytes */
" movl 60(%%esp), %%eax\n" " movl 64(%%esp), %%eax\n" /* eax = len */
" cmpl %%ecx, %%eax\n"
" jbe .L_do_copy1\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n"
" movl %%edi, %%esi\n"
" subl %%ebp, %%esi\n" /* from = out - dist */
" jmp .L_do_copy1\n"
" cmpl %%ecx, %%eax\n" " cmpl %%ecx, %%eax\n"
" jbe .L_do_copy1\n" /* if (nbytes >= len) */ " jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */ " subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n" " rep movsb\n"
" movl %%edi, %%esi\n" " movl %%edi, %%esi\n"
" subl %%ebp, %%esi\n" /* from = out - dist */ " subl %%ebp, %%esi\n" /* from = out - dist */
" jmp .L_do_copy1\n" " jmp .L_do_copy\n"
".align 32,0x90\n"
".L_wrap_around_window:\n" ".L_wrap_around_window:\n"
" movl 28(%%esp), %%eax\n" " movl 52(%%esp), %%eax\n" /* eax = write */
" cmpl %%eax, %%ecx\n" " cmpl %%eax, %%ecx\n"
" jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */ " jbe .L_contiguous_in_window\n" /* if (write >= nbytes) */
" addl 24(%%esp), %%esi\n" " addl 48(%%esp), %%esi\n" /* from += wsize */
" addl %%eax, %%esi\n" " addl %%eax, %%esi\n" /* from += write */
" subl %%ecx, %%esi\n" /* from += wsize + write - nbytes */ " subl %%ecx, %%esi\n" /* from -= nbytes */
" subl %%eax, %%ecx\n" /* nbytes -= write */ " subl %%eax, %%ecx\n" /* nbytes -= write */
" movl 60(%%esp), %%eax\n" " movl 64(%%esp), %%eax\n" /* eax = len */
" cmpl %%ecx, %%eax\n" " cmpl %%ecx, %%eax\n"
" jbe .L_do_copy1\n" /* if (nbytes >= len) */ " jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */ " subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n" " rep movsb\n"
" movl 32(%%esp), %%esi\n" /* from = window */ " movl 28(%%esp), %%esi\n" /* from = window */
" movl 28(%%esp), %%ecx\n" /* nbytes = write */ " movl 52(%%esp), %%ecx\n" /* nbytes = write */
" cmpl %%ecx, %%eax\n" " cmpl %%ecx, %%eax\n"
" jbe .L_do_copy1\n" /* if (nbytes >= len) */ " jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */ " subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n" " rep movsb\n"
" movl %%edi, %%esi\n" " movl %%edi, %%esi\n"
" subl %%ebp, %%esi\n" /* from = out - dist */ " subl %%ebp, %%esi\n" /* from = out - dist */
" jmp .L_do_copy1\n" " jmp .L_do_copy\n"
".align 32,0x90\n"
".L_contiguous_in_window:\n" ".L_contiguous_in_window:\n"
" addl %%eax, %%esi\n" " addl %%eax, %%esi\n"
" subl %%ecx, %%esi\n" /* from += write - nbytes */ " subl %%ecx, %%esi\n" /* from += write - nbytes */
" movl 60(%%esp), %%eax\n" " movl 64(%%esp), %%eax\n" /* eax = len */
" cmpl %%ecx, %%eax\n" " cmpl %%ecx, %%eax\n"
" jbe .L_do_copy1\n" /* if (nbytes >= len) */ " jbe .L_do_copy\n" /* if (nbytes >= len) */
" subl %%ecx, %%eax\n" /* len -= nbytes */ " subl %%ecx, %%eax\n" /* len -= nbytes */
" rep movsb\n" " rep movsb\n"
" movl %%edi, %%esi\n" " movl %%edi, %%esi\n"
" subl %%ebp, %%esi\n" /* from = out - dist */ " subl %%ebp, %%esi\n" /* from = out - dist */
" jmp .L_do_copy\n" /* if (nbytes >= len) */
".L_do_copy1:\n" ".align 32,0x90\n"
".L_do_copy:\n"
" movl %%eax, %%ecx\n" " movl %%eax, %%ecx\n"
" rep movsb\n" " rep movsb\n"
" movl 4(%%esp), %%esi\n" /* move in back to %esi, toss from */ " movl 8(%%esp), %%esi\n" /* move in back to %esi, toss from */
" movl 44(%%esp), %%ebp\n" /* ebp = lcode */ " movl 32(%%esp), %%ebp\n" /* ebp = lcode */
" jmp .L_while_test\n" " jmp .L_while_test\n"
".L_test_for_end_of_block:\n" ".L_test_for_end_of_block:\n"
" testb $32, %%al\n" " testb $32, %%al\n"
" jz .L_invalid_literal_length_code\n" " jz .L_invalid_literal_length_code\n"
" movl $1, 68(%%esp)\n" " movl $1, 72(%%esp)\n"
" jmp .L_break_loop_with_status\n" " jmp .L_break_loop_with_status\n"
".L_invalid_literal_length_code:\n" ".L_invalid_literal_length_code:\n"
" movl $2, 68(%%esp)\n" " movl $2, 72(%%esp)\n"
" jmp .L_break_loop_with_status\n" " jmp .L_break_loop_with_status\n"
".L_invalid_distance_code:\n" ".L_invalid_distance_code:\n"
" movl $3, 68(%%esp)\n" " movl $3, 72(%%esp)\n"
" jmp .L_break_loop_with_status\n" " jmp .L_break_loop_with_status\n"
".L_invalid_distance_too_far:\n" ".L_invalid_distance_too_far:\n"
" movl 4(%%esp), %%esi\n" " movl 8(%%esp), %%esi\n"
" movl $4, 68(%%esp)\n" " movl $4, 72(%%esp)\n"
" jmp .L_break_loop_with_status\n" " jmp .L_break_loop_with_status\n"
".L_break_loop:\n" ".L_break_loop:\n"
" movl $0, 68(%%esp)\n" " movl $0, 72(%%esp)\n"
".L_break_loop_with_status:\n" ".L_break_loop_with_status:\n"
/* put in, out, bits, and hold back into ar and pop esp */ /* put in, out, bits, and hold back into ar and pop esp */
" movl %%esi, 4(%%esp)\n" " movl %%esi, 8(%%esp)\n" /* save in */
" movl %%edi, 12(%%esp)\n" " movl %%edi, 16(%%esp)\n" /* save out */
" movl %%ebx, 40(%%esp)\n" " movl %%ebx, 44(%%esp)\n" /* save bits */
" movl %%edx, 36(%%esp)\n" " movl %%edx, 40(%%esp)\n" /* save hold */
" movl 4(%%esp), %%ebp\n" /* restore esp, ebp */
" movl (%%esp), %%esp\n" " movl (%%esp), %%esp\n"
" popl %%ebp\n"
" popf\n"
: :
: "m" (ar) : "m" (ar)
: "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi" : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
); );
#elif defined( _MSC_VER ) #elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
__asm { __asm {
lea eax, ar lea eax, ar
pushfd mov [eax], esp /* save esp, ebp */
push ebp mov [eax+4], ebp
mov [eax], esp
mov esp, eax mov esp, eax
mov esi, [esp+4] /* esi = in */ mov esi, [esp+8] /* esi = in */
mov edi, [esp+12] /* edi = out */ mov edi, [esp+16] /* edi = out */
mov edx, [esp+36] /* edx = hold */ mov edx, [esp+40] /* edx = hold */
mov ebx, [esp+40] /* ebx = bits */ mov ebx, [esp+44] /* ebx = bits */
mov ebp, [esp+44] /* ebp = lcode */ mov ebp, [esp+32] /* ebp = lcode */
cld cld
jmp L_do_loop jmp L_do_loop
ALIGN 4
L_while_test: L_while_test:
cmp [esp+20], edi cmp [esp+24], edi
jbe L_break_loop jbe L_break_loop
cmp [esp+8], esi cmp [esp+12], esi
jbe L_break_loop jbe L_break_loop
L_do_loop: L_do_loop:
...@@ -465,7 +828,7 @@ L_do_loop: ...@@ -465,7 +828,7 @@ L_do_loop:
or edx, eax /* hold |= *((ushort *)in)++ << bits */ or edx, eax /* hold |= *((ushort *)in)++ << bits */
L_get_length_code: L_get_length_code:
mov eax, [esp+52] /* eax = lmask */ mov eax, [esp+56] /* eax = lmask */
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */ mov eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
...@@ -481,10 +844,11 @@ L_dolen: ...@@ -481,10 +844,11 @@ L_dolen:
stosb stosb
jmp L_while_test jmp L_while_test
ALIGN 4
L_test_for_length_base: L_test_for_length_base:
mov ecx, eax /* len = this */ mov ecx, eax /* len = this */
shr ecx, 16 /* len = this.val */ shr ecx, 16 /* len = this.val */
mov [esp+60], ecx /* len = this */ mov [esp+64], ecx /* save len */
mov cl, al mov cl, al
test al, 16 test al, 16
...@@ -504,13 +868,14 @@ L_test_for_length_base: ...@@ -504,13 +868,14 @@ L_test_for_length_base:
mov cl, ch /* move op back to ecx */ mov cl, ch /* move op back to ecx */
L_add_bits_to_len: L_add_bits_to_len:
mov eax, 1 sub bl, cl
xor eax, eax
inc eax
shl eax, cl shl eax, cl
dec eax dec eax
sub bl, cl
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
shr edx, cl shr edx, cl
add [esp+60], eax /* len += hold & mask[op] */ add [esp+64], eax /* len += hold & mask[op] */
L_decode_distance: L_decode_distance:
cmp bl, 15 cmp bl, 15
...@@ -524,8 +889,8 @@ L_decode_distance: ...@@ -524,8 +889,8 @@ L_decode_distance:
or edx, eax /* hold |= *((ushort *)in)++ << bits */ or edx, eax /* hold |= *((ushort *)in)++ << bits */
L_get_distance_code: L_get_distance_code:
mov eax, [esp+56] /* eax = dmask */ mov eax, [esp+60] /* eax = dmask */
mov ecx, [esp+48] /* ecx = dcode */ mov ecx, [esp+36] /* ecx = dcode */
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */ mov eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
...@@ -554,200 +919,207 @@ L_dodist: ...@@ -554,200 +919,207 @@ L_dodist:
mov cl, ch /* move op back to ecx */ mov cl, ch /* move op back to ecx */
L_add_bits_to_dist: L_add_bits_to_dist:
mov eax, 1 sub bl, cl
xor eax, eax
inc eax
shl eax, cl shl eax, cl
dec eax /* (1 << op) - 1 */ dec eax /* (1 << op) - 1 */
sub bl, cl
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
shr edx, cl shr edx, cl
add ebp, eax /* dist += hold & ((1 << op) - 1) */ add ebp, eax /* dist += hold & ((1 << op) - 1) */
L_check_window: L_check_window:
mov [esp+4], esi /* save in so from can use it's reg */ mov [esp+8], esi /* save in so from can use it's reg */
mov eax, edi mov eax, edi
sub eax, [esp+16] /* nbytes = out - beg */ sub eax, [esp+20] /* nbytes = out - beg */
cmp eax, ebp cmp eax, ebp
jb L_clip_window /* if (dist > nbytes) 4.2% */ jb L_clip_window /* if (dist > nbytes) 4.2% */
mov ecx, [esp+60] mov ecx, [esp+64] /* ecx = len */
mov esi, edi mov esi, edi
sub esi, ebp /* from = out - dist */ sub esi, ebp /* from = out - dist */
sub ecx, 3 /* copy from to out */ sar ecx, 1
jnc L_copy_two
rep movsw
mov al, [esi] mov al, [esi]
mov [edi], al mov [edi], al
mov al, [esi+1] inc edi
mov ah, [esi+2]
add esi, 3 mov esi, [esp+8] /* move in back to %esi, toss from */
mov [edi+1], al mov ebp, [esp+32] /* ebp = lcode */
mov [edi+2], ah jmp L_while_test
add edi, 3
rep movsb
mov esi, [esp+4] /* move in back to %esi, toss from */ L_copy_two:
mov ebp, [esp+44] /* ebp = lcode */ rep movsw
mov esi, [esp+8] /* move in back to %esi, toss from */
mov ebp, [esp+32] /* ebp = lcode */
jmp L_while_test jmp L_while_test
ALIGN 4
L_check_dist_one: L_check_dist_one:
cmp ebp, 1 /* if dist 1, is a memset */ cmp ebp, 1 /* if dist 1, is a memset */
jne L_check_window jne L_check_window
cmp [esp+16], edi cmp [esp+20], edi
je L_check_window je L_check_window /* out == beg, if outside window */
dec edi mov ecx, [esp+64] /* ecx = len */
mov ecx, [esp+60] mov al, [edi-1]
mov al, [edi] mov ah, al
sub ecx, 3
sar ecx, 1
mov [edi+1], al /* memset out with from[-1] */ jnc L_set_two
mov [edi+2], al mov [edi], al /* memset out with from[-1] */
mov [edi+3], al inc edi
add edi, 4
rep stosb L_set_two:
mov ebp, [esp+44] /* ebp = lcode */ rep stosw
mov ebp, [esp+32] /* ebp = lcode */
jmp L_while_test jmp L_while_test
ALIGN 4
L_test_for_second_level_length: L_test_for_second_level_length:
test al, 64 test al, 64
jnz L_test_for_end_of_block /* if ((op & 64) != 0) */ jnz L_test_for_end_of_block /* if ((op & 64) != 0) */
mov eax, 1 xor eax, eax
inc eax
shl eax, cl shl eax, cl
dec eax dec eax
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
add eax, [esp+60] /* eax += this.val */ add eax, [esp+64] /* eax += len */
mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/ mov eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
jmp L_dolen jmp L_dolen
ALIGN 4
L_test_for_second_level_dist: L_test_for_second_level_dist:
test al, 64 test al, 64
jnz L_invalid_distance_code /* if ((op & 64) != 0) */ jnz L_invalid_distance_code /* if ((op & 64) != 0) */
mov eax, 1 xor eax, eax
inc eax
shl eax, cl shl eax, cl
dec eax dec eax
and eax, edx /* eax &= hold */ and eax, edx /* eax &= hold */
add eax, ebp /* eax += this.val */ add eax, ebp /* eax += dist */
mov ecx, [esp+48] /* ecx = dcode */ mov ecx, [esp+36] /* ecx = dcode */
mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/ mov eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
jmp L_dodist jmp L_dodist
ALIGN 4
L_clip_window: L_clip_window:
mov ecx, eax mov ecx, eax
mov eax, [esp+24] /* prepare for dist compare */ mov eax, [esp+48] /* eax = wsize */
neg ecx /* nbytes = -nbytes */ neg ecx /* nbytes = -nbytes */
mov esi, [esp+32] /* from = window */ mov esi, [esp+28] /* from = window */
cmp eax, ebp cmp eax, ebp
jb L_invalid_distance_too_far /* if (dist > wsize) */ jb L_invalid_distance_too_far /* if (dist > wsize) */
add ecx, ebp /* nbytes = dist - nbytes */ add ecx, ebp /* nbytes = dist - nbytes */
cmp dword ptr [esp+28], 0 cmp dword ptr [esp+52], 0
jne L_wrap_around_window /* if (write != 0) */ jne L_wrap_around_window /* if (write != 0) */
sub eax, ecx sub eax, ecx
add esi, eax /* from += wsize - nbytes */ add esi, eax /* from += wsize - nbytes */
mov eax, [esp+60] mov eax, [esp+64] /* eax = len */
cmp eax, ecx
jbe L_do_copy1 /* if (nbytes >= len) */
sub eax, ecx /* len -= nbytes */
rep movsb
mov esi, edi
sub esi, ebp /* from = out - dist */
jmp L_do_copy1
cmp eax, ecx cmp eax, ecx
jbe L_do_copy1 /* if (nbytes >= len) */ jbe L_do_copy /* if (nbytes >= len) */
sub eax, ecx /* len -= nbytes */ sub eax, ecx /* len -= nbytes */
rep movsb rep movsb
mov esi, edi mov esi, edi
sub esi, ebp /* from = out - dist */ sub esi, ebp /* from = out - dist */
jmp L_do_copy1 jmp L_do_copy
ALIGN 4
L_wrap_around_window: L_wrap_around_window:
mov eax, [esp+28] mov eax, [esp+52] /* eax = write */
cmp ecx, eax cmp ecx, eax
jbe L_contiguous_in_window /* if (write >= nbytes) */ jbe L_contiguous_in_window /* if (write >= nbytes) */
add esi, [esp+24] add esi, [esp+48] /* from += wsize */
add esi, eax add esi, eax /* from += write */
sub esi, ecx /* from += wsize + write - nbytes */ sub esi, ecx /* from -= nbytes */
sub ecx, eax /* nbytes -= write */ sub ecx, eax /* nbytes -= write */
mov eax, [esp+60] mov eax, [esp+64] /* eax = len */
cmp eax, ecx cmp eax, ecx
jbe L_do_copy1 /* if (nbytes >= len) */ jbe L_do_copy /* if (nbytes >= len) */
sub eax, ecx /* len -= nbytes */ sub eax, ecx /* len -= nbytes */
rep movsb rep movsb
mov esi, [esp+32] /* from = window */ mov esi, [esp+28] /* from = window */
mov ecx, [esp+28] /* nbytes = write */ mov ecx, [esp+52] /* nbytes = write */
cmp eax, ecx cmp eax, ecx
jbe L_do_copy1 /* if (nbytes >= len) */ jbe L_do_copy /* if (nbytes >= len) */
sub eax, ecx /* len -= nbytes */ sub eax, ecx /* len -= nbytes */
rep movsb rep movsb
mov esi, edi mov esi, edi
sub esi, ebp /* from = out - dist */ sub esi, ebp /* from = out - dist */
jmp L_do_copy1 jmp L_do_copy
ALIGN 4
L_contiguous_in_window: L_contiguous_in_window:
add esi, eax add esi, eax
sub esi, ecx /* from += write - nbytes */ sub esi, ecx /* from += write - nbytes */
mov eax, [esp+60] mov eax, [esp+64] /* eax = len */
cmp eax, ecx cmp eax, ecx
jbe L_do_copy1 /* if (nbytes >= len) */ jbe L_do_copy /* if (nbytes >= len) */
sub eax, ecx /* len -= nbytes */ sub eax, ecx /* len -= nbytes */
rep movsb rep movsb
mov esi, edi mov esi, edi
sub esi, ebp /* from = out - dist */ sub esi, ebp /* from = out - dist */
jmp L_do_copy
L_do_copy1: ALIGN 4
L_do_copy:
mov ecx, eax mov ecx, eax
rep movsb rep movsb
mov esi, [esp+4] /* move in back to %esi, toss from */ mov esi, [esp+8] /* move in back to %esi, toss from */
mov ebp, [esp+44] /* ebp = lcode */ mov ebp, [esp+32] /* ebp = lcode */
jmp L_while_test jmp L_while_test
L_test_for_end_of_block: L_test_for_end_of_block:
test al, 32 test al, 32
jz L_invalid_literal_length_code jz L_invalid_literal_length_code
mov dword ptr [esp+68], 1 mov dword ptr [esp+72], 1
jmp L_break_loop_with_status jmp L_break_loop_with_status
L_invalid_literal_length_code: L_invalid_literal_length_code:
mov dword ptr [esp+68], 2 mov dword ptr [esp+72], 2
jmp L_break_loop_with_status jmp L_break_loop_with_status
L_invalid_distance_code: L_invalid_distance_code:
mov dword ptr [esp+68], 3 mov dword ptr [esp+72], 3
jmp L_break_loop_with_status jmp L_break_loop_with_status
L_invalid_distance_too_far: L_invalid_distance_too_far:
mov esi, [esp+4] mov esi, [esp+4]
mov dword ptr [esp+68], 4 mov dword ptr [esp+72], 4
jmp L_break_loop_with_status jmp L_break_loop_with_status
L_break_loop: L_break_loop:
mov dword ptr [esp+68], 0 mov dword ptr [esp+72], 0
L_break_loop_with_status: L_break_loop_with_status:
/* put in, out, bits, and hold back into ar and pop esp */ /* put in, out, bits, and hold back into ar and pop esp */
mov [esp+4], esi mov [esp+8], esi /* save in */
mov [esp+12], edi mov [esp+16], edi /* save out */
mov [esp+40], ebx mov [esp+44], ebx /* save bits */
mov [esp+36], edx mov [esp+40], edx /* save hold */
mov ebp, [esp+4] /* restore esp, ebp */
mov esp, [esp] mov esp, [esp]
pop ebp
popfd
} }
#else
#error "x86 architecture not defined"
#endif #endif
if (ar.status > 1) { if (ar.status > 1) {
...@@ -772,10 +1144,12 @@ L_break_loop_with_status: ...@@ -772,10 +1144,12 @@ L_break_loop_with_status:
/* update state and return */ /* update state and return */
strm->next_in = ar.in; strm->next_in = ar.in;
strm->next_out = ar.out; strm->next_out = ar.out;
strm->avail_in = (unsigned)(ar.in < ar.last ? 5 + (ar.last - ar.in) : strm->avail_in = (unsigned)(ar.in < ar.last ?
5 - (ar.in - ar.last)); PAD_AVAIL_IN + (ar.last - ar.in) :
strm->avail_out = (unsigned)(ar.out < ar.end ? 257 + (ar.end - ar.out) : PAD_AVAIL_IN - (ar.in - ar.last));
257 - (ar.out - ar.end)); strm->avail_out = (unsigned)(ar.out < ar.end ?
PAD_AVAIL_OUT + (ar.end - ar.out) :
PAD_AVAIL_OUT - (ar.out - ar.end));
state->hold = ar.hold; state->hold = ar.hold;
state->bits = ar.bits; state->bits = ar.bits;
return; return;
......
...@@ -188,17 +188,8 @@ ...@@ -188,17 +188,8 @@
/* /*
* typedef enum inflate_mode consts, in inflate.h * typedef enum inflate_mode consts, in inflate.h
*/ */
#ifndef NO_GUNZIP
#define GUNZIP
#endif
#ifdef GUNZIP
#define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */ #define INFLATE_MODE_TYPE 11 /* state->mode flags enum-ed in inflate.h */
#define INFLATE_MODE_BAD 26 #define INFLATE_MODE_BAD 26
#else
#define INFLATE_MODE_TYPE 3
#define INFLATE_MODE_BAD 17
#endif
#if ! defined( USE_MMX ) && ! defined( NO_MMX ) #if ! defined( USE_MMX ) && ! defined( NO_MMX )
......
; match.asm -- Pentium-Pro optimized version of longest_match() ; match.asm -- Pentium-Pro optimized version of longest_match()
; ;
; Updated for zlib 1.1.3 and converted to MASM 6.1x ; Updated for zlib 1.1.3 and converted to MASM 6.1x
; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com> ; Copyright (C) 2000 Dan Higdon <hdan@kinesoft.com>
; and Chuck Walbourn <chuckw@kinesoft.com> ; and Chuck Walbourn <chuckw@kinesoft.com>
; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro> ; Corrections by Cosmin Truta <cosmint@cs.ubbcluj.ro>
; ;
; This is free software; you can redistribute it and/or modify it ; This is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License. ; under the terms of the GNU General Public License.
; Based on match.S ; Based on match.S
; Written for zlib 1.1.2 ; Written for zlib 1.1.2
; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> ; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
;
.686P ; Modified by Gilles Vollant (2005) for add gzhead and gzindex
.MODEL FLAT
.686P
;=========================================================================== .MODEL FLAT
; EQUATES
;=========================================================================== ;===========================================================================
; EQUATES
MAX_MATCH EQU 258 ;===========================================================================
MIN_MATCH EQU 3
MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1) MAX_MATCH EQU 258
MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7)) MIN_MATCH EQU 3
MIN_LOOKAHEAD EQU (MAX_MATCH + MIN_MATCH + 1)
;=========================================================================== MAX_MATCH_8 EQU ((MAX_MATCH + 7) AND (NOT 7))
; STRUCTURES
;=========================================================================== ;===========================================================================
; STRUCTURES
; This STRUCT assumes a 4-byte alignment ;===========================================================================
DEFLATE_STATE STRUCT ; This STRUCT assumes a 4-byte alignment
ds_strm dd ?
ds_status dd ? DEFLATE_STATE STRUCT
ds_pending_buf dd ? ds_strm dd ?
ds_pending_buf_size dd ? ds_status dd ?
ds_pending_out dd ? ds_pending_buf dd ?
ds_pending dd ? ds_pending_buf_size dd ?
ds_wrap dd ? ds_pending_out dd ?
ds_data_type db ? ds_pending dd ?
ds_method db ? ds_wrap dd ?
db ? ; padding ; gzhead and gzindex are added in zlib 1.2.2.2 (see deflate.h)
db ? ; padding ds_gzhead dd ?
ds_last_flush dd ? ds_gzindex dd ?
ds_w_size dd ? ; used ds_data_type db ?
ds_w_bits dd ? ds_method db ?
ds_w_mask dd ? ; used db ? ; padding
ds_window dd ? ; used db ? ; padding
ds_window_size dd ? ds_last_flush dd ?
ds_prev dd ? ; used ds_w_size dd ? ; used
ds_head dd ? ds_w_bits dd ?
ds_ins_h dd ? ds_w_mask dd ? ; used
ds_hash_size dd ? ds_window dd ? ; used
ds_hash_bits dd ? ds_window_size dd ?
ds_hash_mask dd ? ds_prev dd ? ; used
ds_hash_shift dd ? ds_head dd ?
ds_block_start dd ? ds_ins_h dd ?
ds_match_length dd ? ; used ds_hash_size dd ?
ds_prev_match dd ? ; used ds_hash_bits dd ?
ds_match_available dd ? ds_hash_mask dd ?
ds_strstart dd ? ; used ds_hash_shift dd ?
ds_match_start dd ? ; used ds_block_start dd ?
ds_lookahead dd ? ; used ds_match_length dd ? ; used
ds_prev_length dd ? ; used ds_prev_match dd ? ; used
ds_max_chain_length dd ? ; used ds_match_available dd ?
ds_max_laxy_match dd ? ds_strstart dd ? ; used
ds_level dd ? ds_match_start dd ? ; used
ds_strategy dd ? ds_lookahead dd ? ; used
ds_good_match dd ? ; used ds_prev_length dd ? ; used
ds_nice_match dd ? ; used ds_max_chain_length dd ? ; used
ds_max_laxy_match dd ?
; Don't need anymore of the struct for match ds_level dd ?
DEFLATE_STATE ENDS ds_strategy dd ?
ds_good_match dd ? ; used
;=========================================================================== ds_nice_match dd ? ; used
; CODE
;=========================================================================== ; Don't need anymore of the struct for match
_TEXT SEGMENT DEFLATE_STATE ENDS
;--------------------------------------------------------------------------- ;===========================================================================
; match_init ; CODE
;--------------------------------------------------------------------------- ;===========================================================================
ALIGN 4 _TEXT SEGMENT
PUBLIC _match_init
_match_init PROC ;---------------------------------------------------------------------------
; no initialization needed ; match_init
ret ;---------------------------------------------------------------------------
_match_init ENDP ALIGN 4
PUBLIC _match_init
;--------------------------------------------------------------------------- _match_init PROC
; uInt longest_match(deflate_state *deflatestate, IPos curmatch) ; no initialization needed
;--------------------------------------------------------------------------- ret
ALIGN 4 _match_init ENDP
PUBLIC _longest_match ;---------------------------------------------------------------------------
_longest_match PROC ; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
;---------------------------------------------------------------------------
; Since this code uses EBP for a scratch register, the stack frame must ALIGN 4
; be manually constructed and referenced relative to the ESP register.
PUBLIC _longest_match
; Stack image _longest_match PROC
; Variables
chainlenwmask = 0 ; high word: current chain len ; Since this code uses EBP for a scratch register, the stack frame must
; low word: s->wmask ; be manually constructed and referenced relative to the ESP register.
window = 4 ; local copy of s->window
windowbestlen = 8 ; s->window + bestlen ; Stack image
scanend = 12 ; last two bytes of string ; Variables
scanstart = 16 ; first two bytes of string chainlenwmask = 0 ; high word: current chain len
scanalign = 20 ; dword-misalignment of string ; low word: s->wmask
nicematch = 24 ; a good enough match size window = 4 ; local copy of s->window
bestlen = 28 ; size of best match so far windowbestlen = 8 ; s->window + bestlen
scan = 32 ; ptr to string wanting match scanend = 12 ; last two bytes of string
varsize = 36 ; number of bytes (also offset to last saved register) scanstart = 16 ; first two bytes of string
scanalign = 20 ; dword-misalignment of string
; Saved Registers (actually pushed into place) nicematch = 24 ; a good enough match size
ebx_save = 36 bestlen = 28 ; size of best match so far
edi_save = 40 scan = 32 ; ptr to string wanting match
esi_save = 44 varsize = 36 ; number of bytes (also offset to last saved register)
ebp_save = 48
; Saved Registers (actually pushed into place)
; Parameters ebx_save = 36
retaddr = 52 edi_save = 40
deflatestate = 56 esi_save = 44
curmatch = 60 ebp_save = 48
; Save registers that the compiler may be using ; Parameters
push ebp retaddr = 52
push edi deflatestate = 56
push esi curmatch = 60
push ebx
; Save registers that the compiler may be using
; Allocate local variable space push ebp
sub esp,varsize push edi
push esi
; Retrieve the function arguments. ecx will hold cur_match push ebx
; throughout the entire function. edx will hold the pointer to the
; deflate_state structure during the function's setup (before ; Allocate local variable space
; entering the main loop). sub esp,varsize
mov edx, [esp+deflatestate] ; Retrieve the function arguments. ecx will hold cur_match
ASSUME edx:PTR DEFLATE_STATE ; throughout the entire function. edx will hold the pointer to the
; deflate_state structure during the function's setup (before
mov ecx, [esp+curmatch] ; entering the main loop).
; uInt wmask = s->w_mask; mov edx, [esp+deflatestate]
; unsigned chain_length = s->max_chain_length; ASSUME edx:PTR DEFLATE_STATE
; if (s->prev_length >= s->good_match) {
; chain_length >>= 2; mov ecx, [esp+curmatch]
; }
; uInt wmask = s->w_mask;
mov eax, [edx].ds_prev_length ; unsigned chain_length = s->max_chain_length;
mov ebx, [edx].ds_good_match ; if (s->prev_length >= s->good_match) {
cmp eax, ebx ; chain_length >>= 2;
mov eax, [edx].ds_w_mask ; }
mov ebx, [edx].ds_max_chain_length
jl SHORT LastMatchGood mov eax, [edx].ds_prev_length
shr ebx, 2 mov ebx, [edx].ds_good_match
LastMatchGood: cmp eax, ebx
mov eax, [edx].ds_w_mask
; chainlen is decremented once beforehand so that the function can mov ebx, [edx].ds_max_chain_length
; use the sign flag instead of the zero flag for the exit test. jl SHORT LastMatchGood
; It is then shifted into the high word, to make room for the wmask shr ebx, 2
; value, which it will always accompany. LastMatchGood:
dec ebx ; chainlen is decremented once beforehand so that the function can
shl ebx, 16 ; use the sign flag instead of the zero flag for the exit test.
or ebx, eax ; It is then shifted into the high word, to make room for the wmask
mov [esp+chainlenwmask], ebx ; value, which it will always accompany.
; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; dec ebx
shl ebx, 16
mov eax, [edx].ds_nice_match or ebx, eax
mov ebx, [edx].ds_lookahead mov [esp+chainlenwmask], ebx
cmp ebx, eax
jl SHORT LookaheadLess ; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
mov ebx, eax
LookaheadLess: mov eax, [edx].ds_nice_match
mov [esp+nicematch], ebx mov ebx, [edx].ds_lookahead
cmp ebx, eax
;/* register Bytef *scan = s->window + s->strstart; */ jl SHORT LookaheadLess
mov ebx, eax
mov esi, [edx].ds_window LookaheadLess:
mov [esp+window], esi mov [esp+nicematch], ebx
mov ebp, [edx].ds_strstart
lea edi, [esi+ebp] ;/* register Bytef *scan = s->window + s->strstart; */
mov [esp+scan],edi
mov esi, [edx].ds_window
;/* Determine how many bytes the scan ptr is off from being */ mov [esp+window], esi
;/* dword-aligned. */ mov ebp, [edx].ds_strstart
lea edi, [esi+ebp]
mov eax, edi mov [esp+scan],edi
neg eax
and eax, 3 ;/* Determine how many bytes the scan ptr is off from being */
mov [esp+scanalign], eax ;/* dword-aligned. */
;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ mov eax, edi
;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ neg eax
and eax, 3
mov eax, [edx].ds_w_size mov [esp+scanalign], eax
sub eax, MIN_LOOKAHEAD
sub ebp, eax ;/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
jg SHORT LimitPositive ;/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
xor ebp, ebp
LimitPositive: mov eax, [edx].ds_w_size
sub eax, MIN_LOOKAHEAD
;/* int best_len = s->prev_length; */ sub ebp, eax
jg SHORT LimitPositive
mov eax, [edx].ds_prev_length xor ebp, ebp
mov [esp+bestlen], eax LimitPositive:
;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ ;/* int best_len = s->prev_length; */
add esi, eax mov eax, [edx].ds_prev_length
mov [esp+windowbestlen], esi mov [esp+bestlen], eax
;/* register ush scan_start = *(ushf*)scan; */ ;/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
;/* Posf *prev = s->prev; */ add esi, eax
mov [esp+windowbestlen], esi
movzx ebx, WORD PTR[edi]
mov [esp+scanstart], ebx ;/* register ush scan_start = *(ushf*)scan; */
movzx ebx, WORD PTR[eax+edi-1] ;/* register ush scan_end = *(ushf*)(scan+best_len-1); */
mov [esp+scanend], ebx ;/* Posf *prev = s->prev; */
mov edi, [edx].ds_prev
movzx ebx, WORD PTR[edi]
;/* Jump into the main loop. */ mov [esp+scanstart], ebx
movzx ebx, WORD PTR[eax+edi-1]
mov edx, [esp+chainlenwmask] mov [esp+scanend], ebx
jmp SHORT LoopEntry mov edi, [edx].ds_prev
;/* do { ;/* Jump into the main loop. */
; * match = s->window + cur_match;
; * if (*(ushf*)(match+best_len-1) != scan_end || mov edx, [esp+chainlenwmask]
; * *(ushf*)match != scan_start) continue; jmp SHORT LoopEntry
; * [...]
; * } while ((cur_match = prev[cur_match & wmask]) > limit ;/* do {
; * && --chain_length != 0); ; * match = s->window + cur_match;
; * ; * if (*(ushf*)(match+best_len-1) != scan_end ||
; * Here is the inner loop of the function. The function will spend the ; * *(ushf*)match != scan_start) continue;
; * majority of its time in this loop, and majority of that time will ; * [...]
; * be spent in the first ten instructions. ; * } while ((cur_match = prev[cur_match & wmask]) > limit
; * ; * && --chain_length != 0);
; * Within this loop: ; *
; * %ebx = scanend ; * Here is the inner loop of the function. The function will spend the
; * %ecx = curmatch ; * majority of its time in this loop, and majority of that time will
; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) ; * be spent in the first ten instructions.
; * %esi = windowbestlen - i.e., (window + bestlen) ; *
; * %edi = prev ; * Within this loop:
; * %ebp = limit ; * %ebx = scanend
; */ ; * %ecx = curmatch
; * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
ALIGN 4 ; * %esi = windowbestlen - i.e., (window + bestlen)
LookupLoop: ; * %edi = prev
and ecx, edx ; * %ebp = limit
movzx ecx, WORD PTR[edi+ecx*2] ; */
cmp ecx, ebp
jbe LeaveNow ALIGN 4
sub edx, 000010000H LookupLoop:
js LeaveNow and ecx, edx
movzx ecx, WORD PTR[edi+ecx*2]
LoopEntry: cmp ecx, ebp
movzx eax, WORD PTR[esi+ecx-1] jbe LeaveNow
cmp eax, ebx sub edx, 000010000H
jnz SHORT LookupLoop js LeaveNow
mov eax, [esp+window] LoopEntry:
movzx eax, WORD PTR[eax+ecx] movzx eax, WORD PTR[esi+ecx-1]
cmp eax, [esp+scanstart] cmp eax, ebx
jnz SHORT LookupLoop jnz SHORT LookupLoop
;/* Store the current value of chainlen. */ mov eax, [esp+window]
movzx eax, WORD PTR[eax+ecx]
mov [esp+chainlenwmask], edx cmp eax, [esp+scanstart]
jnz SHORT LookupLoop
;/* 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 */ ;/* Store the current value of chainlen. */
;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
;/* initialized to -(MAX_MATCH_8 - scanalign). */ mov [esp+chainlenwmask], edx
mov esi, [esp+window] ;/* Point %edi to the string under scrutiny, and %esi to the string we */
mov edi, [esp+scan] ;/* are hoping to match it up with. In actuality, %esi and %edi are */
add esi, ecx ;/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
mov eax, [esp+scanalign] ;/* initialized to -(MAX_MATCH_8 - scanalign). */
mov edx, -MAX_MATCH_8
lea edi, [edi+eax+MAX_MATCH_8] mov esi, [esp+window]
lea esi, [esi+eax+MAX_MATCH_8] mov edi, [esp+scan]
add esi, ecx
;/* Test the strings for equality, 8 bytes at a time. At the end, mov eax, [esp+scanalign]
; * adjust %edx so that it is offset to the exact byte that mismatched. mov edx, -MAX_MATCH_8
; * lea edi, [edi+eax+MAX_MATCH_8]
; * We already know at this point that the first three bytes of the lea esi, [esi+eax+MAX_MATCH_8]
; * 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 ;/* Test the strings for equality, 8 bytes at a time. At the end,
; * bytes, as much as necessary in order to dword-align the %edi ; * adjust %edx so that it is offset to the exact byte that mismatched.
; * pointer. (%esi will still be misaligned three times out of four.) ; *
; * ; * We already know at this point that the first three bytes of the
; * It should be confessed that this loop usually does not represent ; * strings match each other, and they can be safely passed over before
; * much of the total running time. Replacing it with a more ; * starting the compare loop. So what this code does is skip over 0-3
; * straightforward "rep cmpsb" would not drastically degrade ; * bytes, as much as necessary in order to dword-align the %edi
; * performance. ; * pointer. (%esi will still be misaligned three times out of four.)
; */ ; *
; * It should be confessed that this loop usually does not represent
LoopCmps: ; * much of the total running time. Replacing it with a more
mov eax, DWORD PTR[esi+edx] ; * straightforward "rep cmpsb" would not drastically degrade
xor eax, DWORD PTR[edi+edx] ; * performance.
jnz SHORT LeaveLoopCmps ; */
mov eax, DWORD PTR[esi+edx+4] LoopCmps:
xor eax, DWORD PTR[edi+edx+4] mov eax, DWORD PTR[esi+edx]
jnz SHORT LeaveLoopCmps4 xor eax, DWORD PTR[edi+edx]
jnz SHORT LeaveLoopCmps
add edx, 8
jnz SHORT LoopCmps mov eax, DWORD PTR[esi+edx+4]
jmp LenMaximum xor eax, DWORD PTR[edi+edx+4]
ALIGN 4 jnz SHORT LeaveLoopCmps4
LeaveLoopCmps4: add edx, 8
add edx, 4 jnz SHORT LoopCmps
jmp LenMaximum
LeaveLoopCmps: ALIGN 4
test eax, 00000FFFFH
jnz SHORT LenLower LeaveLoopCmps4:
add edx, 4
add edx, 2
shr eax, 16 LeaveLoopCmps:
test eax, 00000FFFFH
LenLower: jnz SHORT LenLower
sub al, 1
adc edx, 0 add edx, 2
shr eax, 16
;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
;/* then automatically accept it as the best possible match and leave. */ LenLower:
sub al, 1
lea eax, [edi+edx] adc edx, 0
mov edi, [esp+scan]
sub eax, edi ;/* Calculate the length of the match. If it is longer than MAX_MATCH, */
cmp eax, MAX_MATCH ;/* then automatically accept it as the best possible match and leave. */
jge SHORT LenMaximum
lea eax, [edi+edx]
;/* If the length of the match is not longer than the best match we */ mov edi, [esp+scan]
;/* have so far, then forget it and return to the lookup loop. */ sub eax, edi
cmp eax, MAX_MATCH
mov edx, [esp+deflatestate] jge SHORT LenMaximum
mov ebx, [esp+bestlen]
cmp eax, ebx ;/* If the length of the match is not longer than the best match we */
jg SHORT LongerMatch ;/* have so far, then forget it and return to the lookup loop. */
mov esi, [esp+windowbestlen]
mov edi, [edx].ds_prev mov edx, [esp+deflatestate]
mov ebx, [esp+scanend] mov ebx, [esp+bestlen]
mov edx, [esp+chainlenwmask] cmp eax, ebx
jmp LookupLoop jg SHORT LongerMatch
ALIGN 4 mov esi, [esp+windowbestlen]
mov edi, [edx].ds_prev
;/* s->match_start = cur_match; */ mov ebx, [esp+scanend]
;/* best_len = len; */ mov edx, [esp+chainlenwmask]
;/* if (len >= nice_match) break; */ jmp LookupLoop
;/* scan_end = *(ushf*)(scan+best_len-1); */ ALIGN 4
LongerMatch: ;/* s->match_start = cur_match; */
mov ebx, [esp+nicematch] ;/* best_len = len; */
mov [esp+bestlen], eax ;/* if (len >= nice_match) break; */
mov [edx].ds_match_start, ecx ;/* scan_end = *(ushf*)(scan+best_len-1); */
cmp eax, ebx
jge SHORT LeaveNow LongerMatch:
mov esi, [esp+window] mov ebx, [esp+nicematch]
add esi, eax mov [esp+bestlen], eax
mov [esp+windowbestlen], esi mov [edx].ds_match_start, ecx
movzx ebx, WORD PTR[edi+eax-1] cmp eax, ebx
mov edi, [edx].ds_prev jge SHORT LeaveNow
mov [esp+scanend], ebx mov esi, [esp+window]
mov edx, [esp+chainlenwmask] add esi, eax
jmp LookupLoop mov [esp+windowbestlen], esi
ALIGN 4 movzx ebx, WORD PTR[edi+eax-1]
mov edi, [edx].ds_prev
;/* Accept the current string, with the maximum possible length. */ mov [esp+scanend], ebx
mov edx, [esp+chainlenwmask]
LenMaximum: jmp LookupLoop
mov edx, [esp+deflatestate] ALIGN 4
mov DWORD PTR[esp+bestlen], MAX_MATCH
mov [edx].ds_match_start, ecx ;/* Accept the current string, with the maximum possible length. */
;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ LenMaximum:
;/* return s->lookahead; */ mov edx, [esp+deflatestate]
mov DWORD PTR[esp+bestlen], MAX_MATCH
LeaveNow: mov [edx].ds_match_start, ecx
mov edx, [esp+deflatestate]
mov ebx, [esp+bestlen] ;/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
mov eax, [edx].ds_lookahead ;/* return s->lookahead; */
cmp ebx, eax
jg SHORT LookaheadRet LeaveNow:
mov eax, ebx mov edx, [esp+deflatestate]
LookaheadRet: mov ebx, [esp+bestlen]
mov eax, [edx].ds_lookahead
; Restore the stack and return from whence we came. cmp ebx, eax
jg SHORT LookaheadRet
add esp, varsize mov eax, ebx
pop ebx LookaheadRet:
pop esi
pop edi ; Restore the stack and return from whence we came.
pop ebp
ret add esp, varsize
pop ebx
_longest_match ENDP pop esi
pop edi
_TEXT ENDS pop ebp
END ret
_longest_match ENDP
_TEXT ENDS
END
; ; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86
; gvmat32.asm -- Asm portion of the optimized longest_match for 32 bits x86 ; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
; Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. ; File written by Gilles Vollant, by modifiying the longest_match
; File written by Gilles Vollant, by modifiying the longest_match ; from Jean-loup Gailly in deflate.c
; from Jean-loup Gailly in deflate.c ;
; It need wmask == 0x7fff ; http://www.zlib.net
; (assembly code is faster with a fixed wmask) ; http://www.winimage.com/zLibDll
; ; http://www.muppetlabs.com/~breadbox/software/assembly.html
; For Visual C++ 4.2 and ML 6.11c (version in directory \MASM611C of Win95 DDK) ;
; I compile with : "ml /coff /Zi /c gvmat32.asm" ; For Visual C++ 4.x and higher and ML 6.x and higher
; ; ml.exe is in directory \MASM611C of Win95 DDK
; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
;uInt longest_match_7fff(s, cur_match) ; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
; deflate_state *s; ;
; IPos cur_match; /* current match */ ; this file contain two implementation of longest_match
;
NbStack equ 76 ; longest_match_7fff : written 1996 by Gilles Vollant optimized for
cur_match equ dword ptr[esp+NbStack-0] ; first Pentium. Assume s->w_mask == 0x7fff
str_s equ dword ptr[esp+NbStack-4] ; longest_match_686 : written by Brian raiter (1998), optimized for Pentium Pro
; 5 dword on top (ret,ebp,esi,edi,ebx) ;
adrret equ dword ptr[esp+NbStack-8] ; for using an seembly version of longest_match, you need define ASMV in project
pushebp equ dword ptr[esp+NbStack-12] ; There is two way in using gvmat32.asm
pushedi equ dword ptr[esp+NbStack-16] ;
pushesi equ dword ptr[esp+NbStack-20] ; A) Suggested method
pushebx equ dword ptr[esp+NbStack-24] ; if you want include both longest_match_7fff and longest_match_686
; compile the asm file running
chain_length equ dword ptr [esp+NbStack-28] ; ml /coff /Zi /Flgvmat32.lst /c gvmat32.asm
limit equ dword ptr [esp+NbStack-32] ; and include gvmat32c.c in your project
best_len equ dword ptr [esp+NbStack-36] ; if you have an old cpu (386,486 or first Pentium) and s->w_mask==0x7fff,
window equ dword ptr [esp+NbStack-40] ; longest_match_7fff will be used
prev equ dword ptr [esp+NbStack-44] ; if you have a more modern CPU (Pentium Pro, II and higher)
scan_start equ word ptr [esp+NbStack-48] ; longest_match_686 will be used
wmask equ dword ptr [esp+NbStack-52] ; on old cpu with s->w_mask!=0x7fff, longest_match_686 will be used,
match_start_ptr equ dword ptr [esp+NbStack-56] ; but this is not a sitation you'll find often
nice_match equ dword ptr [esp+NbStack-60] ;
scan equ dword ptr [esp+NbStack-64] ; B) Alternative
; if you are not interresed in old cpu performance and want the smaller
windowlen equ dword ptr [esp+NbStack-68] ; binaries possible
match_start equ dword ptr [esp+NbStack-72] ;
strend equ dword ptr [esp+NbStack-76] ; compile the asm file running
NbStackAdd equ (NbStack-24) ; ml /coff /Zi /c /Flgvmat32.lst /DNOOLDPENTIUMCODE gvmat32.asm
; and do not include gvmat32c.c in your project (ou define also
.386p ; NOOLDPENTIUMCODE)
;
name gvmatch ; note : as I known, longest_match_686 is very faster than longest_match_7fff
.MODEL FLAT ; on pentium Pro/II/III, faster (but less) in P4, but it seem
; longest_match_7fff can be faster (very very litte) on AMD Athlon64/K8
;
; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
; 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 ;uInt longest_match_7fff(s, cur_match)
; (if you compile with zlib 1.0.4 or older, remove the +4). ; deflate_state *s;
; Note : these value are good with a 8 bytes boundary pack structure ; IPos cur_match; /* current match */
dep_chain_length equ 70h+4
dep_window equ 2ch+4 NbStack equ 76
dep_strstart equ 60h+4 cur_match equ dword ptr[esp+NbStack-0]
dep_prev_length equ 6ch+4 str_s equ dword ptr[esp+NbStack-4]
dep_nice_match equ 84h+4 ; 5 dword on top (ret,ebp,esi,edi,ebx)
dep_w_size equ 20h+4 adrret equ dword ptr[esp+NbStack-8]
dep_prev equ 34h+4 pushebp equ dword ptr[esp+NbStack-12]
dep_w_mask equ 28h+4 pushedi equ dword ptr[esp+NbStack-16]
dep_good_match equ 80h+4 pushesi equ dword ptr[esp+NbStack-20]
dep_match_start equ 64h+4 pushebx equ dword ptr[esp+NbStack-24]
dep_lookahead equ 68h+4
chain_length equ dword ptr [esp+NbStack-28]
limit equ dword ptr [esp+NbStack-32]
_TEXT segment best_len equ dword ptr [esp+NbStack-36]
window equ dword ptr [esp+NbStack-40]
IFDEF NOUNDERLINE prev equ dword ptr [esp+NbStack-44]
public longest_match_7fff scan_start equ word ptr [esp+NbStack-48]
public longest_match_686 wmask equ dword ptr [esp+NbStack-52]
; public match_init match_start_ptr equ dword ptr [esp+NbStack-56]
ELSE nice_match equ dword ptr [esp+NbStack-60]
public _longest_match_7fff scan equ dword ptr [esp+NbStack-64]
public _longest_match_686
; public _match_init windowlen equ dword ptr [esp+NbStack-68]
ENDIF match_start equ dword ptr [esp+NbStack-72]
strend equ dword ptr [esp+NbStack-76]
MAX_MATCH equ 258 NbStackAdd equ (NbStack-24)
MIN_MATCH equ 3
MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) .386p
name gvmatch
.MODEL FLAT
IFDEF NOUNDERLINE
;match_init proc near
; ret
;match_init endp ; all the +zlib1222add offsets are due to the addition of fields
ELSE ; in zlib in the deflate_state structure since the asm code was first written
;_match_init proc near ; (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
; ret ; (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
;_match_init endp ; if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
ENDIF
zlib1222add equ 8
IFDEF NOUNDERLINE ; Note : these value are good with a 8 bytes boundary pack structure
longest_match_7fff proc near dep_chain_length equ 74h+zlib1222add
ELSE dep_window equ 30h+zlib1222add
_longest_match_7fff proc near dep_strstart equ 64h+zlib1222add
ENDIF dep_prev_length equ 70h+zlib1222add
dep_nice_match equ 88h+zlib1222add
mov edx,[esp+4] dep_w_size equ 24h+zlib1222add
dep_prev equ 38h+zlib1222add
dep_w_mask equ 2ch+zlib1222add
dep_good_match equ 84h+zlib1222add
push ebp dep_match_start equ 68h+zlib1222add
push edi dep_lookahead equ 6ch+zlib1222add
push esi
push ebx
_TEXT segment
sub esp,NbStackAdd
IFDEF NOUNDERLINE
; initialize or check the variables used in match.asm. IFDEF NOOLDPENTIUMCODE
mov ebp,edx public longest_match
public match_init
; chain_length = s->max_chain_length ELSE
; if (prev_length>=good_match) chain_length >>= 2 public longest_match_7fff
mov edx,[ebp+dep_chain_length] public cpudetect32
mov ebx,[ebp+dep_prev_length] public longest_match_686
cmp [ebp+dep_good_match],ebx ENDIF
ja noshr ELSE
shr edx,2 IFDEF NOOLDPENTIUMCODE
noshr: public _longest_match
; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop public _match_init
inc edx ELSE
mov edi,[ebp+dep_nice_match] public _longest_match_7fff
mov chain_length,edx public _cpudetect32
mov eax,[ebp+dep_lookahead] public _longest_match_686
cmp eax,edi ENDIF
; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; ENDIF
jae nolookaheadnicematch
mov edi,eax MAX_MATCH equ 258
nolookaheadnicematch: MIN_MATCH equ 3
; best_len = s->prev_length MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1)
mov best_len,ebx
; window = s->window
mov esi,[ebp+dep_window] IFNDEF NOOLDPENTIUMCODE
mov ecx,[ebp+dep_strstart] IFDEF NOUNDERLINE
mov window,esi longest_match_7fff proc near
ELSE
mov nice_match,edi _longest_match_7fff proc near
; scan = window + strstart ENDIF
add esi,ecx
mov scan,esi mov edx,[esp+4]
; dx = *window
mov dx,word ptr [esi]
; bx = *(window+best_len-1)
mov bx,word ptr [esi+ebx-1] push ebp
add esi,MAX_MATCH-1 push edi
; scan_start = *scan push esi
mov scan_start,dx push ebx
; strend = scan + MAX_MATCH-1
mov strend,esi sub esp,NbStackAdd
; bx = scan_end = *(window+best_len-1)
; initialize or check the variables used in match.asm.
; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? mov ebp,edx
; s->strstart - (IPos)MAX_DIST(s) : NIL;
; chain_length = s->max_chain_length
mov esi,[ebp+dep_w_size] ; if (prev_length>=good_match) chain_length >>= 2
sub esi,MIN_LOOKAHEAD mov edx,[ebp+dep_chain_length]
; here esi = MAX_DIST(s) mov ebx,[ebp+dep_prev_length]
sub ecx,esi cmp [ebp+dep_good_match],ebx
ja nodist ja noshr
xor ecx,ecx shr edx,2
nodist: noshr:
mov limit,ecx ; we increment chain_length because in the asm, the --chain_lenght is in the beginning of the loop
inc edx
; prev = s->prev mov edi,[ebp+dep_nice_match]
mov edx,[ebp+dep_prev] mov chain_length,edx
mov prev,edx mov eax,[ebp+dep_lookahead]
cmp eax,edi
; ; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
mov edx,dword ptr [ebp+dep_match_start] jae nolookaheadnicematch
mov bp,scan_start mov edi,eax
mov eax,cur_match nolookaheadnicematch:
mov match_start,edx ; best_len = s->prev_length
mov best_len,ebx
mov edx,window
mov edi,edx ; window = s->window
add edi,best_len mov esi,[ebp+dep_window]
mov esi,prev mov ecx,[ebp+dep_strstart]
dec edi mov window,esi
; windowlen = window + best_len -1
mov windowlen,edi mov nice_match,edi
; scan = window + strstart
jmp beginloop2 add esi,ecx
align 4 mov scan,esi
; dx = *window
; here, in the loop mov dx,word ptr [esi]
; eax = ax = cur_match ; bx = *(window+best_len-1)
; ecx = limit mov bx,word ptr [esi+ebx-1]
; bx = scan_end add esi,MAX_MATCH-1
; bp = scan_start ; scan_start = *scan
; edi = windowlen (window + best_len -1) mov scan_start,dx
; esi = prev ; strend = scan + MAX_MATCH-1
mov strend,esi
; bx = scan_end = *(window+best_len-1)
;// here; chain_length <=16
normalbeg0add16: ; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
add chain_length,16 ; s->strstart - (IPos)MAX_DIST(s) : NIL;
jz exitloop
normalbeg0: mov esi,[ebp+dep_w_size]
cmp word ptr[edi+eax],bx sub esi,MIN_LOOKAHEAD
je normalbeg2noroll ; here esi = MAX_DIST(s)
rcontlabnoroll: sub ecx,esi
; cur_match = prev[cur_match & wmask] ja nodist
and eax,7fffh xor ecx,ecx
mov ax,word ptr[esi+eax*2] nodist:
; if cur_match > limit, go to exitloop mov limit,ecx
cmp ecx,eax
jnb exitloop ; prev = s->prev
; if --chain_length != 0, go to exitloop mov edx,[ebp+dep_prev]
dec chain_length mov prev,edx
jnz normalbeg0
jmp exitloop ;
mov edx,dword ptr [ebp+dep_match_start]
normalbeg2noroll: mov bp,scan_start
; if (scan_start==*(cur_match+window)) goto normalbeg2 mov eax,cur_match
cmp bp,word ptr[edx+eax] mov match_start,edx
jne rcontlabnoroll
jmp normalbeg2 mov edx,window
mov edi,edx
contloop3: add edi,best_len
mov edi,windowlen mov esi,prev
dec edi
; cur_match = prev[cur_match & wmask] ; windowlen = window + best_len -1
and eax,7fffh mov windowlen,edi
mov ax,word ptr[esi+eax*2]
; if cur_match > limit, go to exitloop jmp beginloop2
cmp ecx,eax align 4
jnbexitloopshort1:
jnb exitloop ; here, in the loop
; if --chain_length != 0, go to exitloop ; eax = ax = cur_match
; ecx = limit
; bx = scan_end
; begin the main loop ; bp = scan_start
beginloop2: ; edi = windowlen (window + best_len -1)
sub chain_length,16+1 ; esi = prev
; if chain_length <=16, don't use the unrolled loop
jna normalbeg0add16
;// here; chain_length <=16
do16: normalbeg0add16:
cmp word ptr[edi+eax],bx add chain_length,16
je normalbeg2dc0 jz exitloop
normalbeg0:
maccn MACRO lab cmp word ptr[edi+eax],bx
and eax,7fffh je normalbeg2noroll
mov ax,word ptr[esi+eax*2] rcontlabnoroll:
cmp ecx,eax ; cur_match = prev[cur_match & wmask]
jnb exitloop and eax,7fffh
cmp word ptr[edi+eax],bx mov ax,word ptr[esi+eax*2]
je lab ; if cur_match > limit, go to exitloop
ENDM cmp ecx,eax
jnb exitloop
rcontloop0: ; if --chain_length != 0, go to exitloop
maccn normalbeg2dc1 dec chain_length
jnz normalbeg0
rcontloop1: jmp exitloop
maccn normalbeg2dc2
normalbeg2noroll:
rcontloop2: ; if (scan_start==*(cur_match+window)) goto normalbeg2
maccn normalbeg2dc3 cmp bp,word ptr[edx+eax]
jne rcontlabnoroll
rcontloop3: jmp normalbeg2
maccn normalbeg2dc4
contloop3:
rcontloop4: mov edi,windowlen
maccn normalbeg2dc5
; cur_match = prev[cur_match & wmask]
rcontloop5: and eax,7fffh
maccn normalbeg2dc6 mov ax,word ptr[esi+eax*2]
; if cur_match > limit, go to exitloop
rcontloop6: cmp ecx,eax
maccn normalbeg2dc7 jnbexitloopshort1:
jnb exitloop
rcontloop7: ; if --chain_length != 0, go to exitloop
maccn normalbeg2dc8
rcontloop8: ; begin the main loop
maccn normalbeg2dc9 beginloop2:
sub chain_length,16+1
rcontloop9: ; if chain_length <=16, don't use the unrolled loop
maccn normalbeg2dc10 jna normalbeg0add16
rcontloop10: do16:
maccn short normalbeg2dc11 cmp word ptr[edi+eax],bx
je normalbeg2dc0
rcontloop11:
maccn short normalbeg2dc12 maccn MACRO lab
and eax,7fffh
rcontloop12: mov ax,word ptr[esi+eax*2]
maccn short normalbeg2dc13 cmp ecx,eax
jnb exitloop
rcontloop13: cmp word ptr[edi+eax],bx
maccn short normalbeg2dc14 je lab
ENDM
rcontloop14:
maccn short normalbeg2dc15 rcontloop0:
maccn normalbeg2dc1
rcontloop15:
and eax,7fffh rcontloop1:
mov ax,word ptr[esi+eax*2] maccn normalbeg2dc2
cmp ecx,eax
jnb exitloop rcontloop2:
maccn normalbeg2dc3
sub chain_length,16
ja do16 rcontloop3:
jmp normalbeg0add16 maccn normalbeg2dc4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; rcontloop4:
maccn normalbeg2dc5
normbeg MACRO rcontlab,valsub
; if we are here, we know that *(match+best_len-1) == scan_end rcontloop5:
cmp bp,word ptr[edx+eax] maccn normalbeg2dc6
; if (match != scan_start) goto rcontlab
jne rcontlab rcontloop6:
; calculate the good chain_length, and we'll compare scan and match string maccn normalbeg2dc7
add chain_length,16-valsub
jmp iseq rcontloop7:
ENDM maccn normalbeg2dc8
rcontloop8:
normalbeg2dc11: maccn normalbeg2dc9
normbeg rcontloop11,11
rcontloop9:
normalbeg2dc12: maccn normalbeg2dc10
normbeg short rcontloop12,12
rcontloop10:
normalbeg2dc13: maccn short normalbeg2dc11
normbeg short rcontloop13,13
rcontloop11:
normalbeg2dc14: maccn short normalbeg2dc12
normbeg short rcontloop14,14
rcontloop12:
normalbeg2dc15: maccn short normalbeg2dc13
normbeg short rcontloop15,15
rcontloop13:
normalbeg2dc10: maccn short normalbeg2dc14
normbeg rcontloop10,10
rcontloop14:
normalbeg2dc9: maccn short normalbeg2dc15
normbeg rcontloop9,9
rcontloop15:
normalbeg2dc8: and eax,7fffh
normbeg rcontloop8,8 mov ax,word ptr[esi+eax*2]
cmp ecx,eax
normalbeg2dc7: jnb exitloop
normbeg rcontloop7,7
sub chain_length,16
normalbeg2dc6: ja do16
normbeg rcontloop6,6 jmp normalbeg0add16
normalbeg2dc5: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
normbeg rcontloop5,5
normbeg MACRO rcontlab,valsub
normalbeg2dc4: ; if we are here, we know that *(match+best_len-1) == scan_end
normbeg rcontloop4,4 cmp bp,word ptr[edx+eax]
; if (match != scan_start) goto rcontlab
normalbeg2dc3: jne rcontlab
normbeg rcontloop3,3 ; calculate the good chain_length, and we'll compare scan and match string
add chain_length,16-valsub
normalbeg2dc2: jmp iseq
normbeg rcontloop2,2 ENDM
normalbeg2dc1:
normbeg rcontloop1,1 normalbeg2dc11:
normbeg rcontloop11,11
normalbeg2dc0:
normbeg rcontloop0,0 normalbeg2dc12:
normbeg short rcontloop12,12
; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end normalbeg2dc13:
normbeg short rcontloop13,13
normalbeg2:
mov edi,window normalbeg2dc14:
normbeg short rcontloop14,14
cmp bp,word ptr[edi+eax]
jne contloop3 ; if *(ushf*)match != scan_start, continue normalbeg2dc15:
normbeg short rcontloop15,15
iseq:
; if we are here, we know that *(match+best_len-1) == scan_end normalbeg2dc10:
; and (match == scan_start) normbeg rcontloop10,10
mov edi,edx normalbeg2dc9:
mov esi,scan ; esi = scan normbeg rcontloop9,9
add edi,eax ; edi = window + cur_match = match
normalbeg2dc8:
mov edx,[esi+3] ; compare manually dword at match+3 normbeg rcontloop8,8
xor edx,[edi+3] ; and scan +3
normalbeg2dc7:
jz begincompare ; if equal, go to long compare normbeg rcontloop7,7
; we will determine the unmatch byte and calculate len (in esi) normalbeg2dc6:
or dl,dl normbeg rcontloop6,6
je eq1rr
mov esi,3 normalbeg2dc5:
jmp trfinval normbeg rcontloop5,5
eq1rr:
or dx,dx normalbeg2dc4:
je eq1 normbeg rcontloop4,4
mov esi,4 normalbeg2dc3:
jmp trfinval normbeg rcontloop3,3
eq1:
and edx,0ffffffh normalbeg2dc2:
jz eq11 normbeg rcontloop2,2
mov esi,5
jmp trfinval normalbeg2dc1:
eq11: normbeg rcontloop1,1
mov esi,6
jmp trfinval normalbeg2dc0:
normbeg rcontloop0,0
begincompare:
; here we now scan and match begin same
add edi,6 ; we go in normalbeg2 because *(ushf*)(match+best_len-1) == scan_end
add esi,6
mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes normalbeg2:
repe cmpsd ; loop until mismatch mov edi,window
je trfin ; go to trfin if not unmatch cmp bp,word ptr[edi+eax]
; we determine the unmatch byte jne contloop3 ; if *(ushf*)match != scan_start, continue
sub esi,4
mov edx,[edi-4] iseq:
xor edx,[esi] ; if we are here, we know that *(match+best_len-1) == scan_end
; and (match == scan_start)
or dl,dl
jnz trfin mov edi,edx
inc esi mov esi,scan ; esi = scan
add edi,eax ; edi = window + cur_match = match
or dx,dx
jnz trfin mov edx,[esi+3] ; compare manually dword at match+3
inc esi xor edx,[edi+3] ; and scan +3
and edx,0ffffffh jz begincompare ; if equal, go to long compare
jnz trfin
inc esi ; we will determine the unmatch byte and calculate len (in esi)
or dl,dl
trfin: je eq1rr
sub esi,scan ; esi = len mov esi,3
trfinval: jmp trfinval
; here we have finised compare, and esi contain len of equal string eq1rr:
cmp esi,best_len ; if len > best_len, go newbestlen or dx,dx
ja short newbestlen je eq1
; now we restore edx, ecx and esi, for the big loop
mov esi,prev mov esi,4
mov ecx,limit jmp trfinval
mov edx,window eq1:
jmp contloop3 and edx,0ffffffh
jz eq11
newbestlen: mov esi,5
mov best_len,esi ; len become best_len jmp trfinval
eq11:
mov match_start,eax ; save new position as match_start mov esi,6
cmp esi,nice_match ; if best_len >= nice_match, exit jmp trfinval
jae exitloop
mov ecx,scan begincompare:
mov edx,window ; restore edx=window ; here we now scan and match begin same
add ecx,esi add edi,6
add esi,edx add esi,6
mov ecx,(MAX_MATCH-(2+4))/4 ; scan for at most MAX_MATCH bytes
dec esi repe cmpsd ; loop until mismatch
mov windowlen,esi ; windowlen = window + best_len-1
mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end je trfin ; go to trfin if not unmatch
; we determine the unmatch byte
; now we restore ecx and esi, for the big loop : sub esi,4
mov esi,prev mov edx,[edi-4]
mov ecx,limit xor edx,[esi]
jmp contloop3
or dl,dl
exitloop: jnz trfin
; exit : s->match_start=match_start inc esi
mov ebx,match_start
mov ebp,str_s or dx,dx
mov ecx,best_len jnz trfin
mov dword ptr [ebp+dep_match_start],ebx inc esi
mov eax,dword ptr [ebp+dep_lookahead]
cmp ecx,eax and edx,0ffffffh
ja minexlo jnz trfin
mov eax,ecx inc esi
minexlo:
; return min(best_len,s->lookahead) trfin:
sub esi,scan ; esi = len
; restore stack and register ebx,esi,edi,ebp trfinval:
add esp,NbStackAdd ; here we have finised compare, and esi contain len of equal string
cmp esi,best_len ; if len > best_len, go newbestlen
pop ebx ja short newbestlen
pop esi ; now we restore edx, ecx and esi, for the big loop
pop edi mov esi,prev
pop ebp mov ecx,limit
ret mov edx,window
InfoAuthor: jmp contloop3
; please don't remove this string !
; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary! newbestlen:
db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah mov best_len,esi ; len become best_len
mov match_start,eax ; save new position as match_start
cmp esi,nice_match ; if best_len >= nice_match, exit
IFDEF NOUNDERLINE jae exitloop
longest_match_7fff endp mov ecx,scan
ELSE mov edx,window ; restore edx=window
_longest_match_7fff endp add ecx,esi
ENDIF add esi,edx
dec esi
IFDEF NOUNDERLINE mov windowlen,esi ; windowlen = window + best_len-1
cpudetect32 proc near mov bx,[ecx-1] ; bx = *(scan+best_len-1) = scan_end
ELSE
_cpudetect32 proc near ; now we restore ecx and esi, for the big loop :
ENDIF mov esi,prev
mov ecx,limit
push ebx jmp contloop3
pushfd ; push original EFLAGS exitloop:
pop eax ; get original EFLAGS ; exit : s->match_start=match_start
mov ecx, eax ; save original EFLAGS mov ebx,match_start
xor eax, 40000h ; flip AC bit in EFLAGS mov ebp,str_s
push eax ; save new EFLAGS value on stack mov ecx,best_len
popfd ; replace current EFLAGS value mov dword ptr [ebp+dep_match_start],ebx
pushfd ; get new EFLAGS mov eax,dword ptr [ebp+dep_lookahead]
pop eax ; store new EFLAGS in EAX cmp ecx,eax
xor eax, ecx ; cant toggle AC bit, processor=80386 ja minexlo
jz end_cpu_is_386 ; jump if 80386 processor mov eax,ecx
push ecx minexlo:
popfd ; restore AC bit in EFLAGS first ; return min(best_len,s->lookahead)
pushfd ; restore stack and register ebx,esi,edi,ebp
pushfd add esp,NbStackAdd
pop ecx
pop ebx
mov eax, ecx ; get original EFLAGS pop esi
xor eax, 200000h ; flip ID bit in EFLAGS pop edi
push eax ; save new EFLAGS value on stack pop ebp
popfd ; replace current EFLAGS value ret
pushfd ; get new EFLAGS InfoAuthor:
pop eax ; store new EFLAGS in EAX ; please don't remove this string !
popfd ; restore original EFLAGS ; Your are free use gvmat32 in any fre or commercial apps if you don't remove the string in the binary!
xor eax, ecx ; cant toggle ID bit, db 0dh,0ah,"GVMat32 optimised assembly code written 1996-98 by Gilles Vollant",0dh,0ah
je is_old_486 ; processor=old
mov eax,1
db 0fh,0a2h ;CPUID IFDEF NOUNDERLINE
longest_match_7fff endp
exitcpudetect: ELSE
pop ebx _longest_match_7fff endp
ret ENDIF
end_cpu_is_386:
mov eax,0300h IFDEF NOUNDERLINE
jmp exitcpudetect cpudetect32 proc near
ELSE
is_old_486: _cpudetect32 proc near
mov eax,0400h ENDIF
jmp exitcpudetect
push ebx
IFDEF NOUNDERLINE
cpudetect32 endp pushfd ; push original EFLAGS
ELSE pop eax ; get original EFLAGS
_cpudetect32 endp mov ecx, eax ; save original EFLAGS
ENDIF xor eax, 40000h ; flip AC bit in EFLAGS
push eax ; save new EFLAGS value on stack
popfd ; replace current EFLAGS value
pushfd ; get new EFLAGS
pop eax ; store new EFLAGS in EAX
MAX_MATCH equ 258 xor eax, ecx ; cant toggle AC bit, processor=80386
MIN_MATCH equ 3 jz end_cpu_is_386 ; jump if 80386 processor
MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1) push ecx
MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h) popfd ; restore AC bit in EFLAGS first
pushfd
;;; stack frame offsets pushfd
pop ecx
chainlenwmask equ esp + 0 ; high word: current chain len
; low word: s->wmask mov eax, ecx ; get original EFLAGS
window equ esp + 4 ; local copy of s->window xor eax, 200000h ; flip ID bit in EFLAGS
windowbestlen equ esp + 8 ; s->window + bestlen push eax ; save new EFLAGS value on stack
scanstart equ esp + 16 ; first two bytes of string popfd ; replace current EFLAGS value
scanend equ esp + 12 ; last two bytes of string pushfd ; get new EFLAGS
scanalign equ esp + 20 ; dword-misalignment of string pop eax ; store new EFLAGS in EAX
nicematch equ esp + 24 ; a good enough match size popfd ; restore original EFLAGS
bestlen equ esp + 28 ; size of best match so far xor eax, ecx ; cant toggle ID bit,
scan equ esp + 32 ; ptr to string wanting match je is_old_486 ; processor=old
LocalVarsSize equ 36 mov eax,1
; saved ebx byte esp + 36 db 0fh,0a2h ;CPUID
; saved edi byte esp + 40
; saved esi byte esp + 44 exitcpudetect:
; saved ebp byte esp + 48 pop ebx
; return address byte esp + 52 ret
deflatestate equ esp + 56 ; the function arguments
curmatch equ esp + 60 end_cpu_is_386:
mov eax,0300h
;;; Offsets for fields in the deflate_state structure. These numbers jmp exitcpudetect
;;; are calculated from the definition of deflate_state, with the
;;; assumption that the compiler will dword-align the fields. (Thus, is_old_486:
;;; changing the definition of deflate_state could easily cause this mov eax,0400h
;;; program to crash horribly, without so much as a warning at jmp exitcpudetect
;;; compile time. Sigh.)
IFDEF NOUNDERLINE
dsWSize equ 36 cpudetect32 endp
dsWMask equ 44 ELSE
dsWindow equ 48 _cpudetect32 endp
dsPrev equ 56 ENDIF
dsMatchLen equ 88 ENDIF
dsPrevMatch equ 92
dsStrStart equ 100 MAX_MATCH equ 258
dsMatchStart equ 104 MIN_MATCH equ 3
dsLookahead equ 108 MIN_LOOKAHEAD equ (MAX_MATCH + MIN_MATCH + 1)
dsPrevLen equ 112 MAX_MATCH_8_ equ ((MAX_MATCH + 7) AND 0FFF0h)
dsMaxChainLen equ 116
dsGoodMatch equ 132
dsNiceMatch equ 136 ;;; stack frame offsets
chainlenwmask equ esp + 0 ; high word: current chain len
;;; match.asm -- Pentium-Pro-optimized version of longest_match() ; low word: s->wmask
;;; Written for zlib 1.1.2 window equ esp + 4 ; local copy of s->window
;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com> windowbestlen equ esp + 8 ; s->window + bestlen
;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html scanstart equ esp + 16 ; first two bytes of string
;;; scanend equ esp + 12 ; last two bytes of string
;;; This is free software; you can redistribute it and/or modify it scanalign equ esp + 20 ; dword-misalignment of string
;;; under the terms of the GNU General Public License. nicematch equ esp + 24 ; a good enough match size
bestlen equ esp + 28 ; size of best match so far
;GLOBAL _longest_match, _match_init scan equ esp + 32 ; ptr to string wanting match
LocalVarsSize equ 36
;SECTION .text ; saved ebx byte esp + 36
; saved edi byte esp + 40
;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch) ; saved esi byte esp + 44
; saved ebp byte esp + 48
;_longest_match: ; return address byte esp + 52
IFDEF NOUNDERLINE deflatestate equ esp + 56 ; the function arguments
longest_match_686 proc near curmatch equ esp + 60
ELSE
_longest_match_686 proc near ;;; Offsets for fields in the deflate_state structure. These numbers
ENDIF ;;; 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
;;; Save registers that the compiler may be using, and adjust esp to ;;; program to crash horribly, without so much as a warning at
;;; make room for our stack frame. ;;; compile time. Sigh.)
push ebp dsWSize equ 36+zlib1222add
push edi dsWMask equ 44+zlib1222add
push esi dsWindow equ 48+zlib1222add
push ebx dsPrev equ 56+zlib1222add
sub esp, LocalVarsSize dsMatchLen equ 88+zlib1222add
dsPrevMatch equ 92+zlib1222add
;;; Retrieve the function arguments. ecx will hold cur_match dsStrStart equ 100+zlib1222add
;;; throughout the entire function. edx will hold the pointer to the dsMatchStart equ 104+zlib1222add
;;; deflate_state structure during the function's setup (before dsLookahead equ 108+zlib1222add
;;; entering the main loop. dsPrevLen equ 112+zlib1222add
dsMaxChainLen equ 116+zlib1222add
mov edx, [deflatestate] dsGoodMatch equ 132+zlib1222add
mov ecx, [curmatch] dsNiceMatch equ 136+zlib1222add
;;; uInt wmask = s->w_mask;
;;; unsigned chain_length = s->max_chain_length; ;;; match.asm -- Pentium-Pro-optimized version of longest_match()
;;; if (s->prev_length >= s->good_match) { ;;; Written for zlib 1.1.2
;;; chain_length >>= 2; ;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
;;; } ;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
;;;
mov eax, [edx + dsPrevLen] ;;; This is free software; you can redistribute it and/or modify it
mov ebx, [edx + dsGoodMatch] ;;; under the terms of the GNU General Public License.
cmp eax, ebx
mov eax, [edx + dsWMask] ;GLOBAL _longest_match, _match_init
mov ebx, [edx + dsMaxChainLen]
jl LastMatchGood
shr ebx, 2 ;SECTION .text
LastMatchGood:
;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
;;; chainlen is decremented once beforehand so that the function can
;;; use the sign flag instead of the zero flag for the exit test. ;_longest_match:
;;; It is then shifted into the high word, to make room for the wmask IFDEF NOOLDPENTIUMCODE
;;; value, which it will always accompany. IFDEF NOUNDERLINE
longest_match proc near
dec ebx ELSE
shl ebx, 16 _longest_match proc near
or ebx, eax ENDIF
mov [chainlenwmask], ebx ELSE
IFDEF NOUNDERLINE
;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; longest_match_686 proc near
ELSE
mov eax, [edx + dsNiceMatch] _longest_match_686 proc near
mov ebx, [edx + dsLookahead] ENDIF
cmp ebx, eax ENDIF
jl LookaheadLess
mov ebx, eax ;;; Save registers that the compiler may be using, and adjust esp to
LookaheadLess: mov [nicematch], ebx ;;; make room for our stack frame.
;;; register Bytef *scan = s->window + s->strstart; push ebp
push edi
mov esi, [edx + dsWindow] push esi
mov [window], esi push ebx
mov ebp, [edx + dsStrStart] sub esp, LocalVarsSize
lea edi, [esi + ebp]
mov [scan], edi ;;; Retrieve the function arguments. ecx will hold cur_match
;;; throughout the entire function. edx will hold the pointer to the
;;; Determine how many bytes the scan ptr is off from being ;;; deflate_state structure during the function's setup (before
;;; dword-aligned. ;;; entering the main loop.
mov eax, edi mov edx, [deflatestate]
neg eax mov ecx, [curmatch]
and eax, 3
mov [scanalign], eax ;;; uInt wmask = s->w_mask;
;;; unsigned chain_length = s->max_chain_length;
;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ? ;;; if (s->prev_length >= s->good_match) {
;;; s->strstart - (IPos)MAX_DIST(s) : NIL; ;;; chain_length >>= 2;
;;; }
mov eax, [edx + dsWSize]
sub eax, MIN_LOOKAHEAD mov eax, [edx + dsPrevLen]
sub ebp, eax mov ebx, [edx + dsGoodMatch]
jg LimitPositive cmp eax, ebx
xor ebp, ebp mov eax, [edx + dsWMask]
LimitPositive: mov ebx, [edx + dsMaxChainLen]
jl LastMatchGood
;;; int best_len = s->prev_length; shr ebx, 2
LastMatchGood:
mov eax, [edx + dsPrevLen]
mov [bestlen], eax ;;; chainlen is decremented once beforehand so that the function can
;;; use the sign flag instead of the zero flag for the exit test.
;;; Store the sum of s->window + best_len in esi locally, and in esi. ;;; It is then shifted into the high word, to make room for the wmask
;;; value, which it will always accompany.
add esi, eax
mov [windowbestlen], esi dec ebx
shl ebx, 16
;;; register ush scan_start = *(ushf*)scan; or ebx, eax
;;; register ush scan_end = *(ushf*)(scan+best_len-1); mov [chainlenwmask], ebx
;;; Posf *prev = s->prev;
;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
movzx ebx, word ptr [edi]
mov [scanstart], ebx mov eax, [edx + dsNiceMatch]
movzx ebx, word ptr [edi + eax - 1] mov ebx, [edx + dsLookahead]
mov [scanend], ebx cmp ebx, eax
mov edi, [edx + dsPrev] jl LookaheadLess
mov ebx, eax
;;; Jump into the main loop. LookaheadLess: mov [nicematch], ebx
mov edx, [chainlenwmask] ;;; register Bytef *scan = s->window + s->strstart;
jmp short LoopEntry
mov esi, [edx + dsWindow]
align 4 mov [window], esi
mov ebp, [edx + dsStrStart]
;;; do { lea edi, [esi + ebp]
;;; match = s->window + cur_match; mov [scan], edi
;;; if (*(ushf*)(match+best_len-1) != scan_end ||
;;; *(ushf*)match != scan_start) continue; ;;; Determine how many bytes the scan ptr is off from being
;;; [...] ;;; dword-aligned.
;;; } while ((cur_match = prev[cur_match & wmask]) > limit
;;; && --chain_length != 0); mov eax, edi
;;; neg eax
;;; Here is the inner loop of the function. The function will spend the and eax, 3
;;; majority of its time in this loop, and majority of that time will mov [scanalign], eax
;;; be spent in the first ten instructions.
;;; ;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
;;; Within this loop: ;;; s->strstart - (IPos)MAX_DIST(s) : NIL;
;;; ebx = scanend
;;; ecx = curmatch mov eax, [edx + dsWSize]
;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) sub eax, MIN_LOOKAHEAD
;;; esi = windowbestlen - i.e., (window + bestlen) sub ebp, eax
;;; edi = prev jg LimitPositive
;;; ebp = limit xor ebp, ebp
LimitPositive:
LookupLoop:
and ecx, edx ;;; int best_len = s->prev_length;
movzx ecx, word ptr [edi + ecx*2]
cmp ecx, ebp mov eax, [edx + dsPrevLen]
jbe LeaveNow mov [bestlen], eax
sub edx, 00010000h
js LeaveNow ;;; Store the sum of s->window + best_len in esi locally, and in esi.
LoopEntry: movzx eax, word ptr [esi + ecx - 1]
cmp eax, ebx add esi, eax
jnz LookupLoop mov [windowbestlen], esi
mov eax, [window]
movzx eax, word ptr [eax + ecx] ;;; register ush scan_start = *(ushf*)scan;
cmp eax, [scanstart] ;;; register ush scan_end = *(ushf*)(scan+best_len-1);
jnz LookupLoop ;;; Posf *prev = s->prev;
;;; Store the current value of chainlen. movzx ebx, word ptr [edi]
mov [scanstart], ebx
mov [chainlenwmask], edx movzx ebx, word ptr [edi + eax - 1]
mov [scanend], ebx
;;; Point edi to the string under scrutiny, and esi to the string we mov edi, [edx + dsPrev]
;;; are hoping to match it up with. In actuality, esi and edi are
;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is ;;; Jump into the main loop.
;;; initialized to -(MAX_MATCH_8 - scanalign).
mov edx, [chainlenwmask]
mov esi, [window] jmp short LoopEntry
mov edi, [scan]
add esi, ecx align 4
mov eax, [scanalign]
mov edx, 0fffffef8h; -(MAX_MATCH_8) ;;; do {
lea edi, [edi + eax + 0108h] ;MAX_MATCH_8] ;;; match = s->window + cur_match;
lea esi, [esi + eax + 0108h] ;MAX_MATCH_8] ;;; if (*(ushf*)(match+best_len-1) != scan_end ||
;;; *(ushf*)match != scan_start) continue;
;;; Test the strings for equality, 8 bytes at a time. At the end, ;;; [...]
;;; adjust edx so that it is offset to the exact byte that mismatched. ;;; } while ((cur_match = prev[cur_match & wmask]) > limit
;;; ;;; && --chain_length != 0);
;;; 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 ;;; Here is the inner loop of the function. The function will spend the
;;; starting the compare loop. So what this code does is skip over 0-3 ;;; majority of its time in this loop, and majority of that time will
;;; bytes, as much as necessary in order to dword-align the edi ;;; be spent in the first ten instructions.
;;; pointer. (esi will still be misaligned three times out of four.) ;;;
;;; ;;; Within this loop:
;;; It should be confessed that this loop usually does not represent ;;; ebx = scanend
;;; much of the total running time. Replacing it with a more ;;; ecx = curmatch
;;; straightforward "rep cmpsb" would not drastically degrade ;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
;;; performance. ;;; esi = windowbestlen - i.e., (window + bestlen)
;;; edi = prev
LoopCmps: ;;; ebp = limit
mov eax, [esi + edx]
xor eax, [edi + edx] LookupLoop:
jnz LeaveLoopCmps and ecx, edx
mov eax, [esi + edx + 4] movzx ecx, word ptr [edi + ecx*2]
xor eax, [edi + edx + 4] cmp ecx, ebp
jnz LeaveLoopCmps4 jbe LeaveNow
add edx, 8 sub edx, 00010000h
jnz LoopCmps js LeaveNow
jmp short LenMaximum LoopEntry: movzx eax, word ptr [esi + ecx - 1]
LeaveLoopCmps4: add edx, 4 cmp eax, ebx
LeaveLoopCmps: test eax, 0000FFFFh jnz LookupLoop
jnz LenLower mov eax, [window]
add edx, 2 movzx eax, word ptr [eax + ecx]
shr eax, 16 cmp eax, [scanstart]
LenLower: sub al, 1 jnz LookupLoop
adc edx, 0
;;; Store the current value of chainlen.
;;; Calculate the length of the match. If it is longer than MAX_MATCH,
;;; then automatically accept it as the best possible match and leave. mov [chainlenwmask], edx
lea eax, [edi + edx] ;;; Point edi to the string under scrutiny, and esi to the string we
mov edi, [scan] ;;; are hoping to match it up with. In actuality, esi and edi are
sub eax, edi ;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
cmp eax, MAX_MATCH ;;; initialized to -(MAX_MATCH_8 - scanalign).
jge LenMaximum
mov esi, [window]
;;; If the length of the match is not longer than the best match we mov edi, [scan]
;;; have so far, then forget it and return to the lookup loop. add esi, ecx
mov eax, [scanalign]
mov edx, [deflatestate] mov edx, 0fffffef8h; -(MAX_MATCH_8)
mov ebx, [bestlen] lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
cmp eax, ebx lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
jg LongerMatch
mov esi, [windowbestlen] ;;; Test the strings for equality, 8 bytes at a time. At the end,
mov edi, [edx + dsPrev] ;;; adjust edx so that it is offset to the exact byte that mismatched.
mov ebx, [scanend] ;;;
mov edx, [chainlenwmask] ;;; We already know at this point that the first three bytes of the
jmp LookupLoop ;;; 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
;;; s->match_start = cur_match; ;;; bytes, as much as necessary in order to dword-align the edi
;;; best_len = len; ;;; pointer. (esi will still be misaligned three times out of four.)
;;; if (len >= nice_match) break; ;;;
;;; scan_end = *(ushf*)(scan+best_len-1); ;;; It should be confessed that this loop usually does not represent
;;; much of the total running time. Replacing it with a more
LongerMatch: mov ebx, [nicematch] ;;; straightforward "rep cmpsb" would not drastically degrade
mov [bestlen], eax ;;; performance.
mov [edx + dsMatchStart], ecx
cmp eax, ebx LoopCmps:
jge LeaveNow mov eax, [esi + edx]
mov esi, [window] xor eax, [edi + edx]
add esi, eax jnz LeaveLoopCmps
mov [windowbestlen], esi mov eax, [esi + edx + 4]
movzx ebx, word ptr [edi + eax - 1] xor eax, [edi + edx + 4]
mov edi, [edx + dsPrev] jnz LeaveLoopCmps4
mov [scanend], ebx add edx, 8
mov edx, [chainlenwmask] jnz LoopCmps
jmp LookupLoop jmp short LenMaximum
LeaveLoopCmps4: add edx, 4
;;; Accept the current string, with the maximum possible length. LeaveLoopCmps: test eax, 0000FFFFh
jnz LenLower
LenMaximum: mov edx, [deflatestate] add edx, 2
mov dword ptr [bestlen], MAX_MATCH shr eax, 16
mov [edx + dsMatchStart], ecx LenLower: sub al, 1
adc edx, 0
;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
;;; return s->lookahead; ;;; Calculate the length of the match. If it is longer than MAX_MATCH,
;;; then automatically accept it as the best possible match and leave.
LeaveNow:
mov edx, [deflatestate] lea eax, [edi + edx]
mov ebx, [bestlen] mov edi, [scan]
mov eax, [edx + dsLookahead] sub eax, edi
cmp ebx, eax cmp eax, MAX_MATCH
jg LookaheadRet jge LenMaximum
mov eax, ebx
LookaheadRet: ;;; 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.
;;; Restore the stack and return from whence we came.
mov edx, [deflatestate]
add esp, LocalVarsSize mov ebx, [bestlen]
pop ebx cmp eax, ebx
pop esi jg LongerMatch
pop edi mov esi, [windowbestlen]
pop ebp mov edi, [edx + dsPrev]
mov ebx, [scanend]
ret mov edx, [chainlenwmask]
; please don't remove this string ! jmp LookupLoop
; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah ;;; s->match_start = cur_match;
;;; best_len = len;
IFDEF NOUNDERLINE ;;; if (len >= nice_match) break;
longest_match_686 endp ;;; scan_end = *(ushf*)(scan+best_len-1);
ELSE
_longest_match_686 endp LongerMatch: mov ebx, [nicematch]
ENDIF mov [bestlen], eax
mov [edx + dsMatchStart], ecx
_TEXT ends cmp eax, ebx
end jge LeaveNow
mov esi, [window]
add esi, eax
mov [windowbestlen], esi
movzx ebx, word ptr [edi + eax - 1]
mov edi, [edx + dsPrev]
mov [scanend], ebx
mov edx, [chainlenwmask]
jmp LookupLoop
;;; Accept the current string, with the maximum possible length.
LenMaximum: mov edx, [deflatestate]
mov dword ptr [bestlen], MAX_MATCH
mov [edx + dsMatchStart], ecx
;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
;;; return s->lookahead;
LeaveNow:
mov edx, [deflatestate]
mov ebx, [bestlen]
mov eax, [edx + dsLookahead]
cmp ebx, eax
jg LookaheadRet
mov eax, ebx
LookaheadRet:
;;; Restore the stack and return from whence we came.
add esp, LocalVarsSize
pop ebx
pop esi
pop edi
pop ebp
ret
; please don't remove this string !
; Your can freely use gvmat32 in any free or commercial app if you don't remove the string in the binary!
db 0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
IFDEF NOOLDPENTIUMCODE
IFDEF NOUNDERLINE
longest_match endp
ELSE
_longest_match endp
ENDIF
IFDEF NOUNDERLINE
match_init proc near
ret
match_init endp
ELSE
_match_init proc near
ret
_match_init endp
ENDIF
ELSE
IFDEF NOUNDERLINE
longest_match_686 endp
ELSE
_longest_match_686 endp
ENDIF
ENDIF
_TEXT ends
end
/* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86 /* gvmat32.c -- C portion of the optimized longest_match for 32 bits x86
* Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant. * Copyright (C) 1995-1996 Jean-loup Gailly and Gilles Vollant.
* File written by Gilles Vollant, by modifiying the longest_match * File written by Gilles Vollant, by modifiying the longest_match
* from Jean-loup Gailly in deflate.c * from Jean-loup Gailly in deflate.c
* it prepare all parameters and call the assembly longest_match_gvasm * it prepare all parameters and call the assembly longest_match_gvasm
* longest_match execute standard C code is wmask != 0x7fff * longest_match execute standard C code is wmask != 0x7fff
* (assembly code is faster with a fixed wmask) * (assembly code is faster with a fixed wmask)
* *
*/ * Read comment at beginning of gvmat32.asm for more information
*/
#include "deflate.h"
#if defined(ASMV) && (!defined(NOOLDPENTIUMCODE))
#ifdef ASMV #include "deflate.h"
#define NIL 0
/* if your C compiler don't add underline before function name,
#define UNALIGNED_OK define ADD_UNDERLINE_ASMFUNC */
#ifdef ADD_UNDERLINE_ASMFUNC
#define longest_match_7fff _longest_match_7fff
/* if your C compiler don't add underline before function name, #define longest_match_686 _longest_match_686
define ADD_UNDERLINE_ASMFUNC */ #define cpudetect32 _cpudetect32
#ifdef ADD_UNDERLINE_ASMFUNC #endif
#define longest_match_7fff _longest_match_7fff
#define longest_match_686 _longest_match_686
#define cpudetect32 _cpudetect32 unsigned long cpudetect32();
#endif
uInt longest_match_c(
deflate_state *s,
IPos cur_match); /* current match */
void match_init()
{
} uInt longest_match_7fff(
deflate_state *s,
unsigned long cpudetect32(); IPos cur_match); /* current match */
uInt longest_match_c( uInt longest_match_686(
deflate_state *s, deflate_state *s,
IPos cur_match); /* current match */ IPos cur_match); /* current match */
uInt longest_match_7fff( static uInt iIsPPro=2;
deflate_state *s,
IPos cur_match); /* current match */ void match_init ()
{
uInt longest_match_686( iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
deflate_state *s, }
IPos cur_match); /* current match */
uInt longest_match(
uInt longest_match( deflate_state *s,
deflate_state *s, IPos cur_match) /* current match */
IPos cur_match) /* current match */ {
{ if (iIsPPro!=0)
static uInt iIsPPro=2; return longest_match_686(s,cur_match);
if ((s->w_mask == 0x7fff) && (iIsPPro==0)) if (s->w_mask != 0x7fff)
return longest_match_7fff(s,cur_match); return longest_match_686(s,cur_match);
if (iIsPPro==1) /* now ((s->w_mask == 0x7fff) && (iIsPPro==0)) */
return longest_match_686(s,cur_match); return longest_match_7fff(s,cur_match);
}
if (iIsPPro==2)
iIsPPro = (((cpudetect32()/0x100)&0xf)>=6) ? 1 : 0;
#endif /* defined(ASMV) && (!defined(NOOLDPENTIUMCODE)) */
return longest_match_c(s,cur_match);
}
uInt longest_match_c(s, cur_match)
deflate_state *s;
IPos cur_match; /* current match */
{
unsigned chain_length = s->max_chain_length;/* max hash chain length */
register Bytef *scan = s->window + s->strstart; /* current string */
register Bytef *match; /* matched string */
register int len; /* length of current match */
int best_len = s->prev_length; /* best match length so far */
int nice_match = s->nice_match; /* stop if match long enough */
IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
s->strstart - (IPos)MAX_DIST(s) : NIL;
/* Stop when cur_match becomes <= limit. To simplify the code,
* we prevent matches with the string of window index 0.
*/
Posf *prev = s->prev;
uInt wmask = s->w_mask;
#ifdef UNALIGNED_OK
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
register ush scan_start = *(ushf*)scan;
register ush scan_end = *(ushf*)(scan+best_len-1);
#else
register Bytef *strend = s->window + s->strstart + MAX_MATCH;
register Byte scan_end1 = scan[best_len-1];
register Byte scan_end = scan[best_len];
#endif
/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
* It is easy to get rid of this optimization if necessary.
*/
Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
/* Do not waste too much time if we already have a good match: */
if (s->prev_length >= s->good_match) {
chain_length >>= 2;
}
/* Do not look for matches beyond the end of the input. This is necessary
* to make deflate deterministic.
*/
if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
do {
Assert(cur_match < s->strstart, "no future");
match = s->window + cur_match;
/* Skip to next match if the match length cannot increase
* or if the match length is less than 2:
*/
#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
if (*(ushf*)(match+best_len-1) != scan_end ||
*(ushf*)match != scan_start) continue;
/* It is not necessary to compare scan[2] and match[2] since they are
* always equal when the other bytes match, given that the hash keys
* are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
* strstart+3, +5, ... up to strstart+257. We check for insufficient
* lookahead only every 4th comparison; the 128th check will be made
* at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
* necessary to put more guard bytes at the end of the window, or
* to check more often for insufficient lookahead.
*/
Assert(scan[2] == match[2], "scan[2]?");
scan++, match++;
do {
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
scan < strend);
/* The funny "do {}" generates better code on most compilers */
/* Here, scan <= window+strstart+257 */
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
if (*scan == *match) scan++;
len = (MAX_MATCH - 1) - (int)(strend-scan);
scan = strend - (MAX_MATCH-1);
#else /* UNALIGNED_OK */
if (match[best_len] != scan_end ||
match[best_len-1] != scan_end1 ||
*match != *scan ||
*++match != scan[1]) continue;
/* The check at best_len-1 can be removed because it will be made
* again later. (This heuristic is not always a win.)
* It is not necessary to compare scan[2] and match[2] since they
* are always equal when the other bytes match, given that
* the hash keys are equal and that HASH_BITS >= 8.
*/
scan += 2, match++;
Assert(*scan == *match, "match[2]?");
/* We check for insufficient lookahead only every 8th comparison;
* the 256th check will be made at strstart+258.
*/
do {
} while (*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
*++scan == *++match && *++scan == *++match &&
scan < strend);
Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
len = MAX_MATCH - (int)(strend - scan);
scan = strend - MAX_MATCH;
#endif /* UNALIGNED_OK */
if (len > best_len) {
s->match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
#ifdef UNALIGNED_OK
scan_end = *(ushf*)(scan+best_len-1);
#else
scan_end1 = scan[best_len-1];
scan_end = scan[best_len];
#endif
}
} while ((cur_match = prev[cur_match & wmask]) > limit
&& --chain_length != 0);
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead;
}
#endif /* ASMV */
; 75 "inffast.S" ;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding
;FILE "inffast.S" ; *
; * inffas32.asm is derivated from inffas86.c, with translation of assembly code
;;;GLOBAL _inflate_fast ; *
; * Copyright (C) 1995-2003 Mark Adler
;;;SECTION .text ; * For conditions of distribution and use, see copyright notice in zlib.h
; *
; * Copyright (C) 2003 Chris Anderson <christop@charm.net>
; * Please use the copyright conditions above.
.586p ; *
.mmx ; * 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
name inflate_fast_x86 ; * the moment. I have successfully compiled and tested this code with gcc2.96,
.MODEL FLAT ; * 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
_DATA segment ; * enabled. I will attempt to merge the MMX code into this version. Newer
inflate_fast_use_mmx: ; * versions of this and inffast.S can be found at
dd 1 ; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
; *
; * 2005 : modification by Gilles Vollant
_TEXT segment ; */
PUBLIC _inflate_fast ; For Visual C++ 4.x and higher and ML 6.x and higher
; ml.exe is in directory \MASM611C of Win95 DDK
ALIGN 4 ; ml.exe is also distributed in http://www.masm32.com/masmdl.htm
_inflate_fast: ; and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
jmp inflate_fast_entry ;
;
; compile with command line option
; ml /coff /Zi /c /Flinffas32.lst inffas32.asm
ALIGN 4
db 'Fast decoding Code from Chris Anderson' ; if you define NO_GZIP (see inflate.h), compile with
db 0 ; ml /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm
ALIGN 4
invalid_literal_length_code_msg: ; zlib122sup is 0 fort zlib 1.2.2.1 and lower
db 'invalid literal/length code' ; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head
db 0 ; in inflate_state in inflate.h)
zlib1222sup equ 8
ALIGN 4
invalid_distance_code_msg:
db 'invalid distance code' IFDEF GUNZIP
db 0 INFLATE_MODE_TYPE equ 11
INFLATE_MODE_BAD equ 26
ALIGN 4 ELSE
invalid_distance_too_far_msg: IFNDEF NO_GUNZIP
db 'invalid distance too far back' INFLATE_MODE_TYPE equ 11
db 0 INFLATE_MODE_BAD equ 26
ELSE
INFLATE_MODE_TYPE equ 3
ALIGN 4 INFLATE_MODE_BAD equ 17
inflate_fast_mask: ENDIF
dd 0 ENDIF
dd 1
dd 3
dd 7 ; 75 "inffast.S"
dd 15 ;FILE "inffast.S"
dd 31
dd 63 ;;;GLOBAL _inflate_fast
dd 127
dd 255 ;;;SECTION .text
dd 511
dd 1023
dd 2047
dd 4095 .586p
dd 8191 .mmx
dd 16383
dd 32767 name inflate_fast_x86
dd 65535 .MODEL FLAT
dd 131071
dd 262143 _DATA segment
dd 524287 inflate_fast_use_mmx:
dd 1048575 dd 1
dd 2097151
dd 4194303
dd 8388607 _TEXT segment
dd 16777215 PUBLIC _inflate_fast
dd 33554431
dd 67108863 ALIGN 4
dd 134217727 _inflate_fast:
dd 268435455 jmp inflate_fast_entry
dd 536870911
dd 1073741823
dd 2147483647
dd 4294967295 ALIGN 4
db 'Fast decoding Code from Chris Anderson'
db 0
mode_state equ 0 ;/* state->mode */ ALIGN 4
wsize_state equ 32 ;/* state->wsize */ invalid_literal_length_code_msg:
write_state equ (36+4) ;/* state->write */ db 'invalid literal/length code'
window_state equ (40+4) ;/* state->window */ db 0
hold_state equ (44+4) ;/* state->hold */
bits_state equ (48+4) ;/* state->bits */ ALIGN 4
lencode_state equ (64+4) ;/* state->lencode */ invalid_distance_code_msg:
distcode_state equ (68+4) ;/* state->distcode */ db 'invalid distance code'
lenbits_state equ (72+4) ;/* state->lenbits */ db 0
distbits_state equ (76+4) ;/* state->distbits */
ALIGN 4
invalid_distance_too_far_msg:
;;SECTION .text db 'invalid distance too far back'
; 205 "inffast.S" db 0
;GLOBAL inflate_fast_use_mmx
;SECTION .data ALIGN 4
inflate_fast_mask:
dd 0
; GLOBAL inflate_fast_use_mmx:object dd 1
;.size inflate_fast_use_mmx, 4 dd 3
; 226 "inffast.S" dd 7
;SECTION .text dd 15
dd 31
ALIGN 4 dd 63
inflate_fast_entry: dd 127
push edi dd 255
push esi dd 511
push ebp dd 1023
push ebx dd 2047
pushfd dd 4095
sub esp,64 dd 8191
cld dd 16383
dd 32767
dd 65535
dd 131071
dd 262143
mov esi, [esp+88] dd 524287
mov edi, [esi+28] dd 1048575
dd 2097151
dd 4194303
dd 8388607
dd 16777215
dd 33554431
dd 67108863
dd 134217727
mov edx, [esi+4] dd 268435455
mov eax, [esi+0] dd 536870911
dd 1073741823
add edx,eax dd 2147483647
sub edx,11 dd 4294967295
mov [esp+44],eax
mov [esp+20],edx mode_state equ 0 ;/* state->mode */
wsize_state equ (32+zlib1222sup) ;/* state->wsize */
mov ebp, [esp+92] write_state equ (36+4+zlib1222sup) ;/* state->write */
mov ecx, [esi+16] window_state equ (40+4+zlib1222sup) ;/* state->window */
mov ebx, [esi+12] hold_state equ (44+4+zlib1222sup) ;/* state->hold */
bits_state equ (48+4+zlib1222sup) ;/* state->bits */
sub ebp,ecx lencode_state equ (64+4+zlib1222sup) ;/* state->lencode */
neg ebp distcode_state equ (68+4+zlib1222sup) ;/* state->distcode */
add ebp,ebx lenbits_state equ (72+4+zlib1222sup) ;/* state->lenbits */
distbits_state equ (76+4+zlib1222sup) ;/* state->distbits */
sub ecx,257
add ecx,ebx
;;SECTION .text
mov [esp+60],ebx ; 205 "inffast.S"
mov [esp+40],ebp ;GLOBAL inflate_fast_use_mmx
mov [esp+16],ecx
; 285 "inffast.S" ;SECTION .data
mov eax, [edi+lencode_state]
mov ecx, [edi+distcode_state]
; GLOBAL inflate_fast_use_mmx:object
mov [esp+8],eax ;.size inflate_fast_use_mmx, 4
mov [esp+12],ecx ; 226 "inffast.S"
;SECTION .text
mov eax,1
mov ecx, [edi+lenbits_state] ALIGN 4
shl eax,cl inflate_fast_entry:
dec eax push edi
mov [esp+0],eax push esi
push ebp
mov eax,1 push ebx
mov ecx, [edi+distbits_state] pushfd
shl eax,cl sub esp,64
dec eax cld
mov [esp+4],eax
mov eax, [edi+wsize_state]
mov ecx, [edi+write_state]
mov edx, [edi+window_state] mov esi, [esp+88]
mov edi, [esi+28]
mov [esp+52],eax
mov [esp+48],ecx
mov [esp+56],edx
mov ebp, [edi+hold_state]
mov ebx, [edi+bits_state]
; 321 "inffast.S"
mov esi, [esp+44] mov edx, [esi+4]
mov ecx, [esp+20] mov eax, [esi+0]
cmp ecx,esi
ja L_align_long add edx,eax
sub edx,11
add ecx,11
sub ecx,esi mov [esp+44],eax
mov eax,12 mov [esp+20],edx
sub eax,ecx
lea edi, [esp+28] mov ebp, [esp+92]
rep movsb mov ecx, [esi+16]
mov ecx,eax mov ebx, [esi+12]
xor eax,eax
rep stosb sub ebp,ecx
lea esi, [esp+28] neg ebp
mov [esp+20],esi add ebp,ebx
jmp L_is_aligned
sub ecx,257
add ecx,ebx
L_align_long:
test esi,3 mov [esp+60],ebx
jz L_is_aligned mov [esp+40],ebp
xor eax,eax mov [esp+16],ecx
mov al, [esi] ; 285 "inffast.S"
inc esi mov eax, [edi+lencode_state]
mov ecx,ebx mov ecx, [edi+distcode_state]
add ebx,8
shl eax,cl mov [esp+8],eax
or ebp,eax mov [esp+12],ecx
jmp L_align_long
mov eax,1
L_is_aligned: mov ecx, [edi+lenbits_state]
mov edi, [esp+60] shl eax,cl
; 366 "inffast.S" dec eax
L_check_mmx: mov [esp+0],eax
cmp dword ptr [inflate_fast_use_mmx],2
je L_init_mmx mov eax,1
ja L_do_loop mov ecx, [edi+distbits_state]
shl eax,cl
push eax dec eax
push ebx mov [esp+4],eax
push ecx
push edx mov eax, [edi+wsize_state]
pushfd mov ecx, [edi+write_state]
mov eax, [esp] mov edx, [edi+window_state]
xor dword ptr [esp],0200000h
mov [esp+52],eax
mov [esp+48],ecx
mov [esp+56],edx
popfd mov ebp, [edi+hold_state]
pushfd mov ebx, [edi+bits_state]
pop edx ; 321 "inffast.S"
xor edx,eax mov esi, [esp+44]
jz L_dont_use_mmx mov ecx, [esp+20]
xor eax,eax cmp ecx,esi
cpuid ja L_align_long
cmp ebx,0756e6547h
jne L_dont_use_mmx add ecx,11
cmp ecx,06c65746eh sub ecx,esi
jne L_dont_use_mmx mov eax,12
cmp edx,049656e69h sub eax,ecx
jne L_dont_use_mmx lea edi, [esp+28]
mov eax,1 rep movsb
cpuid mov ecx,eax
shr eax,8 xor eax,eax
and eax,15 rep stosb
cmp eax,6 lea esi, [esp+28]
jne L_dont_use_mmx mov [esp+20],esi
test edx,0800000h jmp L_is_aligned
jnz L_use_mmx
jmp L_dont_use_mmx
L_use_mmx: L_align_long:
mov dword ptr [inflate_fast_use_mmx],2 test esi,3
jmp L_check_mmx_pop jz L_is_aligned
L_dont_use_mmx: xor eax,eax
mov dword ptr [inflate_fast_use_mmx],3 mov al, [esi]
L_check_mmx_pop: inc esi
pop edx mov ecx,ebx
pop ecx add ebx,8
pop ebx shl eax,cl
pop eax or ebp,eax
jmp L_check_mmx jmp L_align_long
; 426 "inffast.S"
ALIGN 4 L_is_aligned:
L_do_loop: mov edi, [esp+60]
; 437 "inffast.S" ; 366 "inffast.S"
cmp bl,15 L_check_mmx:
ja L_get_length_code cmp dword ptr [inflate_fast_use_mmx],2
je L_init_mmx
xor eax,eax ja L_do_loop
lodsw
mov cl,bl push eax
add bl,16 push ebx
shl eax,cl push ecx
or ebp,eax push edx
pushfd
L_get_length_code: mov eax, [esp]
mov edx, [esp+0] xor dword ptr [esp],0200000h
mov ecx, [esp+8]
and edx,ebp
mov eax, [ecx+edx*4]
L_dolen: popfd
pushfd
pop edx
xor edx,eax
jz L_dont_use_mmx
xor eax,eax
cpuid
mov cl,ah cmp ebx,0756e6547h
sub bl,ah jne L_dont_use_mmx
shr ebp,cl cmp ecx,06c65746eh
jne L_dont_use_mmx
cmp edx,049656e69h
jne L_dont_use_mmx
mov eax,1
cpuid
shr eax,8
test al,al and eax,15
jnz L_test_for_length_base cmp eax,6
jne L_dont_use_mmx
shr eax,16 test edx,0800000h
stosb jnz L_use_mmx
jmp L_dont_use_mmx
L_while_test: L_use_mmx:
mov dword ptr [inflate_fast_use_mmx],2
jmp L_check_mmx_pop
cmp [esp+16],edi L_dont_use_mmx:
jbe L_break_loop mov dword ptr [inflate_fast_use_mmx],3
L_check_mmx_pop:
cmp [esp+20],esi pop edx
ja L_do_loop pop ecx
jmp L_break_loop pop ebx
pop eax
L_test_for_length_base: jmp L_check_mmx
; 502 "inffast.S" ; 426 "inffast.S"
mov edx,eax ALIGN 4
shr edx,16 L_do_loop:
mov cl,al ; 437 "inffast.S"
cmp bl,15
test al,16 ja L_get_length_code
jz L_test_for_second_level_length
and cl,15 xor eax,eax
jz L_save_len lodsw
cmp bl,cl mov cl,bl
jae L_add_bits_to_len add bl,16
shl eax,cl
mov ch,cl or ebp,eax
xor eax,eax
lodsw L_get_length_code:
mov cl,bl mov edx, [esp+0]
add bl,16 mov ecx, [esp+8]
shl eax,cl and edx,ebp
or ebp,eax mov eax, [ecx+edx*4]
mov cl,ch
L_dolen:
L_add_bits_to_len:
mov eax,1
shl eax,cl
dec eax
sub bl,cl
and eax,ebp
shr ebp,cl mov cl,ah
add edx,eax sub bl,ah
shr ebp,cl
L_save_len:
mov [esp+24],edx
L_decode_distance:
; 549 "inffast.S"
cmp bl,15 test al,al
ja L_get_distance_code jnz L_test_for_length_base
xor eax,eax shr eax,16
lodsw stosb
mov cl,bl
add bl,16 L_while_test:
shl eax,cl
or ebp,eax
cmp [esp+16],edi
L_get_distance_code: jbe L_break_loop
mov edx, [esp+4]
mov ecx, [esp+12] cmp [esp+20],esi
and edx,ebp ja L_do_loop
mov eax, [ecx+edx*4] jmp L_break_loop
L_test_for_length_base:
L_dodist: ; 502 "inffast.S"
mov edx,eax mov edx,eax
shr edx,16 shr edx,16
mov cl,ah mov cl,al
sub bl,ah
shr ebp,cl test al,16
; 584 "inffast.S" jz L_test_for_second_level_length
mov cl,al and cl,15
jz L_save_len
test al,16 cmp bl,cl
jz L_test_for_second_level_dist jae L_add_bits_to_len
and cl,15
jz L_check_dist_one mov ch,cl
cmp bl,cl xor eax,eax
jae L_add_bits_to_dist lodsw
mov cl,bl
mov ch,cl add bl,16
xor eax,eax shl eax,cl
lodsw or ebp,eax
mov cl,bl mov cl,ch
add bl,16
shl eax,cl L_add_bits_to_len:
or ebp,eax mov eax,1
mov cl,ch shl eax,cl
dec eax
L_add_bits_to_dist: sub bl,cl
mov eax,1 and eax,ebp
shl eax,cl shr ebp,cl
dec eax add edx,eax
sub bl,cl
and eax,ebp L_save_len:
shr ebp,cl mov [esp+24],edx
add edx,eax
jmp L_check_window
L_decode_distance:
L_check_window: ; 549 "inffast.S"
; 625 "inffast.S" cmp bl,15
mov [esp+44],esi ja L_get_distance_code
mov eax,edi
sub eax, [esp+40] xor eax,eax
lodsw
cmp eax,edx mov cl,bl
jb L_clip_window add bl,16
shl eax,cl
mov ecx, [esp+24] or ebp,eax
mov esi,edi
sub esi,edx L_get_distance_code:
mov edx, [esp+4]
sub ecx,3 mov ecx, [esp+12]
mov al, [esi] and edx,ebp
mov [edi],al mov eax, [ecx+edx*4]
mov al, [esi+1]
mov dl, [esi+2]
add esi,3 L_dodist:
mov [edi+1],al mov edx,eax
mov [edi+2],dl shr edx,16
add edi,3 mov cl,ah
rep movsb sub bl,ah
shr ebp,cl
mov esi, [esp+44] ; 584 "inffast.S"
jmp L_while_test mov cl,al
ALIGN 4 test al,16
L_check_dist_one: jz L_test_for_second_level_dist
cmp edx,1 and cl,15
jne L_check_window jz L_check_dist_one
cmp [esp+40],edi cmp bl,cl
je L_check_window jae L_add_bits_to_dist
dec edi mov ch,cl
mov ecx, [esp+24] xor eax,eax
mov al, [edi] lodsw
sub ecx,3 mov cl,bl
add bl,16
mov [edi+1],al shl eax,cl
mov [edi+2],al or ebp,eax
mov [edi+3],al mov cl,ch
add edi,4
rep stosb L_add_bits_to_dist:
mov eax,1
jmp L_while_test shl eax,cl
dec eax
ALIGN 4 sub bl,cl
L_test_for_second_level_length: and eax,ebp
shr ebp,cl
add edx,eax
jmp L_check_window
test al,64 L_check_window:
jnz L_test_for_end_of_block ; 625 "inffast.S"
mov [esp+44],esi
mov eax,1 mov eax,edi
shl eax,cl sub eax, [esp+40]
dec eax
and eax,ebp cmp eax,edx
add eax,edx jb L_clip_window
mov edx, [esp+8]
mov eax, [edx+eax*4] mov ecx, [esp+24]
jmp L_dolen mov esi,edi
sub esi,edx
ALIGN 4
L_test_for_second_level_dist: sub ecx,3
mov al, [esi]
mov [edi],al
mov al, [esi+1]
mov dl, [esi+2]
test al,64 add esi,3
jnz L_invalid_distance_code mov [edi+1],al
mov [edi+2],dl
mov eax,1 add edi,3
shl eax,cl rep movsb
dec eax
and eax,ebp mov esi, [esp+44]
add eax,edx jmp L_while_test
mov edx, [esp+12]
mov eax, [edx+eax*4] ALIGN 4
jmp L_dodist L_check_dist_one:
cmp edx,1
ALIGN 4 jne L_check_window
L_clip_window: cmp [esp+40],edi
; 721 "inffast.S" je L_check_window
mov ecx,eax
mov eax, [esp+52] dec edi
neg ecx mov ecx, [esp+24]
mov esi, [esp+56] mov al, [edi]
sub ecx,3
cmp eax,edx
jb L_invalid_distance_too_far mov [edi+1],al
mov [edi+2],al
add ecx,edx mov [edi+3],al
cmp dword ptr [esp+48],0 add edi,4
jne L_wrap_around_window rep stosb
sub eax,ecx jmp L_while_test
add esi,eax
; 749 "inffast.S" ALIGN 4
mov eax, [esp+24] L_test_for_second_level_length:
cmp eax,ecx
jbe L_do_copy1
sub eax,ecx
rep movsb test al,64
mov esi,edi jnz L_test_for_end_of_block
sub esi,edx
jmp L_do_copy1 mov eax,1
shl eax,cl
cmp eax,ecx dec eax
jbe L_do_copy1 and eax,ebp
add eax,edx
sub eax,ecx mov edx, [esp+8]
rep movsb mov eax, [edx+eax*4]
mov esi,edi jmp L_dolen
sub esi,edx
jmp L_do_copy1 ALIGN 4
L_test_for_second_level_dist:
L_wrap_around_window:
; 793 "inffast.S"
mov eax, [esp+48]
cmp ecx,eax
jbe L_contiguous_in_window test al,64
jnz L_invalid_distance_code
add esi, [esp+52]
add esi,eax mov eax,1
sub esi,ecx shl eax,cl
sub ecx,eax dec eax
and eax,ebp
add eax,edx
mov eax, [esp+24] mov edx, [esp+12]
cmp eax,ecx mov eax, [edx+eax*4]
jbe L_do_copy1 jmp L_dodist
sub eax,ecx ALIGN 4
rep movsb L_clip_window:
mov esi, [esp+56] ; 721 "inffast.S"
mov ecx, [esp+48] mov ecx,eax
cmp eax,ecx mov eax, [esp+52]
jbe L_do_copy1 neg ecx
mov esi, [esp+56]
sub eax,ecx
rep movsb cmp eax,edx
mov esi,edi jb L_invalid_distance_too_far
sub esi,edx
jmp L_do_copy1 add ecx,edx
cmp dword ptr [esp+48],0
L_contiguous_in_window: jne L_wrap_around_window
; 836 "inffast.S"
add esi,eax sub eax,ecx
sub esi,ecx add esi,eax
; 749 "inffast.S"
mov eax, [esp+24]
mov eax, [esp+24] cmp eax,ecx
cmp eax,ecx jbe L_do_copy1
jbe L_do_copy1
sub eax,ecx
sub eax,ecx rep movsb
rep movsb mov esi,edi
mov esi,edi sub esi,edx
sub esi,edx jmp L_do_copy1
L_do_copy1: cmp eax,ecx
; 862 "inffast.S" jbe L_do_copy1
mov ecx,eax
rep movsb sub eax,ecx
rep movsb
mov esi, [esp+44] mov esi,edi
jmp L_while_test sub esi,edx
; 878 "inffast.S" jmp L_do_copy1
ALIGN 4
L_init_mmx: L_wrap_around_window:
emms ; 793 "inffast.S"
mov eax, [esp+48]
cmp ecx,eax
jbe L_contiguous_in_window
add esi, [esp+52]
movd mm0,ebp add esi,eax
mov ebp,ebx sub esi,ecx
; 896 "inffast.S" sub ecx,eax
movd mm4,[esp+0]
movq mm3,mm4
movd mm5,[esp+4] mov eax, [esp+24]
movq mm2,mm5 cmp eax,ecx
pxor mm1,mm1 jbe L_do_copy1
mov ebx, [esp+8]
jmp L_do_loop_mmx sub eax,ecx
rep movsb
ALIGN 4 mov esi, [esp+56]
L_do_loop_mmx: mov ecx, [esp+48]
psrlq mm0,mm1 cmp eax,ecx
jbe L_do_copy1
cmp ebp,32
ja L_get_length_code_mmx sub eax,ecx
rep movsb
movd mm6,ebp mov esi,edi
movd mm7,[esi] sub esi,edx
add esi,4 jmp L_do_copy1
psllq mm7,mm6
add ebp,32 L_contiguous_in_window:
por mm0,mm7 ; 836 "inffast.S"
add esi,eax
L_get_length_code_mmx: sub esi,ecx
pand mm4,mm0
movd eax,mm4
movq mm4,mm3 mov eax, [esp+24]
mov eax, [ebx+eax*4] cmp eax,ecx
jbe L_do_copy1
L_dolen_mmx:
movzx ecx,ah sub eax,ecx
movd mm1,ecx rep movsb
sub ebp,ecx mov esi,edi
sub esi,edx
test al,al
jnz L_test_for_length_base_mmx L_do_copy1:
; 862 "inffast.S"
shr eax,16 mov ecx,eax
stosb rep movsb
L_while_test_mmx: mov esi, [esp+44]
jmp L_while_test
; 878 "inffast.S"
cmp [esp+16],edi ALIGN 4
jbe L_break_loop L_init_mmx:
emms
cmp [esp+20],esi
ja L_do_loop_mmx
jmp L_break_loop
L_test_for_length_base_mmx:
movd mm0,ebp
mov edx,eax mov ebp,ebx
shr edx,16 ; 896 "inffast.S"
movd mm4,[esp+0]
test al,16 movq mm3,mm4
jz L_test_for_second_level_length_mmx movd mm5,[esp+4]
and eax,15 movq mm2,mm5
jz L_decode_distance_mmx pxor mm1,mm1
mov ebx, [esp+8]
psrlq mm0,mm1 jmp L_do_loop_mmx
movd mm1,eax
movd ecx,mm0 ALIGN 4
sub ebp,eax L_do_loop_mmx:
and ecx, [inflate_fast_mask+eax*4] psrlq mm0,mm1
add edx,ecx
cmp ebp,32
L_decode_distance_mmx: ja L_get_length_code_mmx
psrlq mm0,mm1
movd mm6,ebp
cmp ebp,32 movd mm7,[esi]
ja L_get_dist_code_mmx add esi,4
psllq mm7,mm6
movd mm6,ebp add ebp,32
movd mm7,[esi] por mm0,mm7
add esi,4
psllq mm7,mm6 L_get_length_code_mmx:
add ebp,32 pand mm4,mm0
por mm0,mm7 movd eax,mm4
movq mm4,mm3
L_get_dist_code_mmx: mov eax, [ebx+eax*4]
mov ebx, [esp+12]
pand mm5,mm0 L_dolen_mmx:
movd eax,mm5 movzx ecx,ah
movq mm5,mm2 movd mm1,ecx
mov eax, [ebx+eax*4] sub ebp,ecx
L_dodist_mmx: test al,al
jnz L_test_for_length_base_mmx
movzx ecx,ah
mov ebx,eax shr eax,16
shr ebx,16 stosb
sub ebp,ecx
movd mm1,ecx L_while_test_mmx:
test al,16
jz L_test_for_second_level_dist_mmx cmp [esp+16],edi
and eax,15 jbe L_break_loop
jz L_check_dist_one_mmx
cmp [esp+20],esi
L_add_bits_to_dist_mmx: ja L_do_loop_mmx
psrlq mm0,mm1 jmp L_break_loop
movd mm1,eax
movd ecx,mm0 L_test_for_length_base_mmx:
sub ebp,eax
and ecx, [inflate_fast_mask+eax*4] mov edx,eax
add ebx,ecx shr edx,16
L_check_window_mmx: test al,16
mov [esp+44],esi jz L_test_for_second_level_length_mmx
mov eax,edi and eax,15
sub eax, [esp+40] jz L_decode_distance_mmx
cmp eax,ebx psrlq mm0,mm1
jb L_clip_window_mmx movd mm1,eax
movd ecx,mm0
mov ecx,edx sub ebp,eax
mov esi,edi and ecx, [inflate_fast_mask+eax*4]
sub esi,ebx add edx,ecx
sub ecx,3 L_decode_distance_mmx:
mov al, [esi] psrlq mm0,mm1
mov [edi],al
mov al, [esi+1] cmp ebp,32
mov dl, [esi+2] ja L_get_dist_code_mmx
add esi,3
mov [edi+1],al movd mm6,ebp
mov [edi+2],dl movd mm7,[esi]
add edi,3 add esi,4
rep movsb psllq mm7,mm6
add ebp,32
mov esi, [esp+44] por mm0,mm7
mov ebx, [esp+8]
jmp L_while_test_mmx L_get_dist_code_mmx:
mov ebx, [esp+12]
ALIGN 4 pand mm5,mm0
L_check_dist_one_mmx: movd eax,mm5
cmp ebx,1 movq mm5,mm2
jne L_check_window_mmx mov eax, [ebx+eax*4]
cmp [esp+40],edi
je L_check_window_mmx L_dodist_mmx:
dec edi movzx ecx,ah
mov ecx,edx mov ebx,eax
mov al, [edi] shr ebx,16
sub ecx,3 sub ebp,ecx
movd mm1,ecx
mov [edi+1],al
mov [edi+2],al test al,16
mov [edi+3],al jz L_test_for_second_level_dist_mmx
add edi,4 and eax,15
rep stosb jz L_check_dist_one_mmx
mov ebx, [esp+8] L_add_bits_to_dist_mmx:
jmp L_while_test_mmx psrlq mm0,mm1
movd mm1,eax
ALIGN 4 movd ecx,mm0
L_test_for_second_level_length_mmx: sub ebp,eax
test al,64 and ecx, [inflate_fast_mask+eax*4]
jnz L_test_for_end_of_block add ebx,ecx
and eax,15 L_check_window_mmx:
psrlq mm0,mm1 mov [esp+44],esi
movd ecx,mm0 mov eax,edi
and ecx, [inflate_fast_mask+eax*4] sub eax, [esp+40]
add ecx,edx
mov eax, [ebx+ecx*4] cmp eax,ebx
jmp L_dolen_mmx jb L_clip_window_mmx
ALIGN 4 mov ecx,edx
L_test_for_second_level_dist_mmx: mov esi,edi
test al,64 sub esi,ebx
jnz L_invalid_distance_code
sub ecx,3
and eax,15 mov al, [esi]
psrlq mm0,mm1 mov [edi],al
movd ecx,mm0 mov al, [esi+1]
and ecx, [inflate_fast_mask+eax*4] mov dl, [esi+2]
mov eax, [esp+12] add esi,3
add ecx,ebx mov [edi+1],al
mov eax, [eax+ecx*4] mov [edi+2],dl
jmp L_dodist_mmx add edi,3
rep movsb
ALIGN 4
L_clip_window_mmx: mov esi, [esp+44]
mov ebx, [esp+8]
mov ecx,eax jmp L_while_test_mmx
mov eax, [esp+52]
neg ecx ALIGN 4
mov esi, [esp+56] L_check_dist_one_mmx:
cmp ebx,1
cmp eax,ebx jne L_check_window_mmx
jb L_invalid_distance_too_far cmp [esp+40],edi
je L_check_window_mmx
add ecx,ebx
cmp dword ptr [esp+48],0 dec edi
jne L_wrap_around_window_mmx mov ecx,edx
mov al, [edi]
sub eax,ecx sub ecx,3
add esi,eax
mov [edi+1],al
cmp edx,ecx mov [edi+2],al
jbe L_do_copy1_mmx mov [edi+3],al
add edi,4
sub edx,ecx rep stosb
rep movsb
mov esi,edi mov ebx, [esp+8]
sub esi,ebx jmp L_while_test_mmx
jmp L_do_copy1_mmx
ALIGN 4
cmp edx,ecx L_test_for_second_level_length_mmx:
jbe L_do_copy1_mmx test al,64
jnz L_test_for_end_of_block
sub edx,ecx
rep movsb and eax,15
mov esi,edi psrlq mm0,mm1
sub esi,ebx movd ecx,mm0
jmp L_do_copy1_mmx and ecx, [inflate_fast_mask+eax*4]
add ecx,edx
L_wrap_around_window_mmx: mov eax, [ebx+ecx*4]
jmp L_dolen_mmx
mov eax, [esp+48]
cmp ecx,eax ALIGN 4
jbe L_contiguous_in_window_mmx L_test_for_second_level_dist_mmx:
test al,64
add esi, [esp+52] jnz L_invalid_distance_code
add esi,eax
sub esi,ecx and eax,15
sub ecx,eax psrlq mm0,mm1
movd ecx,mm0
and ecx, [inflate_fast_mask+eax*4]
cmp edx,ecx mov eax, [esp+12]
jbe L_do_copy1_mmx add ecx,ebx
mov eax, [eax+ecx*4]
sub edx,ecx jmp L_dodist_mmx
rep movsb
mov esi, [esp+56] ALIGN 4
mov ecx, [esp+48] L_clip_window_mmx:
cmp edx,ecx
jbe L_do_copy1_mmx mov ecx,eax
mov eax, [esp+52]
sub edx,ecx neg ecx
rep movsb mov esi, [esp+56]
mov esi,edi
sub esi,ebx cmp eax,ebx
jmp L_do_copy1_mmx jb L_invalid_distance_too_far
L_contiguous_in_window_mmx: add ecx,ebx
cmp dword ptr [esp+48],0
add esi,eax jne L_wrap_around_window_mmx
sub esi,ecx
sub eax,ecx
add esi,eax
cmp edx,ecx
jbe L_do_copy1_mmx cmp edx,ecx
jbe L_do_copy1_mmx
sub edx,ecx
rep movsb sub edx,ecx
mov esi,edi rep movsb
sub esi,ebx mov esi,edi
sub esi,ebx
L_do_copy1_mmx: jmp L_do_copy1_mmx
cmp edx,ecx
mov ecx,edx jbe L_do_copy1_mmx
rep movsb
sub edx,ecx
mov esi, [esp+44] rep movsb
mov ebx, [esp+8] mov esi,edi
jmp L_while_test_mmx sub esi,ebx
; 1174 "inffast.S" jmp L_do_copy1_mmx
L_invalid_distance_code:
L_wrap_around_window_mmx:
mov eax, [esp+48]
cmp ecx,eax
jbe L_contiguous_in_window_mmx
mov ecx, invalid_distance_code_msg
mov edx,26 add esi, [esp+52]
jmp L_update_stream_state add esi,eax
sub esi,ecx
L_test_for_end_of_block: sub ecx,eax
cmp edx,ecx
jbe L_do_copy1_mmx
test al,32 sub edx,ecx
jz L_invalid_literal_length_code rep movsb
mov esi, [esp+56]
mov ecx,0 mov ecx, [esp+48]
mov edx,11 cmp edx,ecx
jmp L_update_stream_state jbe L_do_copy1_mmx
L_invalid_literal_length_code: sub edx,ecx
rep movsb
mov esi,edi
sub esi,ebx
jmp L_do_copy1_mmx
mov ecx, invalid_literal_length_code_msg L_contiguous_in_window_mmx:
mov edx,26
jmp L_update_stream_state add esi,eax
sub esi,ecx
L_invalid_distance_too_far:
cmp edx,ecx
jbe L_do_copy1_mmx
mov esi, [esp+44]
mov ecx, invalid_distance_too_far_msg sub edx,ecx
mov edx,26 rep movsb
jmp L_update_stream_state mov esi,edi
sub esi,ebx
L_update_stream_state:
L_do_copy1_mmx:
mov eax, [esp+88]
test ecx,ecx
jz L_skip_msg mov ecx,edx
mov [eax+24],ecx rep movsb
L_skip_msg:
mov eax, [eax+28] mov esi, [esp+44]
mov [eax+mode_state],edx mov ebx, [esp+8]
jmp L_break_loop jmp L_while_test_mmx
; 1174 "inffast.S"
ALIGN 4 L_invalid_distance_code:
L_break_loop:
; 1243 "inffast.S"
cmp dword ptr [inflate_fast_use_mmx],2
jne L_update_next_in
mov ecx, invalid_distance_code_msg
mov edx,INFLATE_MODE_BAD
mov ebx,ebp jmp L_update_stream_state
L_update_next_in: L_test_for_end_of_block:
; 1266 "inffast.S"
mov eax, [esp+88]
mov ecx,ebx
mov edx, [eax+28]
shr ecx,3
sub esi,ecx test al,32
shl ecx,3 jz L_invalid_literal_length_code
sub ebx,ecx
mov [eax+12],edi mov ecx,0
mov [edx+bits_state],ebx mov edx,INFLATE_MODE_TYPE
mov ecx,ebx jmp L_update_stream_state
lea ebx, [esp+28] L_invalid_literal_length_code:
cmp [esp+20],ebx
jne L_buf_not_used
sub esi,ebx
mov ebx, [eax+0]
mov [esp+20],ebx mov ecx, invalid_literal_length_code_msg
add esi,ebx mov edx,INFLATE_MODE_BAD
mov ebx, [eax+4] jmp L_update_stream_state
sub ebx,11
add [esp+20],ebx L_invalid_distance_too_far:
L_buf_not_used:
mov [eax+0],esi
mov esi, [esp+44]
mov ebx,1 mov ecx, invalid_distance_too_far_msg
shl ebx,cl mov edx,INFLATE_MODE_BAD
dec ebx jmp L_update_stream_state
L_update_stream_state:
mov eax, [esp+88]
test ecx,ecx
cmp dword ptr [inflate_fast_use_mmx],2 jz L_skip_msg
jne L_update_hold mov [eax+24],ecx
L_skip_msg:
mov eax, [eax+28]
mov [eax+mode_state],edx
psrlq mm0,mm1 jmp L_break_loop
movd ebp,mm0
ALIGN 4
emms L_break_loop:
; 1243 "inffast.S"
L_update_hold: cmp dword ptr [inflate_fast_use_mmx],2
jne L_update_next_in
and ebp,ebx
mov [edx+hold_state],ebp mov ebx,ebp
L_update_next_in:
; 1266 "inffast.S"
mov eax, [esp+88]
mov ebx, [esp+20] mov ecx,ebx
cmp ebx,esi mov edx, [eax+28]
jbe L_last_is_smaller shr ecx,3
sub esi,ecx
sub ebx,esi shl ecx,3
add ebx,11 sub ebx,ecx
mov [eax+4],ebx mov [eax+12],edi
jmp L_fixup_out mov [edx+bits_state],ebx
L_last_is_smaller: mov ecx,ebx
sub esi,ebx
neg esi lea ebx, [esp+28]
add esi,11 cmp [esp+20],ebx
mov [eax+4],esi jne L_buf_not_used
sub esi,ebx
mov ebx, [eax+0]
mov [esp+20],ebx
L_fixup_out: add esi,ebx
mov ebx, [eax+4]
mov ebx, [esp+16] sub ebx,11
cmp ebx,edi add [esp+20],ebx
jbe L_end_is_smaller
L_buf_not_used:
sub ebx,edi mov [eax+0],esi
add ebx,257
mov [eax+16],ebx mov ebx,1
jmp L_done shl ebx,cl
L_end_is_smaller: dec ebx
sub edi,ebx
neg edi
add edi,257
mov [eax+16],edi
cmp dword ptr [inflate_fast_use_mmx],2
jne L_update_hold
L_done:
add esp,64 psrlq mm0,mm1
popfd movd ebp,mm0
pop ebx
pop ebp emms
pop esi
pop edi L_update_hold:
ret
and ebp,ebx
mov [edx+hold_state],ebp
_TEXT ends
end
mov ebx, [esp+20]
cmp ebx,esi
jbe L_last_is_smaller
sub ebx,esi
add ebx,11
mov [eax+4],ebx
jmp L_fixup_out
L_last_is_smaller:
sub esi,ebx
neg esi
add esi,11
mov [eax+4],esi
L_fixup_out:
mov ebx, [esp+16]
cmp ebx,edi
jbe L_end_is_smaller
sub ebx,edi
add ebx,257
mov [eax+16],ebx
jmp L_done
L_end_is_smaller:
sub edi,ebx
neg edi
add edi,257
mov [eax+16],edi
L_done:
add esp,64
popfd
pop ebx
pop ebp
pop esi
pop edi
ret
_TEXT ends
end
cl /I..\.. /O2 /c gvmat32c.c cl /DASMV /I..\.. /O2 /c gvmat32c.c
ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm ml /coff /Zi /c /Flgvmat32.lst gvmat32.asm
ml /coff /Zi /c /Flinffas32.lst inffas32.asm ml /coff /Zi /c /Flinffas32.lst inffas32.asm
/* crypt.h -- base code for crypt/uncrypt ZIPfile /* crypt.h -- base code for crypt/uncrypt ZIPfile
Version 1.00, September 10th, 2003 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
This code is a modified version of crypting code in Infozip distribution This code is a modified version of crypting code in Infozip distribution
......
/* ioapi.c -- IO base function header for compress/uncompress .zip /* ioapi.c -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API files using zlib + zip or unzip API
Version 1.00, September 10th, 2003 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
*/ */
#include <stdio.h> #include <stdio.h>
...@@ -94,7 +94,7 @@ uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) ...@@ -94,7 +94,7 @@ uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
uLong size; uLong size;
{ {
uLong ret; uLong ret;
ret = fread(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
} }
...@@ -106,7 +106,7 @@ uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) ...@@ -106,7 +106,7 @@ uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
uLong size; uLong size;
{ {
uLong ret; uLong ret;
ret = fwrite(buf, 1, (size_t)size, (FILE *)stream); ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret; return ret;
} }
......
/* ioapi.h -- IO base function header for compress/uncompress .zip /* ioapi.h -- IO base function header for compress/uncompress .zip
files using zlib + zip or unzip API files using zlib + zip or unzip API
Version 1.00, September 10th, 2003 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
*/ */
#ifndef _ZLIBIOAPI_H #ifndef _ZLIBIOAPI_H
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
files using zlib + zip or unzip API files using zlib + zip or unzip API
This IO API version uses the Win32 API (for Microsoft Windows) This IO API version uses the Win32 API (for Microsoft Windows)
Version 1.00, September 10th, 2003 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
*/ */
#include <stdlib.h> #include <stdlib.h>
......
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
files using zlib + zip or unzip API files using zlib + zip or unzip API
This IO API version uses the Win32 API (for Microsoft Windows) This IO API version uses the Win32 API (for Microsoft Windows)
Version 1.00, September 10th, 2003 Version 1.01e, February 12th, 2005
Copyright (C) 1998-2003 Gilles Vollant Copyright (C) 1998-2005 Gilles Vollant
*/ */
#include <windows.h> #include <windows.h>
......
...@@ -10,7 +10,7 @@ unit zlibpas; ...@@ -10,7 +10,7 @@ unit zlibpas;
interface interface
const const
ZLIB_VERSION = '1.2.1'; ZLIB_VERSION = '1.2.3';
type type
alloc_func = function(opaque: Pointer; items, size: Integer): Pointer; alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
......
/* /*
* puff.c * puff.c
* Copyright (C) 2002, 2003 Mark Adler * Copyright (C) 2002-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in puff.h * For conditions of distribution and use, see copyright notice in puff.h
* version 1.7, 3 Mar 2003 * version 1.8, 9 Jan 2004
* *
* puff.c is a simple inflate written to be an unambiguous way to specify the * puff.c is a simple inflate written to be an unambiguous way to specify the
* deflate format. It is not written for speed but rather simplicity. As a * deflate format. It is not written for speed but rather simplicity. As a
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
* 1.6 7 Aug 2002 - Minor format changes * 1.6 7 Aug 2002 - Minor format changes
* 1.7 3 Mar 2003 - Added test code for distribution * 1.7 3 Mar 2003 - Added test code for distribution
* - Added zlib-like license * - Added zlib-like license
* 1.8 9 Jan 2004 - Added some comments on no distance codes case
*/ */
#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */ #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
...@@ -577,6 +578,9 @@ local int fixed(struct state *s) ...@@ -577,6 +578,9 @@ local int fixed(struct state *s)
* block is fewer bits), but it is allowed by the format. So incomplete * block is fewer bits), but it is allowed by the format. So incomplete
* literal/length codes of one symbol should also be permitted. * literal/length codes of one symbol should also be permitted.
* *
* - If there are only literal codes and no lengths, then there are no distance
* codes. This is represented by one distance code with zero bits.
*
* - The list of up to 286 length/literal lengths and up to 30 distance lengths * - The list of up to 286 length/literal lengths and up to 30 distance lengths
* are themselves compressed using Huffman codes and run-length encoding. In * are themselves compressed using Huffman codes and run-length encoding. In
* the list of code lengths, a 0 symbol means no code, a 1..15 symbol means * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
......
#include <stdio.h>
#include <stdio.h> #include <stdlib.h>
#include <stdlib.h> #include <windows.h>
#include <windows.h>
#include "zlib.h" #include "zlib.h"
int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
{ void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
FILE* stream; {
void* ptr; R->HighPart = A.HighPart - B.HighPart;
int retVal=1; if (A.LowPart >= B.LowPart)
stream=fopen(filename, "rb"); R->LowPart = A.LowPart - B.LowPart;
if (stream==NULL) else
return 0; {
R->LowPart = A.LowPart - B.LowPart;
fseek(stream,0,SEEK_END); R->HighPart --;
}
*plFileSize=ftell(stream); }
fseek(stream,0,SEEK_SET);
ptr=malloc((*plFileSize)+1); #ifdef _M_X64
if (ptr==NULL) // see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
retVal=0; unsigned __int64 __rdtsc(void);
else void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{ {
if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize)) // printf("rdtsc = %I64x\n",__rdtsc());
retVal=0; pbeginTime64->QuadPart=__rdtsc();
} }
fclose(stream);
*pFilePtr=ptr; LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
return retVal; {
} LARGE_INTEGER LIres;
unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));
int main(int argc, char *argv[]) LIres.QuadPart=res;
{ // printf("rdtsc = %I64x\n",__rdtsc());
int BlockSizeCompress=0x8000; return LIres;
int BlockSizeUncompress=0x8000; }
int cprLevel=Z_DEFAULT_COMPRESSION ; #else
long lFileSize; #ifdef _M_IX86
unsigned char* FilePtr; void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
long lBufferSizeCpr; {
long lBufferSizeUncpr; DWORD dwEdx,dwEax;
long lCompressedSize=0; _asm
unsigned char* CprPtr; {
unsigned char* UncprPtr; rdtsc
long lSizeCpr,lSizeUncpr; mov dwEax,eax
DWORD dwGetTick; mov dwEdx,edx
}
if (argc<=1) pbeginTime64->LowPart=dwEax;
{ pbeginTime64->HighPart=dwEdx;
printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n"); }
return 0;
} void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0) myGetRDTSC32(pbeginTime64);
{ }
printf("error reading %s\n",argv[1]);
return 1; LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
} {
else printf("file %s read, %u bytes\n",argv[1],lFileSize); LARGE_INTEGER LIres,endTime64;
myGetRDTSC32(&endTime64);
if (argc>=3)
BlockSizeCompress=atol(argv[2]); LIres.LowPart=LIres.HighPart=0;
MyDoMinus64(&LIres,endTime64,beginTime64);
if (argc>=4) return LIres;
BlockSizeUncompress=atol(argv[3]); }
#else
if (argc>=5) void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
cprLevel=(int)atol(argv[4]); {
}
lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
lBufferSizeUncpr = lBufferSizeCpr; void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress); }
UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
dwGetTick=GetTickCount(); {
{ LARGE_INTEGER lr;
z_stream zcpr; lr.QuadPart=0;
int ret=Z_OK; return lr;
long lOrigToDo = lFileSize; }
long lOrigDone = 0; #endif
int step=0; #endif
memset(&zcpr,0,sizeof(z_stream));
deflateInit(&zcpr,cprLevel); void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
{
zcpr.next_in = FilePtr; if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
zcpr.next_out = CprPtr; {
pbeginTime64->LowPart = GetTickCount();
pbeginTime64->HighPart = 0;
do }
{ }
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeCompress); DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
zcpr.avail_out = BlockSizeCompress; {
ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH); LARGE_INTEGER endTime64,ticksPerSecond,ticks;
lOrigDone += (zcpr.total_in-all_read_before); DWORDLONG ticksShifted,tickSecShifted;
lOrigToDo -= (zcpr.total_in-all_read_before); DWORD dwLog=16+0;
step++; DWORD dwRet;
} while (ret==Z_OK); if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
dwRet = (GetTickCount() - beginTime64.LowPart)*1;
lSizeCpr=zcpr.total_out; else
deflateEnd(&zcpr); {
dwGetTick=GetTickCount()-dwGetTick; MyDoMinus64(&ticks,endTime64,beginTime64);
printf("total compress size = %u, in %u step\n",lSizeCpr,step); QueryPerformanceFrequency(&ticksPerSecond);
printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.);
}
{
dwGetTick=GetTickCount(); ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
{ tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
z_stream zcpr;
int ret=Z_OK; }
long lOrigToDo = lSizeCpr;
long lOrigDone = 0; dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
int step=0; dwRet *=1;
memset(&zcpr,0,sizeof(z_stream)); }
inflateInit(&zcpr); return dwRet;
}
zcpr.next_in = CprPtr;
zcpr.next_out = UncprPtr; int ReadFileMemory(const char* filename,long* plFileSize,void** pFilePtr)
{
FILE* stream;
do void* ptr;
{ int retVal=1;
long all_read_before = zcpr.total_in; stream=fopen(filename, "rb");
zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress); if (stream==NULL)
zcpr.avail_out = BlockSizeUncompress; return 0;
ret=inflate(&zcpr,Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before); fseek(stream,0,SEEK_END);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++; *plFileSize=ftell(stream);
} while (ret==Z_OK); fseek(stream,0,SEEK_SET);
ptr=malloc((*plFileSize)+1);
lSizeUncpr=zcpr.total_out; if (ptr==NULL)
inflateEnd(&zcpr); retVal=0;
dwGetTick=GetTickCount()-dwGetTick; else
printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step); {
printf("time = %u msec = %f sec\n\n",dwGetTick,dwGetTick/(double)1000.); if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
} retVal=0;
}
if (lSizeUncpr==lFileSize) fclose(stream);
{ *pFilePtr=ptr;
if (memcmp(FilePtr,UncprPtr,lFileSize)==0) return retVal;
printf("compare ok\n"); }
} int main(int argc, char *argv[])
{
return 0; int BlockSizeCompress=0x8000;
int BlockSizeUncompress=0x8000;
} int cprLevel=Z_DEFAULT_COMPRESSION ;
long lFileSize;
unsigned char* FilePtr;
long lBufferSizeCpr;
long lBufferSizeUncpr;
long lCompressedSize=0;
unsigned char* CprPtr;
unsigned char* UncprPtr;
long lSizeCpr,lSizeUncpr;
DWORD dwGetTick,dwMsecQP;
LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
if (argc<=1)
{
printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
return 0;
}
if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
{
printf("error reading %s\n",argv[1]);
return 1;
}
else printf("file %s read, %u bytes\n",argv[1],lFileSize);
if (argc>=3)
BlockSizeCompress=atol(argv[2]);
if (argc>=4)
BlockSizeUncompress=atol(argv[3]);
if (argc>=5)
cprLevel=(int)atol(argv[4]);
lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
lBufferSizeUncpr = lBufferSizeCpr;
CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lFileSize;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
deflateInit(&zcpr,cprLevel);
zcpr.next_in = FilePtr;
zcpr.next_out = CprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
zcpr.avail_out = BlockSizeCompress;
ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeCpr=zcpr.total_out;
deflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total compress size = %u, in %u step\n",lSizeCpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
BeginCountPerfCounter(&li_qp,TRUE);
dwGetTick=GetTickCount();
BeginCountRdtsc(&li_rdtsc);
{
z_stream zcpr;
int ret=Z_OK;
long lOrigToDo = lSizeCpr;
long lOrigDone = 0;
int step=0;
memset(&zcpr,0,sizeof(z_stream));
inflateInit(&zcpr);
zcpr.next_in = CprPtr;
zcpr.next_out = UncprPtr;
do
{
long all_read_before = zcpr.total_in;
zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
zcpr.avail_out = BlockSizeUncompress;
ret=inflate(&zcpr,Z_SYNC_FLUSH);
lOrigDone += (zcpr.total_in-all_read_before);
lOrigToDo -= (zcpr.total_in-all_read_before);
step++;
} while (ret==Z_OK);
lSizeUncpr=zcpr.total_out;
inflateEnd(&zcpr);
dwGetTick=GetTickCount()-dwGetTick;
dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
}
if (lSizeUncpr==lFileSize)
{
if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
printf("compare ok\n");
}
return 0;
}
Building instructions for the DLL versions of Zlib 1.21 Building instructions for the DLL versions of Zlib 1.2.3
======================================================= ========================================================
This directory contains projects that build zlib and minizip using This directory contains projects that build zlib and minizip using
Microsoft Visual C++ 7.0/7.1. Microsoft Visual C++ 7.0/7.1, and Visual C++ .
You don't need to build these projects yourself. You can download the You don't need to build these projects yourself. You can download the
binaries from: binaries from:
...@@ -11,18 +11,36 @@ binaries from: ...@@ -11,18 +11,36 @@ binaries from:
More information can be found at this site. More information can be found at this site.
Build instructions Build instructions for Visual Studio 7.x (32 bits)
------------------ --------------------------------------------------
- Unzip zlib*.zip and copy the files from contrib\vstudio\vc7, - Uncompress current zlib, including all contrib/* files
from contrib\vstudio\masmx86 and from contrib\minizip into the same
directory.
- Download the crtdll library from - Download the crtdll library from
http://www.winimage.com/zLibDll/crtdll.zip http://www.winimage.com/zLibDll/crtdll.zip
Unzip crtdll.zip to extract crtdll.lib. Unzip crtdll.zip to extract crtdll.lib on contrib\vstudio\vc7.
- If you are using x86, use the Release target. - Open contrib\vstudio\vc7\zlibvc.sln with Microsoft Visual C++ 7.x
- Open zlibvc.sln with Microsoft Visual C++ 7.0 or 7.1
(Visual Studio .Net 2002 or 2003). (Visual Studio .Net 2002 or 2003).
Build instructions for Visual Studio 2005 (32 bits or 64 bits)
--------------------------------------------------------------
- Uncompress current zlib, including all contrib/* files
- For 32 bits only: download the crtdll library from
http://www.winimage.com/zLibDll/crtdll.zip
Unzip crtdll.zip to extract crtdll.lib on contrib\vstudio\vc8.
- Open contrib\vstudio\vc8\zlibvc.sln with Microsoft Visual C++ 8.0
Build instructions for Visual Studio 2005 64 bits, PSDK compiler
----------------------------------------------------------------
at the time of writing this text file, Visual Studio 2005 (and
Microsoft Visual C++ 8.0) is on the beta 2 stage.
Using you can get the free 64 bits compiler from Platform SDK,
which is NOT a beta, and compile using the Visual studio 2005 IDE
see http://www.winimage.com/misc/sdk64onvs2005/ for instruction
- Uncompress current zlib, including all contrib/* files
- start Visual Studio 2005 from a platform SDK command prompt, using
the /useenv switch
- Open contrib\vstudio\vc8\zlibvc.sln with Microsoft Visual C++ 8.0
Important Important
--------- ---------
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\..;..\..\minizip"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
...@@ -63,6 +64,7 @@ ...@@ -63,6 +64,7 @@
Optimization="2" Optimization="2"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
OmitFramePointers="TRUE" OmitFramePointers="TRUE"
AdditionalIncludeDirectories="..\..\..;..\..\minizip"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
...@@ -104,7 +106,7 @@ ...@@ -104,7 +106,7 @@
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"> Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File <File
RelativePath="miniunz.c"> RelativePath="..\..\minizip\miniunz.c">
</File> </File>
</Filter> </Filter>
<Filter <Filter
...@@ -116,7 +118,7 @@ ...@@ -116,7 +118,7 @@
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter> </Filter>
<File <File
RelativePath="zlibwapi.lib"> RelativePath="ReleaseDll\zlibwapi.lib">
</File> </File>
</Files> </Files>
<Globals> <Globals>
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\..;..\..\minizip"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE" MinimalRebuild="TRUE"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
...@@ -63,6 +64,7 @@ ...@@ -63,6 +64,7 @@
Optimization="2" Optimization="2"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
OmitFramePointers="TRUE" OmitFramePointers="TRUE"
AdditionalIncludeDirectories="..\..\..;..\..\minizip"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
...@@ -104,7 +106,7 @@ ...@@ -104,7 +106,7 @@
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"> Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
<File <File
RelativePath="minizip.c"> RelativePath="..\..\minizip\minizip.c">
</File> </File>
</Filter> </Filter>
<Filter <Filter
...@@ -116,7 +118,7 @@ ...@@ -116,7 +118,7 @@
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"> Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
</Filter> </Filter>
<File <File
RelativePath="zlibwapi.lib"> RelativePath="ReleaseDll\zlibwapi.lib">
</File> </File>
</Files> </Files>
<Globals> <Globals>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
#define IDR_VERSION1 1 #define IDR_VERSION1 1
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
FILEVERSION 1,2,1,0 FILEVERSION 1,2,3,0
PRODUCTVERSION 1,2,1,0 PRODUCTVERSION 1,2,3,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0 FILEFLAGS 0
FILEOS VOS_DOS_WINDOWS32 FILEOS VOS_DOS_WINDOWS32
...@@ -17,7 +17,7 @@ BEGIN ...@@ -17,7 +17,7 @@ BEGIN
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression library\0" VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.2.1.0\0" VALUE "FileVersion", "1.2.3.0\0"
VALUE "InternalName", "zlib\0" VALUE "InternalName", "zlib\0"
VALUE "OriginalFilename", "zlib.dll\0" VALUE "OriginalFilename", "zlib.dll\0"
VALUE "ProductName", "ZLib.DLL\0" VALUE "ProductName", "ZLib.DLL\0"
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI" PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
RuntimeLibrary="5" RuntimeLibrary="5"
...@@ -61,6 +62,7 @@ ...@@ -61,6 +62,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI" PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -102,6 +104,7 @@ ...@@ -102,6 +104,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF" PreprocessorDefinitions="WIN32;ZLIB_WINAPI;ASMV;ASMINF"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -117,7 +120,7 @@ ...@@ -117,7 +120,7 @@
Name="VCCustomBuildTool"/> Name="VCCustomBuildTool"/>
<Tool <Tool
Name="VCLibrarianTool" Name="VCLibrarianTool"
AdditionalOptions="gvmat32.obj inffas32.obj /NODEFAULTLIB " AdditionalOptions="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj /NODEFAULTLIB "
OutputFile=".\zlibstat\zlibstat.lib" OutputFile=".\zlibstat\zlibstat.lib"
SuppressStartupBanner="TRUE"/> SuppressStartupBanner="TRUE"/>
<Tool <Tool
...@@ -144,6 +147,7 @@ ...@@ -144,6 +147,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32;ZLIB_WINAPI" PreprocessorDefinitions="WIN32;ZLIB_WINAPI"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -182,49 +186,49 @@ ...@@ -182,49 +186,49 @@
Name="Source Files" Name="Source Files"
Filter=""> Filter="">
<File <File
RelativePath=".\adler32.c"> RelativePath="..\..\..\adler32.c">
</File> </File>
<File <File
RelativePath=".\compress.c"> RelativePath="..\..\..\compress.c">
</File> </File>
<File <File
RelativePath=".\crc32.c"> RelativePath="..\..\..\crc32.c">
</File> </File>
<File <File
RelativePath=".\deflate.c"> RelativePath="..\..\..\deflate.c">
</File> </File>
<File <File
RelativePath=".\gvmat32c.c"> RelativePath="..\..\masmx86\gvmat32c.c">
</File> </File>
<File <File
RelativePath=".\gzio.c"> RelativePath="..\..\..\gzio.c">
</File> </File>
<File <File
RelativePath=".\infback.c"> RelativePath="..\..\..\infback.c">
</File> </File>
<File <File
RelativePath=".\inffast.c"> RelativePath="..\..\..\inffast.c">
</File> </File>
<File <File
RelativePath=".\inflate.c"> RelativePath="..\..\..\inflate.c">
</File> </File>
<File <File
RelativePath=".\inftrees.c"> RelativePath="..\..\..\inftrees.c">
</File> </File>
<File <File
RelativePath=".\ioapi.c"> RelativePath="..\..\minizip\ioapi.c">
</File> </File>
<File <File
RelativePath=".\trees.c"> RelativePath="..\..\..\trees.c">
</File> </File>
<File <File
RelativePath=".\uncompr.c"> RelativePath="..\..\..\uncompr.c">
</File> </File>
<File <File
RelativePath=".\unzip.c"> RelativePath="..\..\minizip\unzip.c">
</File> </File>
<File <File
RelativePath=".\zip.c"> RelativePath="..\..\minizip\zip.c">
</File> </File>
<File <File
RelativePath=".\zlib.rc"> RelativePath=".\zlib.rc">
...@@ -233,7 +237,7 @@ ...@@ -233,7 +237,7 @@
RelativePath=".\zlibvc.def"> RelativePath=".\zlibvc.def">
</File> </File>
<File <File
RelativePath=".\zutil.c"> RelativePath="..\..\..\zutil.c">
</File> </File>
</Filter> </Filter>
</Files> </Files>
......
...@@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", ...@@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj",
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testZlibDll", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}"
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug ConfigName.0 = Debug
...@@ -58,6 +60,16 @@ Global ...@@ -58,6 +60,16 @@ Global
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.Build.0 = Release|Win32 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm.Build.0 = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.Build.0 = Release|Win32 {C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Debug.ActiveCfg = Debug|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Debug.Build.0 = Debug|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Release.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.Release.Build.0 = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseAxp.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseAxp.Build.0 = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutAsm.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutAsm.Build.0 = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutCrtdll.ActiveCfg = Release|Win32
{AA6666AA-E09F-4135-9C0C-4FE50C3C654C}.ReleaseWithoutCrtdll.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF" PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
RuntimeLibrary="1" RuntimeLibrary="1"
...@@ -35,7 +36,7 @@ ...@@ -35,7 +36,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="gvmat32.obj inffas32.obj" AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj"
OutputFile=".\DebugDll\zlibwapi.dll" OutputFile=".\DebugDll\zlibwapi.dll"
LinkIncremental="2" LinkIncremental="2"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
...@@ -72,10 +73,12 @@ ...@@ -72,10 +73,12 @@
IntermediateDirectory=".\zlibDllWithoutAsm" IntermediateDirectory=".\zlibDllWithoutAsm"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"> ATLMinimizesCRunTimeLibraryUsage="FALSE"
WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32,ZLIB_WINAPI" PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -134,10 +137,12 @@ ...@@ -134,10 +137,12 @@
IntermediateDirectory=".\zlibDllWithoutCrtDll" IntermediateDirectory=".\zlibDllWithoutCrtDll"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"> ATLMinimizesCRunTimeLibraryUsage="FALSE"
WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF" PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -156,7 +161,7 @@ ...@@ -156,7 +161,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="gvmat32.obj inffas32.obj " AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj "
OutputFile=".\zlibDllWithoutCrtDll\zlibwapi.dll" OutputFile=".\zlibDllWithoutCrtDll\zlibwapi.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
...@@ -196,10 +201,12 @@ ...@@ -196,10 +201,12 @@
IntermediateDirectory=".\zlibvc__" IntermediateDirectory=".\zlibvc__"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"> ATLMinimizesCRunTimeLibraryUsage="FALSE"
WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32,ZLIB_WINAPI" PreprocessorDefinitions="WIN32,ZLIB_WINAPI"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -256,10 +263,12 @@ ...@@ -256,10 +263,12 @@
IntermediateDirectory=".\ReleaseDll" IntermediateDirectory=".\ReleaseDll"
ConfigurationType="2" ConfigurationType="2"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"> ATLMinimizesCRunTimeLibraryUsage="FALSE"
WholeProgramOptimization="TRUE">
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF" PreprocessorDefinitions="WIN32,ZLIB_WINAPI,ASMV,ASMINF"
StringPooling="TRUE" StringPooling="TRUE"
ExceptionHandling="FALSE" ExceptionHandling="FALSE"
...@@ -278,7 +287,7 @@ ...@@ -278,7 +287,7 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="gvmat32.obj inffas32.obj crtdll.lib" AdditionalDependencies="..\..\masmx86\gvmat32.obj ..\..\masmx86\inffas32.obj crtdll.lib"
OutputFile=".\ReleaseDll\zlibwapi.dll" OutputFile=".\ReleaseDll\zlibwapi.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
...@@ -318,19 +327,19 @@ ...@@ -318,19 +327,19 @@
Name="Source Files" Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"> Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90">
<File <File
RelativePath=".\adler32.c"> RelativePath="..\..\..\adler32.c">
</File> </File>
<File <File
RelativePath=".\compress.c"> RelativePath="..\..\..\compress.c">
</File> </File>
<File <File
RelativePath=".\crc32.c"> RelativePath="..\..\..\crc32.c">
</File> </File>
<File <File
RelativePath=".\deflate.c"> RelativePath="..\..\..\deflate.c">
</File> </File>
<File <File
RelativePath=".\gvmat32c.c"> RelativePath="..\..\masmx86\gvmat32c.c">
<FileConfiguration <FileConfiguration
Name="ReleaseWithoutAsm|Win32" Name="ReleaseWithoutAsm|Win32"
ExcludedFromBuild="TRUE"> ExcludedFromBuild="TRUE">
...@@ -339,34 +348,34 @@ ...@@ -339,34 +348,34 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath=".\gzio.c"> RelativePath="..\..\..\gzio.c">
</File> </File>
<File <File
RelativePath=".\infback.c"> RelativePath="..\..\..\infback.c">
</File> </File>
<File <File
RelativePath=".\inffast.c"> RelativePath="..\..\..\inffast.c">
</File> </File>
<File <File
RelativePath=".\inflate.c"> RelativePath="..\..\..\inflate.c">
</File> </File>
<File <File
RelativePath=".\inftrees.c"> RelativePath="..\..\..\inftrees.c">
</File> </File>
<File <File
RelativePath=".\ioapi.c"> RelativePath="..\..\minizip\ioapi.c">
</File> </File>
<File <File
RelativePath=".\iowin32.c"> RelativePath="..\..\minizip\iowin32.c">
</File> </File>
<File <File
RelativePath=".\trees.c"> RelativePath="..\..\..\trees.c">
</File> </File>
<File <File
RelativePath=".\uncompr.c"> RelativePath="..\..\..\uncompr.c">
</File> </File>
<File <File
RelativePath=".\unzip.c"> RelativePath="..\..\minizip\unzip.c">
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32">
<Tool <Tool
...@@ -376,7 +385,7 @@ ...@@ -376,7 +385,7 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath=".\zip.c"> RelativePath="..\..\minizip\zip.c">
<FileConfiguration <FileConfiguration
Name="Release|Win32"> Name="Release|Win32">
<Tool <Tool
...@@ -392,38 +401,38 @@ ...@@ -392,38 +401,38 @@
RelativePath=".\zlibvc.def"> RelativePath=".\zlibvc.def">
</File> </File>
<File <File
RelativePath=".\zutil.c"> RelativePath="..\..\..\zutil.c">
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="Header Files" Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"> Filter="h;hpp;hxx;hm;inl;fi;fd">
<File <File
RelativePath=".\deflate.h"> RelativePath="..\..\..\deflate.h">
</File> </File>
<File <File
RelativePath=".\infblock.h"> RelativePath="..\..\..\infblock.h">
</File> </File>
<File <File
RelativePath=".\infcodes.h"> RelativePath="..\..\..\infcodes.h">
</File> </File>
<File <File
RelativePath=".\inffast.h"> RelativePath="..\..\..\inffast.h">
</File> </File>
<File <File
RelativePath=".\inftrees.h"> RelativePath="..\..\..\inftrees.h">
</File> </File>
<File <File
RelativePath=".\infutil.h"> RelativePath="..\..\..\infutil.h">
</File> </File>
<File <File
RelativePath=".\zconf.h"> RelativePath="..\..\..\zconf.h">
</File> </File>
<File <File
RelativePath=".\zlib.h"> RelativePath="..\..\..\zlib.h">
</File> </File>
<File <File
RelativePath=".\zutil.h"> RelativePath="..\..\..\zutil.h">
</File> </File>
</Filter> </Filter>
<Filter <Filter
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# test works out-of-the-box, installs `somewhere' on demand # test works out-of-the-box, installs `somewhere' on demand
# Toolflags: # Toolflags:
CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah
C++flags = -c -depend !Depend -IC: -throwback C++flags = -c -depend !Depend -IC: -throwback
Linkflags = -aif -c++ -o $@ Linkflags = -aif -c++ -o $@
ObjAsmflags = -throwback -NoCache -depend !Depend ObjAsmflags = -throwback -NoCache -depend !Depend
CMHGflags = CMHGflags =
LibFileflags = -c -l -o $@ LibFileflags = -c -l -o $@
Squeezeflags = -o $@ Squeezeflags = -o $@
# change the line below to where _you_ want the library installed. # change the line below to where _you_ want the library installed.
...@@ -17,10 +17,10 @@ libdest = lib:zlib ...@@ -17,10 +17,10 @@ libdest = lib:zlib
# Final targets: # Final targets:
@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ @.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
@.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
@.o.uncompr @.o.zutil @.o.uncompr @.o.zutil
LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
@.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
@.o.trees @.o.uncompr @.o.zutil @.o.trees @.o.uncompr @.o.zutil
test: @.minigzip @.example @.lib test: @.minigzip @.example @.lib
@copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV
@echo running tests: hang on. @echo running tests: hang on.
...@@ -41,9 +41,9 @@ test: @.minigzip @.example @.lib ...@@ -41,9 +41,9 @@ test: @.minigzip @.example @.lib
@/@.example @.fred @.fred @/@.example @.fred @.fred
@echo that will have given lots of hello!'s. @echo that will have given lots of hello!'s.
@.minigzip: @.o.minigzip @.lib C:o.Stubs @.minigzip: @.o.minigzip @.lib C:o.Stubs
Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
@.example: @.o.example @.lib C:o.Stubs @.example: @.o.example @.lib C:o.Stubs
Link $(Linkflags) @.o.example @.lib C:o.Stubs Link $(Linkflags) @.o.example @.lib C:o.Stubs
install: @.lib install: @.lib
......
This directory contains files that have not been updated for zlib 1.2.1 This directory contains files that have not been updated for zlib 1.2.x
(Volunteers are encouraged to help clean this up. Thanks.) (Volunteers are encouraged to help clean this up. Thanks.)
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
<QPG:Files> <QPG:Files>
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/> <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
<QPG:Add file="../libz.so.1.2.1" install="/opt/lib/" user="root:bin" permission="644"/> <QPG:Add file="../libz.so.1.2.3" install="/opt/lib/" user="root:bin" permission="644"/>
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.1"/> <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.3"/>
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.1"/> <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.3"/>
<QPG:Add file="../libz.so.1.2.1" install="/opt/lib/" component="slib"/> <QPG:Add file="../libz.so.1.2.3" install="/opt/lib/" component="slib"/>
</QPG:Files> </QPG:Files>
<QPG:PackageFilter> <QPG:PackageFilter>
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
</QPM:ProductDescription> </QPM:ProductDescription>
<QPM:ReleaseDescription> <QPM:ReleaseDescription>
<QPM:ReleaseVersion>1.2.1</QPM:ReleaseVersion> <QPM:ReleaseVersion>1.2.3</QPM:ReleaseVersion>
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency> <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
<QPM:ReleaseStability>Stable</QPM:ReleaseStability> <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor> <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
</QPM:Script> </QPM:Script>
</QPM:ProductInstallationProcedure> </QPM:ProductInstallationProcedure>
</QPM:PackageManifest> </QPM:PackageManifest>
<QPM:Launch> <QPM:Launch>
</QPM:Launch> </QPM:Launch>
</QPG:PackageFilter> </QPG:PackageFilter>
...@@ -119,7 +119,7 @@ ...@@ -119,7 +119,7 @@
</QPM:OrderDependency> </QPM:OrderDependency>
</QPM:ProductInstallationProcedure> </QPM:ProductInstallationProcedure>
</QPM:PackageManifest> </QPM:PackageManifest>
<QPM:Launch> <QPM:Launch>
</QPM:Launch> </QPM:Launch>
</QPG:PackageFilter> </QPG:PackageFilter>
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
</QPM:OrderDependency> </QPM:OrderDependency>
</QPM:ProductInstallationProcedure> </QPM:ProductInstallationProcedure>
</QPM:PackageManifest> </QPM:PackageManifest>
<QPM:Launch> <QPM:Launch>
</QPM:Launch> </QPM:Launch>
</QPG:PackageFilter> </QPG:PackageFilter>
......
...@@ -12,7 +12,7 @@ in the zlib distribution, or at the following location: ...@@ -12,7 +12,7 @@ in the zlib distribution, or at the following location:
1. What is ZLIB1.DLL, and how can I get it? 1. What is ZLIB1.DLL, and how can I get it?
- ZLIB1.DLL is the official build of zlib as a DLL. - ZLIB1.DLL is the official build of zlib as a DLL.
(Please remark the symbol '1' in the name.) (Please remark the character '1' in the name.)
Pointers to a precompiled ZLIB1.DLL can be found in the zlib Pointers to a precompiled ZLIB1.DLL can be found in the zlib
web site at: web site at:
...@@ -37,20 +37,19 @@ in the zlib distribution, or at the following location: ...@@ -37,20 +37,19 @@ in the zlib distribution, or at the following location:
and build settings. If you do build the DLL yourself, please and build settings. If you do build the DLL yourself, please
make sure that it complies with all the above requirements, make sure that it complies with all the above requirements,
and it runs with the precompiled test programs, bundled with and it runs with the precompiled test programs, bundled with
the original ZLIB1.DLL distribution and available at the zlib the original ZLIB1.DLL distribution.
web site.
If, for any reason, you need to build an incompatible DLL, If, for any reason, you need to build an incompatible DLL,
please use a different name. please use a different file name.
2. Why did you change the name of the DLL to ZLIB1.DLL? 2. Why did you change the name of the DLL to ZLIB1.DLL?
What happened to the old ZLIB.DLL? What happened to the old ZLIB.DLL?
- The old ZLIB.DLL, built from zlib-1.1.x and earlier, required - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
compilation settings that were incompatible to those used by a compilation settings that were incompatible to those used by
static build. The DLL settings were supposed to be enabled by a static build. The DLL settings were supposed to be enabled
defining the macro ZLIB_DLL, before including "zlib.h". by defining the macro ZLIB_DLL, before including "zlib.h".
Incorrect handling of this macro was silently accepted at Incorrect handling of this macro was silently accepted at
build time, resulting in two major problems: build time, resulting in two major problems:
...@@ -65,8 +64,8 @@ in the zlib distribution, or at the following location: ...@@ -65,8 +64,8 @@ in the zlib distribution, or at the following location:
functions. Failure to do so resulted in creating binaries functions. Failure to do so resulted in creating binaries
that were unable to run with the official ZLIB.DLL build. that were unable to run with the official ZLIB.DLL build.
The only possible solution that we could foresee was to make a The only possible solution that we could foresee was to make
binary-incompatible change in the DLL interfacing, in order to a binary-incompatible change in the DLL interface, in order to
remove the dependency on the ZLIB_DLL macro, and to release remove the dependency on the ZLIB_DLL macro, and to release
the new DLL under a different name. the new DLL under a different name.
...@@ -85,17 +84,13 @@ in the zlib distribution, or at the following location: ...@@ -85,17 +84,13 @@ in the zlib distribution, or at the following location:
- In principle, you can do it by assigning calling convention - In principle, you can do it by assigning calling convention
keywords to the macros ZEXPORT and ZEXPORTVA. In practice, keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
it depends on what you mean by "an old ZLIB.DLL", because it depends on what you mean by "an old ZLIB.DLL", because the
the old DLL exists in several mutually-incompatible versions. old DLL exists in several mutually-incompatible versions.
You have to find out first what kind of calling convention is
If you have a compiled application that works with a certain being used in your particular ZLIB.DLL build, and to use the
ZLIB.DLL without any known security issues, there is hardly same one in the new build. If you don't know what this is all
a need to rebuild the DLL from new sources only to link it to about, you might be better off if you would just leave the old
the old app binary. But if you really want to do it, you have DLL intact.
to find out first what kind of calling convention uses your
particular ZLIB.DLL build, and to use the same one in the new
build. If you don't know what this is all about, you might be
better off if you would just forget it.
4. Can I compile my application using the new zlib interface, and 4. Can I compile my application using the new zlib interface, and
...@@ -170,19 +165,19 @@ in the zlib distribution, or at the following location: ...@@ -170,19 +165,19 @@ in the zlib distribution, or at the following location:
the K&R-style function prototypes, where the argument types the K&R-style function prototypes, where the argument types
are not specified; but that is another story for another day. are not specified; but that is another story for another day.
The fact that remains is that CDECL is the default convention. The remaining fact is that CDECL is the default convention.
Even if an explicit convention (such as STDCALL or FASTCALL) Even if an explicit convention is hard-coded into the function
is hard-coded into the function prototypes inside C headers, prototypes inside C headers, problems may appear. The
problems may appear. One problem, for example, deals with the necessity to expose the convention in users' callbacks is one
necessity to expose the convention in users' callbacks. of these problems.
The calling convention issues are also important when using The calling convention issues are also important when using
zlib in other programming languages. Some of them, like Ada zlib in other programming languages. Some of them, like Ada
(GNAT) and Fortran (GNU G77), have C bindings implemented (GNAT) and Fortran (GNU G77), have C bindings implemented
initially on Unix, and relying on the C calling convention. initially on Unix, and relying on the C calling convention.
On the other hand, the pre- .NET versions of Microsoft Visual On the other hand, the pre- .NET versions of Microsoft Visual
Basic require STDCALL, while Borland Delphi prefers (although Basic require STDCALL, while Borland Delphi prefers, although
it does not require) FASTCALL. it does not require, FASTCALL.
In fairness to all possible uses of zlib outside the C In fairness to all possible uses of zlib outside the C
programming language, we choose the default "C" convention. programming language, we choose the default "C" convention.
...@@ -208,7 +203,14 @@ in the zlib distribution, or at the following location: ...@@ -208,7 +203,14 @@ in the zlib distribution, or at the following location:
zlib distribution. zlib distribution.
8. If my application uses ZLIB1.DLL, should I link it to 8. I need to use zlib in my Microsoft .NET project. What can I
do?
- Henrik Ravn has contributed a .NET wrapper around zlib. Look
into contrib/dotzlib/, inside the zlib distribution.
9. If my application uses ZLIB1.DLL, should I link it to
MSVCRT.DLL? Why? MSVCRT.DLL? Why?
- It is not required, but it is recommended to link your - It is not required, but it is recommended to link your
...@@ -223,8 +225,8 @@ in the zlib distribution, or at the following location: ...@@ -223,8 +225,8 @@ in the zlib distribution, or at the following location:
depend on it should also be linked to MSVCRT.DLL. depend on it should also be linked to MSVCRT.DLL.
9. Why are you saying that ZLIB1.DLL and my application must be 10. Why are you saying that ZLIB1.DLL and my application should
linked to the same C run-time (CRT) library? I linked my be linked to the same C run-time (CRT) library? I linked my
application and my DLLs to different C libraries (e.g. my application and my DLLs to different C libraries (e.g. my
application to a static library, and my DLLs to MSVCRT.DLL), application to a static library, and my DLLs to MSVCRT.DLL),
and everything works fine. and everything works fine.
...@@ -255,11 +257,11 @@ in the zlib distribution, or at the following location: ...@@ -255,11 +257,11 @@ in the zlib distribution, or at the following location:
and DLLs are avoiding the corruption of each of the CRTs' and DLLs are avoiding the corruption of each of the CRTs'
internal states, maybe by careful design, or maybe by fortune. internal states, maybe by careful design, or maybe by fortune.
Also note that linking ZLIB1.DLL to non-Microsoft CRTs (such Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
as those provided by Borland) raises similar problems. as those provided by Borland, raises similar problems.
10. Why are you linking ZLIB1.DLL to MSVCRT.DLL? 11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
- MSVCRT.DLL exists on every Windows 95 with a new service pack - MSVCRT.DLL exists on every Windows 95 with a new service pack
installed, or with Microsoft Internet Explorer 4 or later, and installed, or with Microsoft Internet Explorer 4 or later, and
...@@ -269,21 +271,14 @@ in the zlib distribution, or at the following location: ...@@ -269,21 +271,14 @@ in the zlib distribution, or at the following location:
software provider for free. software provider for free.
The fact that MSVCRT.DLL does not exist on a virgin Windows 95 The fact that MSVCRT.DLL does not exist on a virgin Windows 95
is not so problematic. The number of Windows 95 installations is not so problematic. Windows 95 is scarcely found nowadays,
is rapidly decreasing, Microsoft stopped supporting it a long Microsoft ended its support a long time ago, and many recent
time ago, and many recent applications from various vendors, applications from various vendors, including Microsoft, do not
including Microsoft, do not even run on it. Furthermore, no even run on it. Furthermore, no serious user should run
serious user should run Windows 95 without a proper update Windows 95 without a proper update installed.
installed.
There is also the fact that the mainstream C compilers for
Windows are Microsoft Visual C++ 6.0, and gcc/MinGW. Both
are producing executables that link to MSVCRT.DLL by default,
without offering other dynamic CRTs as alternatives easy to
select by users.
11. Why are you not linking ZLIB1.DLL to 12. Why are you not linking ZLIB1.DLL to
<<my favorite C run-time library>> ? <<my favorite C run-time library>> ?
- We considered and abandoned the following alternatives: - We considered and abandoned the following alternatives:
...@@ -294,27 +289,60 @@ in the zlib distribution, or at the following location: ...@@ -294,27 +289,60 @@ in the zlib distribution, or at the following location:
to a static C library, you may as well consider linking zlib to a static C library, you may as well consider linking zlib
in statically, too. in statically, too.
* Linking ZLIB1.DLL to CRTDLL.DLL looks very appealing, * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
because CRTDLL.DLL is present on every Win32 installation. CRTDLL.DLL is present on every Win32 installation.
Unfortunately, it has a series of problems: it raises Unfortunately, it has a series of problems: it does not
difficulties when using it with C++ code, it does not work work properly with Microsoft's C++ libraries, it does not
with 64-bit file offsets, (and so on...), and Microsoft provide support for 64-bit file offsets, (and so on...),
discontinued its support a long time ago. and Microsoft discontinued its support a long time ago.
* Linking ZLIB1.DLL to MSVCR70.DLL, supplied with the * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
Microsoft .NET platform and Visual C++ 7.0 or newer, is not with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
a good option. Although it is available for free download raises problems related to the status of ZLIB1.DLL as a
and distribution, its presence is scarce on today's Win32 system component. According to the Microsoft Knowledge Base
installations. If it will ever become more popular than article KB326922 "INFO: Redistribution of the Shared C
MSVCRT.DLL and will be pre-installed on the future Win32 Runtime Component in Visual C++ .NET", MSVCR70.DLL and
systems, we will probably think again about it. MSVCR71.DLL are not supposed to function as system DLLs,
because they may clash with MSVCRT.DLL. Instead, the
* Linking ZLIB1.DLL to NTDLL.DLL is not possible. application's installer is supposed to put these DLLs
NTDLL.DLL exports only a part of the C library, and only on (if needed) in the application's private directory.
Windows NT systems. If ZLIB1.DLL depends on a non-system runtime, it cannot
function as a redistributable system component.
12. I need to link my own DLL build to a CRT different than * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
Borland's, or Cygwin's, raises problems related to the
reliable presence of these runtimes on Win32 systems.
It's easier to let the DLL build of zlib up to the people
who distribute these runtimes, and who may proceed as
explained in the answer to Question 14.
13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
(Visual Studio .NET) or newer?
- Due to the problems explained in the Microsoft Knowledge Base
article KB326922 (see the previous answer), the C runtime that
comes with the VC7 environment is no longer considered a
system component. That is, it should not be assumed that this
runtime exists, or may be installed in a system directory.
Since ZLIB1.DLL is supposed to be a system component, it may
not depend on a non-system component.
In order to link ZLIB1.DLL and your application to MSVCRT.DLL
in VC7, you need the library of Visual C++ 6.0 or older. If
you don't have this library at hand, it's probably best not to
use ZLIB1.DLL.
We are hoping that, in the future, Microsoft will provide a
way to build applications linked to a proper system runtime,
from the Visual C++ environment. Until then, you have a
couple of alternatives, such as linking zlib in statically.
If your application requires dynamic linking, you may proceed
as explained in the answer to Question 14.
14. I need to link my own DLL build to a CRT different than
MSVCRT.DLL. What can I do? MSVCRT.DLL. What can I do?
- Feel free to rebuild the DLL from the zlib sources, and link - Feel free to rebuild the DLL from the zlib sources, and link
...@@ -330,7 +358,7 @@ in the zlib distribution, or at the following location: ...@@ -330,7 +358,7 @@ in the zlib distribution, or at the following location:
CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
13. May I include additional pieces of code that I find useful, 15. May I include additional pieces of code that I find useful,
link them in ZLIB1.DLL, and export them? link them in ZLIB1.DLL, and export them?
- No. A legitimate build of ZLIB1.DLL must not include code - No. A legitimate build of ZLIB1.DLL must not include code
...@@ -338,14 +366,12 @@ in the zlib distribution, or at the following location: ...@@ -338,14 +366,12 @@ in the zlib distribution, or at the following location:
But you can make your own private DLL build, under a different But you can make your own private DLL build, under a different
file name, as suggested in the previous answer. file name, as suggested in the previous answer.
For example, in Borland Delphi and C++ Builder, zlib is a part For example, zlib is a part of the VCL library, distributed
of the standard VCL library. If an application links to VCL with Borland Delphi and C++ Builder. The DLL build of VCL
dynamically, the name of the distributable binary (VCLxx.DLL) is a redistributable file, named VCLxx.DLL.
does not posess any danger of clashing with a legitimate but
incompatible ZLIB1.DLL.
14. May I remove some functionality out of ZLIB1.DLL, by enabling 16. May I remove some functionality out of ZLIB1.DLL, by enabling
macros like NO_GZCOMPRESS or NO_GZIP at compile time? macros like NO_GZCOMPRESS or NO_GZIP at compile time?
- No. A legitimate build of ZLIB1.DLL must provide the complete - No. A legitimate build of ZLIB1.DLL must provide the complete
...@@ -354,7 +380,7 @@ in the zlib distribution, or at the following location: ...@@ -354,7 +380,7 @@ in the zlib distribution, or at the following location:
different file name, as suggested in the previous answer. different file name, as suggested in the previous answer.
15. I made my own ZLIB1.DLL build. Can I test it for compliance? 17. I made my own ZLIB1.DLL build. Can I test it for compliance?
- We prefer that you download the official DLL from the zlib - We prefer that you download the official DLL from the zlib
web site. If you need something peculiar from this DLL, you web site. If you need something peculiar from this DLL, you
......
...@@ -5,8 +5,8 @@ VS_VERSION_INFO VERSIONINFO ...@@ -5,8 +5,8 @@ VS_VERSION_INFO VERSIONINFO
#else #else
VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
#endif #endif
FILEVERSION 1,2,1,0 FILEVERSION 1,2,2,0
PRODUCTVERSION 1,2,1,0 PRODUCTVERSION 1,2,2,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 1 FILEFLAGS 1
...@@ -23,12 +23,12 @@ BEGIN ...@@ -23,12 +23,12 @@ BEGIN
//language ID = U.S. English, char set = Windows, Multilingual //language ID = U.S. English, char set = Windows, Multilingual
BEGIN BEGIN
VALUE "FileDescription", "zlib data compression library\0" VALUE "FileDescription", "zlib data compression library\0"
VALUE "FileVersion", "1.2.1\0" VALUE "FileVersion", "1.2.3\0"
VALUE "InternalName", "zlib1.dll\0" VALUE "InternalName", "zlib1.dll\0"
VALUE "LegalCopyright", "(C) 1995-2003 Jean-loup Gailly & Mark Adler\0" VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
VALUE "OriginalFilename", "zlib1.dll\0" VALUE "OriginalFilename", "zlib1.dll\0"
VALUE "ProductName", "zlib\0" VALUE "ProductName", "zlib\0"
VALUE "ProductVersion", "1.2.1\0" VALUE "ProductVersion", "1.2.3\0"
VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0" VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
END END
END END
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment