diff --git a/components/bsa/ba2dx10file.cpp b/components/bsa/ba2dx10file.cpp index a438121d5b..afb2c0a4aa 100644 --- a/components/bsa/ba2dx10file.cpp +++ b/components/bsa/ba2dx10file.cpp @@ -1,29 +1,12 @@ #include "ba2dx10file.hpp" +#include #include +#include #include #include -#include - -#if defined(_MSC_VER) -// why is this necessary? These are included with /external:I -#pragma warning(push) -#pragma warning(disable : 4706) -#pragma warning(disable : 4702) -#include -#include -#include -#include -#pragma warning(pop) -#else -#include -#include -#include -#include -#endif - -#include +#include #include #include @@ -644,11 +627,16 @@ namespace Bsa size_t headerSize = (header.ddspf.fourCC == ESM::fourCC("DX10") ? sizeof(DDSHeaderDX10) : sizeof(DDSHeader)); size_t textureSize = sizeof(uint32_t) + headerSize; //"DDS " + header + uint32_t maxPackedChunkSize = 0; for (const auto& textureChunk : fileRecord.texturesChunks) + { textureSize += textureChunk.size; + maxPackedChunkSize = std::max(textureChunk.packedSize, maxPackedChunkSize); + } auto memoryStreamPtr = std::make_unique(textureSize); char* buff = memoryStreamPtr->getRawData(); + std::vector inputBuffer(maxPackedChunkSize); uint32_t dds = ESM::fourCC("DDS "); buff = (char*)std::memcpy(buff, &dds, sizeof(uint32_t)) + sizeof(uint32_t); @@ -658,25 +646,22 @@ namespace Bsa // append chunks for (const auto& c : fileRecord.texturesChunks) { + const uint32_t inputSize = c.packedSize != 0 ? c.packedSize : c.size; + Files::IStreamPtr streamPtr = Files::openConstrainedFileStream(mFilepath, c.offset, inputSize); if (c.packedSize != 0) { - Files::IStreamPtr streamPtr = Files::openConstrainedFileStream(mFilepath, c.offset, c.packedSize); - std::istream* fileStream = streamPtr.get(); + streamPtr->read(inputBuffer.data(), c.packedSize); + uLongf destSize = static_cast(c.size); + int ec = ::uncompress(reinterpret_cast(memoryStreamPtr->getRawData() + offset), &destSize, + reinterpret_cast(inputBuffer.data()), static_cast(c.packedSize)); - boost::iostreams::filtering_streambuf inputStreamBuf; - inputStreamBuf.push(boost::iostreams::zlib_decompressor()); - inputStreamBuf.push(*fileStream); - - boost::iostreams::basic_array_sink sr(memoryStreamPtr->getRawData() + offset, c.size); - boost::iostreams::copy(inputStreamBuf, sr); + if (ec != Z_OK) + fail("zlib uncompress failed: " + std::string(::zError(ec))); } // uncompressed chunk else { - Files::IStreamPtr streamPtr = Files::openConstrainedFileStream(mFilepath, c.offset, c.size); - std::istream* fileStream = streamPtr.get(); - - fileStream->read(memoryStreamPtr->getRawData() + offset, c.size); + streamPtr->read(memoryStreamPtr->getRawData() + offset, c.size); } offset += c.size; } diff --git a/components/bsa/ba2gnrlfile.cpp b/components/bsa/ba2gnrlfile.cpp index 75e7305245..f169440208 100644 --- a/components/bsa/ba2gnrlfile.cpp +++ b/components/bsa/ba2gnrlfile.cpp @@ -1,27 +1,11 @@ #include "ba2gnrlfile.hpp" +#include #include #include #include -#include - -#if defined(_MSC_VER) -// why is this necessary? These are included with /external:I -#pragma warning(push) -#pragma warning(disable : 4706) -#pragma warning(disable : 4702) -#include -#include -#include -#pragma warning(pop) -#else -#include -#include -#include -#endif - -#include +#include #include #include @@ -223,12 +207,14 @@ namespace Bsa auto memoryStreamPtr = std::make_unique(fileRecord.size); if (fileRecord.packedSize) { - boost::iostreams::filtering_streambuf inputStreamBuf; - inputStreamBuf.push(boost::iostreams::zlib_decompressor()); - inputStreamBuf.push(*streamPtr); + std::vector buffer(inputSize); + streamPtr->read(buffer.data(), inputSize); + uLongf destSize = static_cast(fileRecord.size); + int ec = ::uncompress(reinterpret_cast(memoryStreamPtr->getRawData()), &destSize, + reinterpret_cast(buffer.data()), static_cast(buffer.size())); - boost::iostreams::basic_array_sink sr(memoryStreamPtr->getRawData(), fileRecord.size); - boost::iostreams::copy(inputStreamBuf, sr); + if (ec != Z_OK) + fail("zlib uncompress failed: " + std::string(::zError(ec))); } else { diff --git a/components/bsa/compressedbsafile.cpp b/components/bsa/compressedbsafile.cpp index 8426c5965c..655a4d2844 100644 --- a/components/bsa/compressedbsafile.cpp +++ b/components/bsa/compressedbsafile.cpp @@ -24,27 +24,13 @@ */ #include "compressedbsafile.hpp" +#include #include #include #include #include - -#if defined(_MSC_VER) -#pragma warning(push) -#pragma warning(disable : 4706) -#pragma warning(disable : 4702) -#include -#include -#include -#pragma warning(pop) -#else -#include -#include -#include -#endif - -#include +#include #include #include @@ -292,19 +278,26 @@ namespace Bsa if (compressed) { + std::vector buffer(size); + streamPtr->read(buffer.data(), size); + if (mHeader.mVersion != Version_SSE) { - boost::iostreams::filtering_streambuf inputStreamBuf; - inputStreamBuf.push(boost::iostreams::zlib_decompressor()); - inputStreamBuf.push(*streamPtr); + uLongf destSize = static_cast(resultSize); + int ec = ::uncompress(reinterpret_cast(memoryStreamPtr->getRawData()), &destSize, + reinterpret_cast(buffer.data()), static_cast(buffer.size())); - boost::iostreams::basic_array_sink sr(memoryStreamPtr->getRawData(), resultSize); - boost::iostreams::copy(inputStreamBuf, sr); + if (ec != Z_OK) + { + std::string message = "zlib uncompress failed for file "; + message.append(fileRecord.mName.begin(), fileRecord.mName.end()); + message += ": "; + message += ::zError(ec); + fail(message); + } } else { - auto buffer = std::vector(size); - streamPtr->read(buffer.data(), size); LZ4F_decompressionContext_t context = nullptr; LZ4F_createDecompressionContext(&context, LZ4F_VERSION); LZ4F_decompressOptions_t options = {};