You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.2 KiB

/**
* @file encrypt.cpp
*
* Implementation of functions for compression and decompressing MPQ data.
*/
#include <cstdint>
#include <cstring>
#include <memory>
#include <mpqfs/mpqfs.h>
#include "encrypt.h"
namespace devilution {
uint32_t PkwareCompress(std::byte *srcData, uint32_t size)
{
size_t dstCap = size * 2 + 64;
auto dst = std::make_unique<uint8_t[]>(dstCap);
size_t dstSize = dstCap;
int rc = mpqfs_pk_implode(
reinterpret_cast<const uint8_t *>(srcData), size,
dst.get(), &dstSize, /*dict_bits=*/6);
if (rc == 0 && dstSize < size) {
std::memcpy(srcData, dst.get(), dstSize);
return static_cast<uint32_t>(dstSize);
}
// Compression didn't help — return original size.
return size;
}
uint32_t PkwareDecompress(std::byte *inBuff, uint32_t recvSize, size_t maxBytes)
{
auto out = std::make_unique<uint8_t[]>(maxBytes);
size_t outSize = maxBytes;
int rc = mpqfs_pk_explode(
reinterpret_cast<const uint8_t *>(inBuff), recvSize,
out.get(), &outSize);
if (rc != 0)
return 0;
std::memcpy(inBuff, out.get(), outSize);
return static_cast<uint32_t>(outSize);
}
} // namespace devilution