mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 15:08:14 +00:00
[RTL]
sync compression functions with wine svn path=/trunk/; revision=68389
This commit is contained in:
parent
e2dc21346a
commit
d92f46f3a4
1 changed files with 42 additions and 28 deletions
|
@ -95,24 +95,21 @@ static PUCHAR lznt1_decompress_chunk(UCHAR *dst, ULONG dst_size, UCHAR *src, ULO
|
||||||
static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size,
|
static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG src_size,
|
||||||
ULONG offset, ULONG *final_size, UCHAR *workspace)
|
ULONG offset, ULONG *final_size, UCHAR *workspace)
|
||||||
{
|
{
|
||||||
UCHAR *src_cur, *src_end, *dst_cur, *dst_end, *ptr;
|
UCHAR *src_cur = src, *src_end = src + src_size;
|
||||||
|
UCHAR *dst_cur = dst, *dst_end = dst + dst_size;
|
||||||
ULONG chunk_size, block_size;
|
ULONG chunk_size, block_size;
|
||||||
WORD chunk_header;
|
WORD chunk_header;
|
||||||
|
UCHAR *ptr;
|
||||||
|
|
||||||
src_cur = src;
|
if (src_cur + sizeof(WORD) > src_end)
|
||||||
src_end = src + src_size;
|
|
||||||
dst_cur = dst;
|
|
||||||
dst_end = dst + dst_size;
|
|
||||||
|
|
||||||
if (src_cur + sizeof(WCHAR) > src_end)
|
|
||||||
return STATUS_BAD_COMPRESSION_BUFFER;
|
return STATUS_BAD_COMPRESSION_BUFFER;
|
||||||
|
|
||||||
/* skip over chunks which have a big distance (>= 0x1000) to the destination offset */
|
/* skip over chunks which have a big distance (>= 0x1000) to the destination offset */
|
||||||
while (offset >= 0x1000 && src_cur + sizeof(WCHAR) <= src_end)
|
while (offset >= 0x1000 && src_cur + sizeof(WORD) <= src_end)
|
||||||
{
|
{
|
||||||
/* read chunk header and extract size */
|
/* read chunk header and extract size */
|
||||||
chunk_header = *(WORD *)src_cur;
|
chunk_header = *(WORD *)src_cur;
|
||||||
src_cur += sizeof(WCHAR);
|
src_cur += sizeof(WORD);
|
||||||
if (!chunk_header) goto out;
|
if (!chunk_header) goto out;
|
||||||
chunk_size = (chunk_header & 0xFFF) + 1;
|
chunk_size = (chunk_header & 0xFFF) + 1;
|
||||||
|
|
||||||
|
@ -125,11 +122,11 @@ static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG s
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this chunk is can be included partially */
|
/* this chunk is can be included partially */
|
||||||
if (offset && src_cur + sizeof(WCHAR) <= src_end)
|
if (offset && src_cur + sizeof(WORD) <= src_end)
|
||||||
{
|
{
|
||||||
/* read chunk header and extract size */
|
/* read chunk header and extract size */
|
||||||
chunk_header = *(WORD *)src_cur;
|
chunk_header = *(WORD *)src_cur;
|
||||||
src_cur += sizeof(WCHAR);
|
src_cur += sizeof(WORD);
|
||||||
if (!chunk_header) goto out;
|
if (!chunk_header) goto out;
|
||||||
chunk_size = (chunk_header & 0xFFF) + 1;
|
chunk_size = (chunk_header & 0xFFF) + 1;
|
||||||
|
|
||||||
|
@ -167,15 +164,15 @@ static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG s
|
||||||
src_cur += chunk_size;
|
src_cur += chunk_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (src_cur + sizeof(WCHAR) <= src_end)
|
/* handle remaining chunks */
|
||||||
|
while (src_cur + sizeof(WORD) <= src_end)
|
||||||
{
|
{
|
||||||
/* read chunk header and extract size */
|
/* read chunk header and extract size */
|
||||||
chunk_header = *(WORD *)src_cur;
|
chunk_header = *(WORD *)src_cur;
|
||||||
src_cur += sizeof(WCHAR);
|
src_cur += sizeof(WORD);
|
||||||
if (!chunk_header) goto out;
|
if (!chunk_header) goto out;
|
||||||
chunk_size = (chunk_header & 0xFFF) + 1;
|
chunk_size = (chunk_header & 0xFFF) + 1;
|
||||||
|
|
||||||
/* ensure we have enough buffer to process chunk */
|
|
||||||
if (src_cur + chunk_size > src_end)
|
if (src_cur + chunk_size > src_end)
|
||||||
return STATUS_BAD_COMPRESSION_BUFFER;
|
return STATUS_BAD_COMPRESSION_BUFFER;
|
||||||
|
|
||||||
|
@ -189,7 +186,8 @@ static NTSTATUS lznt1_decompress(UCHAR *dst, ULONG dst_size, UCHAR *src, ULONG s
|
||||||
memset(dst_cur, 0, block_size);
|
memset(dst_cur, 0, block_size);
|
||||||
dst_cur += block_size;
|
dst_cur += block_size;
|
||||||
}
|
}
|
||||||
else if (dst_cur >= dst_end)
|
|
||||||
|
if (dst_cur >= dst_end)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (chunk_header & 0x8000)
|
if (chunk_header & 0x8000)
|
||||||
|
@ -219,17 +217,34 @@ out:
|
||||||
|
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
RtlpCompressBufferLZNT1(USHORT Engine,
|
RtlpCompressBufferLZNT1(UCHAR *src, ULONG src_size, UCHAR *dst, ULONG dst_size,
|
||||||
PUCHAR UncompressedBuffer,
|
ULONG chunk_size, ULONG *final_size, UCHAR *workspace)
|
||||||
ULONG UncompressedBufferSize,
|
|
||||||
PUCHAR CompressedBuffer,
|
|
||||||
ULONG CompressedBufferSize,
|
|
||||||
ULONG UncompressedChunkSize,
|
|
||||||
PULONG FinalCompressedSize,
|
|
||||||
PVOID WorkSpace)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UCHAR *src_cur = src, *src_end = src + src_size;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
UCHAR *dst_cur = dst, *dst_end = dst + dst_size;
|
||||||
|
ULONG block_size;
|
||||||
|
|
||||||
|
while (src_cur < src_end)
|
||||||
|
{
|
||||||
|
/* determine size of current chunk */
|
||||||
|
block_size = min(0x1000, src_end - src_cur);
|
||||||
|
if (dst_cur + sizeof(WORD) + block_size > dst_end)
|
||||||
|
return STATUS_BUFFER_TOO_SMALL;
|
||||||
|
|
||||||
|
/* write (uncompressed) chunk header */
|
||||||
|
*(WORD *)dst_cur = 0x3000 | (block_size - 1);
|
||||||
|
dst_cur += sizeof(WORD);
|
||||||
|
|
||||||
|
/* write chunk content */
|
||||||
|
memcpy(dst_cur, src_cur, block_size);
|
||||||
|
dst_cur += block_size;
|
||||||
|
src_cur += block_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (final_size)
|
||||||
|
*final_size = dst_cur - dst;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,15 +284,14 @@ RtlCompressBuffer(IN USHORT CompressionFormatAndEngine,
|
||||||
IN PVOID WorkSpace)
|
IN PVOID WorkSpace)
|
||||||
{
|
{
|
||||||
USHORT Format = CompressionFormatAndEngine & COMPRESSION_FORMAT_MASK;
|
USHORT Format = CompressionFormatAndEngine & COMPRESSION_FORMAT_MASK;
|
||||||
USHORT Engine = CompressionFormatAndEngine & COMPRESSION_ENGINE_MASK;
|
/* USHORT Engine = CompressionFormatAndEngine & COMPRESSION_ENGINE_MASK; */
|
||||||
|
|
||||||
if ((Format == COMPRESSION_FORMAT_NONE) ||
|
if ((Format == COMPRESSION_FORMAT_NONE) ||
|
||||||
(Format == COMPRESSION_FORMAT_DEFAULT))
|
(Format == COMPRESSION_FORMAT_DEFAULT))
|
||||||
return(STATUS_INVALID_PARAMETER);
|
return(STATUS_INVALID_PARAMETER);
|
||||||
|
|
||||||
if (Format == COMPRESSION_FORMAT_LZNT1)
|
if (Format == COMPRESSION_FORMAT_LZNT1)
|
||||||
return(RtlpCompressBufferLZNT1(Engine,
|
return(RtlpCompressBufferLZNT1(UncompressedBuffer,
|
||||||
UncompressedBuffer,
|
|
||||||
UncompressedBufferSize,
|
UncompressedBufferSize,
|
||||||
CompressedBuffer,
|
CompressedBuffer,
|
||||||
CompressedBufferSize,
|
CompressedBufferSize,
|
||||||
|
|
Loading…
Reference in a new issue