Alexandre Julliard : cabinet: Add support for MSZIP compression.
Alexandre Julliard
julliard at winehq.org
Fri Feb 18 10:50:16 CST 2011
Module: wine
Branch: master
Commit: e1a0ef7ef8922a029a0d26c5bb9b37fe131c8f60
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e1a0ef7ef8922a029a0d26c5bb9b37fe131c8f60
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Feb 18 00:15:44 2011 +0100
cabinet: Add support for MSZIP compression.
---
dlls/cabinet/Makefile.in | 1 +
dlls/cabinet/fci.c | 55 ++++++++++++++++++++++++++++++++++++++++++---
dlls/cabinet/tests/fdi.c | 4 +--
3 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/dlls/cabinet/Makefile.in b/dlls/cabinet/Makefile.in
index 7a1ad9d..2876936 100644
--- a/dlls/cabinet/Makefile.in
+++ b/dlls/cabinet/Makefile.in
@@ -1,5 +1,6 @@
MODULE = cabinet.dll
IMPORTLIB = cabinet
+EXTRALIBS = @ZLIB@
C_SRCS = \
cabinet_main.c \
diff --git a/dlls/cabinet/fci.c b/dlls/cabinet/fci.c
index f1d6a80..55a024a 100644
--- a/dlls/cabinet/fci.c
+++ b/dlls/cabinet/fci.c
@@ -24,11 +24,9 @@
There is still some work to be done:
-- no real compression yet
- unknown behaviour if files>=2GB or cabinet >=4GB
- check if the maximum size for a cabinet is too small to store any data
- call pfnfcignc on exactly the same position as MS FCIAddFile in every case
-- probably check err
*/
@@ -40,6 +38,9 @@ There is still some work to be done:
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#ifdef HAVE_ZLIB
+# include <zlib.h>
+#endif
#include "windef.h"
#include "winbase.h"
@@ -166,9 +167,9 @@ typedef struct FCI_Int
void *pv;
char szPrevCab[CB_MAX_CABINET_NAME]; /* previous cabinet name */
char szPrevDisk[CB_MAX_DISK_NAME]; /* disk name of previous cabinet */
- char* data_in; /* uncompressed data blocks */
+ unsigned char *data_in; /* uncompressed data blocks */
cab_UWORD cdata_in;
- char* data_out; /* compressed data blocks */
+ unsigned char *data_out; /* compressed data blocks */
ULONG cCompressedBytesInFolder;
cab_UWORD cFolders;
cab_UWORD cFiles;
@@ -945,6 +946,46 @@ static cab_UWORD compress_NONE( FCI_Int *fci )
return fci->cdata_in;
}
+#ifdef HAVE_ZLIB
+
+static void *zalloc( void *opaque, unsigned int items, unsigned int size )
+{
+ FCI_Int *fci = opaque;
+ return fci->alloc( items * size );
+}
+
+static void zfree( void *opaque, void *ptr )
+{
+ FCI_Int *fci = opaque;
+ return fci->free( ptr );
+}
+
+static cab_UWORD compress_MSZIP( FCI_Int *fci )
+{
+ z_stream stream;
+
+ stream.zalloc = zalloc;
+ stream.zfree = zfree;
+ stream.opaque = fci;
+ if (deflateInit2( &stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY ) != Z_OK)
+ {
+ set_error( fci, FCIERR_ALLOC_FAIL, ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
+ }
+ stream.next_in = fci->data_in;
+ stream.avail_in = fci->cdata_in;
+ stream.next_out = fci->data_out + 2;
+ stream.avail_out = 2 * CB_MAX_CHUNK - 2;
+ /* insert the signature */
+ fci->data_out[0] = 'C';
+ fci->data_out[1] = 'K';
+ deflate( &stream, Z_FINISH );
+ deflateEnd( &stream );
+ return stream.total_out + 2;
+}
+
+#endif /* HAVE_ZLIB */
+
/***********************************************************************
* FCICreate (CABINET.10)
@@ -1441,6 +1482,12 @@ BOOL __cdecl FCIAddFile(
if (!FCIFlushFolder( hfci, pfnfcignc, pfnfcis )) return FALSE;
switch (typeCompress)
{
+ case tcompTYPE_MSZIP:
+#ifdef HAVE_ZLIB
+ p_fci_internal->compression = tcompTYPE_MSZIP;
+ p_fci_internal->compress = compress_MSZIP;
+ break;
+#endif
default:
FIXME( "compression %x not supported, defaulting to none\n", typeCompress );
/* fall through */
diff --git a/dlls/cabinet/tests/fdi.c b/dlls/cabinet/tests/fdi.c
index 19f9e29..b3f70bf 100644
--- a/dlls/cabinet/tests/fdi.c
+++ b/dlls/cabinet/tests/fdi.c
@@ -581,11 +581,9 @@ static void test_FDIIsCabinet(void)
ok(cabinfo.cFiles == 4, "Expected 4, got %d\n", cabinfo.cFiles);
ok(cabinfo.cFolders == 1, "Expected 1, got %d\n", cabinfo.cFolders);
ok(cabinfo.setID == 0xbeef, "Expected 0xbeef, got %d\n", cabinfo.setID);
+ ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
todo_wine
- {
- ok(cabinfo.cbCabinet == 182, "Expected 182, got %d\n", cabinfo.cbCabinet);
ok(cabinfo.iCabinet == 0, "Expected 0, got %d\n", cabinfo.iCabinet);
- }
fdi_close(fd);
FDIDestroy(hfdi);
More information about the wine-cvs
mailing list