Browse Source

--- Merging r22282 into '.':
U packages/paszlib/src/zipper.pp
--- Merging r22298 into '.':
G packages/paszlib/src/zipper.pp
--- Merging r22372 into '.':
G packages/paszlib/src/zipper.pp

# revisions: 22282,2284,2285,22298,22372
r22282 | nickysn | 2012-09-02 17:36:03 +0200 (Sun, 02 Sep 2012) | 1 line
Changed paths:
M /trunk/packages/paszlib/src/zipper.pp

+ set the minimum required zip version for each file according to the compression algorithm used
fetching log for rev 2284 - 502 characters
r2284 | florian | 2006-01-14 14:11:28 +0100 (Sat, 14 Jan 2006) | 8 lines
Changed paths:
M /branches/fixes_2_0
M /branches/fixes_2_0/fcl/passrc/pscanner.pp
M /branches/fixes_2_0/utils/fpdoc/dw_html.pp

Merged revisions 2283 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

r2283 (florian)
+ >< support for fpdoc from Vincent Snijders
fetching log for rev 2285 - 371 characters
r2285 | jonas | 2006-01-14 15:09:39 +0100 (Sat, 14 Jan 2006) | 2 lines
Changed paths:
M /trunk/compiler/pstatmnt.pas
A /trunk/tests/webtbf/tw4695.pp

* check whether loop counters are valid for assignment (bug 4695)
r22298 | florian | 2012-09-03 14:34:16 +0200 (Mon, 03 Sep 2012) | 1 line
Changed paths:
M /trunk/packages/paszlib/src/zipper.pp

* fix building of zipper.pp as suggested by Jeppe Johansen
r22372 | nickysn | 2012-09-11 23:22:34 +0200 (Tue, 11 Sep 2012) | 1 line
Changed paths:
M /trunk/packages/paszlib/src/zipper.pp

TZipper: set the compression level bit flag in the file header of deflate compressed files

git-svn-id: branches/fixes_2_6@22536 -

marco 13 years ago
parent
commit
f7c8073b54
1 changed files with 58 additions and 13 deletions
  1. 58 13
      packages/paszlib/src/zipper.pp

+ 58 - 13
packages/paszlib/src/zipper.pp

@@ -136,6 +136,8 @@ Type
     Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord); virtual;
     Procedure Compress; Virtual; Abstract;
     Class Function ZipID : Word; virtual; Abstract;
+    Class Function ZipVersionReqd: Word; virtual; Abstract;
+    Function ZipBitFlag: Word; virtual; Abstract;
     Property BufferSize : LongWord read FBufferSize;
     Property OnPercent : Integer Read FOnPercent Write FOnPercent;
     Property OnProgress : TProgressEvent Read FOnProgress Write FOnProgress;
@@ -226,6 +228,8 @@ Type
     Destructor Destroy; override;
     Procedure Compress; override;
     Class Function ZipID : Word; override;
+    Class Function ZipVersionReqd : Word; override;
+    Function ZipBitFlag : Word; override;
   end;
 
   { TDeflater }
@@ -237,6 +241,8 @@ Type
     Constructor Create(AInFile, AOutFile : TStream; ABufSize : LongWord);override;
     Procedure Compress; override;
     Class Function ZipID : Word; override;
+    Class Function ZipVersionReqd : Word; override;
+    Function ZipBitFlag : Word; override;
     Property CompressionLevel : TCompressionlevel Read FCompressionLevel Write FCompressionLevel;
   end;
 
@@ -319,7 +325,7 @@ Type
   Protected
     Procedure CloseInput(Item : TZipFileEntry);
     Procedure StartZipFile(Item : TZipFileEntry);
-    Function  UpdateZipHeader(Item : TZipFileEntry; FZip : TStream; ACRC : LongWord;AMethod : Word) : Boolean;
+    Function  UpdateZipHeader(Item : TZipFileEntry; FZip : TStream; ACRC : LongWord;AMethod : Word; AZipVersionReqd : Word; AZipBitFlag : Word) : Boolean;
     Procedure BuildZipDirectory;
     Procedure DoEndOfFile;
     Procedure ZipOneFile(Item : TZipFileEntry); virtual;
@@ -675,8 +681,8 @@ Var
 begin
   CRC32Val:=$FFFFFFFF;
   Buf:=GetMem(FBufferSize);
-  if FOnPercent = 0 then 
-    FOnPercent := 1; 
+  if FOnPercent = 0 then
+    FOnPercent := 1;
   OnBytes:=Round((FInFile.Size * FOnPercent) / 100);
   BytesNow:=0; NextMark := OnBytes;
   FSize:=FInfile.Size;
@@ -698,7 +704,7 @@ begin
             if (FSize>0) and assigned(FOnProgress) Then
               FOnProgress(self,100 * ( BytesNow / FSize));
             inc(NextMark,OnBytes);
-          end;   
+          end;
       Until (Count=0);
     Finally
       C.Free;
@@ -716,6 +722,23 @@ begin
   Result:=8;
 end;
 
+class function TDeflater.ZipVersionReqd: Word;
+begin
+  Result:=20;
+end;
+
+function TDeflater.ZipBitFlag: Word;
+begin
+  case CompressionLevel of
+    clnone: Result := %110;
+    clfastest: Result := %100;
+    cldefault: Result := %000;
+    clmax: Result := %010;
+    else
+      Result := 0;
+  end;
+end;
+
 { ---------------------------------------------------------------------
     TInflater
   ---------------------------------------------------------------------}
@@ -853,6 +876,16 @@ begin
   Result:=1;
 end;
 
+class function TShrinker.ZipVersionReqd: Word;
+begin
+  Result:=10;
+end;
+
+function TShrinker.ZipBitFlag: Word;
+begin
+  Result:=0;
+end;
+
 
 Procedure TShrinker.DoOnProgress(Const Pct: Double);
 
@@ -1251,7 +1284,9 @@ Begin
 End;
 
 
-Function TZipper.UpdateZipHeader(Item : TZipFileEntry; FZip : TStream; ACRC : LongWord; AMethod : Word) : Boolean;
+function TZipper.UpdateZipHeader(Item: TZipFileEntry; FZip: TStream;
+  ACRC: LongWord; AMethod: Word; AZipVersionReqd: Word; AZipBitFlag: Word
+  ): Boolean;
 var
   ZFileName  : ShortString;
 Begin
@@ -1259,14 +1294,20 @@ Begin
   With LocalHdr do
     begin
     FileName_Length := Length(ZFileName);
-    Compressed_Size := FZip.Size;
     Crc32 := ACRC;
-    Compress_method:=AMethod;
     Result:=Not (Compressed_Size >= Uncompressed_Size);
     If Not Result then
       begin                     { No...                          }
       Compress_Method := 0;                  { ...change stowage type      }
       Compressed_Size := Uncompressed_Size;  { ...update compressed size   }
+      end
+    else
+      begin
+      Compress_method:=AMethod;
+      Compressed_Size := FZip.Size;
+      Bit_Flag := Bit_Flag or AZipBitFlag;
+      if AZipVersionReqd > Extract_Version_Reqd then
+        Extract_Version_Reqd := AZipVersionReqd;
       end;
     end;
   FOutStream.WriteBuffer({$IFDEF ENDIAN_BIG}SwapLFH{$ENDIF}(LocalHdr),SizeOf(LocalHdr));
@@ -1356,6 +1397,8 @@ Procedure TZipper.ZipOneFile(Item : TZipFileEntry);
 Var
   CRC : LongWord;
   ZMethod : Word;
+  ZVersionReqd : Word;
+  ZBitFlag : Word;
   ZipStream : TStream;
   TmpFileName : String;
 
@@ -1378,10 +1421,12 @@ Begin
           Compress;
           CRC:=Crc32Val;
           ZMethod:=ZipID;
+          ZVersionReqd:=ZipVersionReqd;
+          ZBitFlag:=ZipBitFlag;
         Finally
           Free;
         end;
-      If UpdateZipHeader(Item,ZipStream,CRC,ZMethod) then
+      If UpdateZipHeader(Item,ZipStream,CRC,ZMethod,ZVersionReqd,ZBitFlag) then
         // Compressed file smaller than original file.
         FOutStream.CopyFrom(ZipStream,0)
       else
@@ -1568,8 +1613,8 @@ Begin
     as directory separator. We don't want that behaviour
     here, since 'abc\' is a valid file name under Unix.
 	
-	(mantis 15836) On the other hand, many archives on 
-	 windows have '/' as pathseparator, even Windows 
+	(mantis 15836) On the other hand, many archives on
+	 windows have '/' as pathseparator, even Windows
 	 generated .odt files. So we disable this for windows.
   }
   OldDirectorySeparators:=AllowDirectorySeparators;
@@ -1580,7 +1625,7 @@ Begin
   OutStream:=Nil;
   If Assigned(FOnCreateStream) then
     FOnCreateStream(Self, OutStream, Item);
-  // If FOnCreateStream didn't create one, we create one now.  
+  // If FOnCreateStream didn't create one, we create one now.
   If (OutStream=Nil) then
     Begin
     if (Path<>'') then
@@ -1652,7 +1697,7 @@ End;
 Procedure TUnZipper.ReadZipDirectory;
 
 Var
-  i,
+  i : LongInt;
   EndHdrPos,
   CenDirPos : LongInt;
   NewNode   : TFullZipFileEntry;
@@ -2074,7 +2119,7 @@ Procedure TZipFileEntries.AddFileEntries(Const List : TStrings);
 
 Var
   I : integer;
-  
+
 begin
   For I:=0 to List.Count-1 do
     AddFileEntry(List[i]);