Commit 46d4bec2 authored by Christian Costa's avatar Christian Costa Committed by Alexandre Julliard

d3dxof: Decompress all MSZIP chunks of the compressed file and update file format description.

parent f07317fe
......@@ -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);
*decomp_buffer_ptr = decomp_buffer;
while (buf->rem_bytes)
{
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 archive %d\n", 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 (%u) does not match decompressed file size (%u)\n",
(DWORD)(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");
......
......@@ -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";
......
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