[PATCH] d3dxof: Decompress all MSZIP chunks of the compressed file and update file format description
Christian Costa
titan.costa at gmail.com
Thu Feb 16 17:19:12 CST 2012
Fix first problem of bug 24751
---
dlls/d3dxof/parsing.c | 60 +++++++++++++++++++++++++++++++-------------
dlls/d3dxof/tests/d3dxof.c | 9 ++++---
2 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/dlls/d3dxof/parsing.c b/dlls/d3dxof/parsing.c
index 4b9b12f..f177e0a 100644
--- a/dlls/d3dxof/parsing.c
+++ b/dlls/d3dxof/parsing.c
@@ -220,40 +220,64 @@ HRESULT parse_header(parse_buffer * buf, BYTE ** decomp_buffer_ptr)
if (header[2] == XOFFILE_FORMAT_BINARY_MSZIP || header[2] == XOFFILE_FORMAT_TEXT_MSZIP)
{
/* Extended header for compressed data:
- * 16-17 -> decompressed size w/ header, 18-19 -> null,
- * 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
- * 24-xx -> compressed MSZIP data */
+ * 16-19 -> size of decompressed file including xof header,
+ * 20-21 -> size of first decompressed MSZIP chunk, 22-23 -> size of first compressed MSZIP chunk
+ * 24-xx -> compressed MSZIP data chunk
+ * xx-xx -> size of next decompressed MSZIP chunk, xx-xx -> size of next compressed MSZIP chunk
+ * xx-xx -> compressed MSZIP data chunk
+ * .............................................................................................. */
int err;
- WORD decomp_size;
- WORD comp_size;
+ DWORD decomp_file_size;
+ WORD decomp_chunk_size;
+ WORD comp_chunk_size;
LPBYTE decomp_buffer;
- buf->rem_bytes -= sizeof(WORD) * 2;
- buf->buffer += sizeof(WORD) * 2;
- if (!read_bytes(buf, &decomp_size, sizeof(decomp_size)))
- return DXFILEERR_BADFILETYPE;
- if (!read_bytes(buf, &comp_size, sizeof(comp_size)))
+ if (!read_bytes(buf, &decomp_file_size, sizeof(decomp_file_size)))
return DXFILEERR_BADFILETYPE;
- TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
- debugstr_fourcc(header[2]), comp_size, decomp_size);
+ TRACE("Compressed format %s detected: decompressed file size with xof header = %d\n",
+ debugstr_fourcc(header[2]), decomp_file_size);
+
+ /* Does not take xof header into account */
+ decomp_file_size -= 16;
- decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
+ decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_file_size);
if (!decomp_buffer)
{
ERR("Out of memory\n");
return DXFILEERR_BADALLOC;
}
- err = mszip_decompress(comp_size, decomp_size, (char*)buf->buffer, (char*)decomp_buffer);
- if (err)
+ *decomp_buffer_ptr = decomp_buffer;
+
+ while (buf->rem_bytes)
{
- WARN("Error while decompressing mszip archive %d\n", err);
+ if (!read_bytes(buf, &decomp_chunk_size, sizeof(decomp_chunk_size)))
+ return DXFILEERR_BADFILETYPE;
+ if (!read_bytes(buf, &comp_chunk_size, sizeof(comp_chunk_size)))
+ return DXFILEERR_BADFILETYPE;
+
+ TRACE("Process chunk: compressed_size = %d, decompressed_size = %d\n",
+ comp_chunk_size, decomp_chunk_size);
+
+ err = mszip_decompress(comp_chunk_size, decomp_chunk_size, (char*)buf->buffer, (char*)decomp_buffer);
+ if (err)
+ {
+ WARN("Error while decompressing MSZIP chunk %d\n", err);
HeapFree(GetProcessHeap(), 0, decomp_buffer);
return DXFILEERR_BADALLOC;
+ }
+ buf->rem_bytes -= comp_chunk_size;
+ buf->buffer += comp_chunk_size;
+ decomp_buffer += decomp_chunk_size;
}
+
+ if ((decomp_buffer - *decomp_buffer_ptr) != decomp_file_size)
+ ERR("Size of all decompressed chunks (%d) does not match decompressed file size (%d)\n",
+ decomp_buffer - *decomp_buffer_ptr, decomp_file_size);
+
/* Use decompressed data */
- buf->buffer = *decomp_buffer_ptr = decomp_buffer;
- buf->rem_bytes = decomp_size;
+ buf->buffer = *decomp_buffer_ptr;
+ buf->rem_bytes = decomp_file_size;
}
TRACE("Header is correct\n");
diff --git a/dlls/d3dxof/tests/d3dxof.c b/dlls/d3dxof/tests/d3dxof.c
index 8ce22b7..5c6315a 100644
--- a/dlls/d3dxof/tests/d3dxof.c
+++ b/dlls/d3dxof/tests/d3dxof.c
@@ -74,11 +74,12 @@ static char empty_bin_file[] = "xof 0302bin 0064";
/* MSZip data is generated with the command "MAKECAB.EXE /D Compress=ON /D CompressionType=MSZip file packed"
* Data in cab is after the filename (null terminated) and the 32-bit checksum:
* size (16-bit), packed_size (16-bit) and compressed data (with leading 16-bit CK signature)
- * Data in x files is preceding by 2 16-bit words: size with xof header (16 bytes) and a 0 value
- * It does not seem possible to generate a MSZip data with no byte, so put just 1 byte here */
-/* "\n" packed with MSZip => not text */
+ * for each MSZIP chunk whose decompressed size can not exceed 32768 bytes
+ * Data in x files is preceeding by the size (32-bit) of the decompressed file including the xof header (16 bytes)
+ * It does not seem possible to generate a MSZip data chunk with no byte, so put just 1 byte here */
+/* "\n" packed with MSZip => no text */
static char empty_tzip_file[] = "xof 0302tzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
-/* "\n" packed with MSZip => not token (token are 16-bit and there is only 1 byte) */
+/* "\n" packed with MSZip => no token (token are 16-bit and there is only 1 byte) */
static char empty_bzip_file[] = "xof 0302bzip0064\x11\x00\x00\x00\x01\x00\x05\x00\x43\x4b\xe3\x02\x00";
static char empty_cmp_file[] = "xof 0302cmp 0064";
static char empty_xxxx_file[] = "xof 0302xxxx0064";
More information about the wine-patches
mailing list