diff --git a/src/compress.h b/src/compress.h index c8f2389f2..2b7c84cd2 100644 --- a/src/compress.h +++ b/src/compress.h @@ -7,7 +7,7 @@ namespace maxcso { -static const char *VERSION = "1.4.3"; +static const char *VERSION = "1.4.4"; struct Task; diff --git a/src/input.cpp b/src/input.cpp index 2048423af..bd14e4867 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -79,7 +79,7 @@ void Input::DetectFormat() { ++csoBlockShift_; } - const uint32_t sectors = static_cast(size_ >> csoBlockShift_); + const uint32_t sectors = static_cast(SizeAligned() >> csoBlockShift_); csoIndex_ = new uint32_t[sectors + 1]; const unsigned int bytes = (sectors + 1) * sizeof(uint32_t); const uv_buf_t buf = uv_buf_init(reinterpret_cast(csoIndex_), bytes); @@ -383,4 +383,8 @@ bool Input::DecompressSectorLZ4(uint8_t *dst, const uint8_t *src, int dstSize, s return true; } +inline int64_t Input::SizeAligned() { + return size_ + csoBlockSize_ - 1; +} + }; \ No newline at end of file diff --git a/src/input.h b/src/input.h index 65b690688..17b49a398 100644 --- a/src/input.h +++ b/src/input.h @@ -24,6 +24,7 @@ class Input { void SetupCache(uint32_t minSize); void ReadSector(); void EnqueueDecompressSector(uint8_t *src, uint32_t len, uint32_t offset, bool isLZ4); + inline int64_t SizeAligned(); enum FileType { UNKNOWN, diff --git a/src/output.cpp b/src/output.cpp index 8c65e984d..00ea0b4eb 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -44,7 +44,7 @@ void Output::SetFile(uv_file file, int64_t srcSize, uint32_t blockSize, CSOForma ++blockShift_; } - const uint32_t sectors = static_cast(srcSize >> blockShift_); + const uint32_t sectors = static_cast((srcSize + blockSize_ - 1) >> blockShift_); // Start after the header and index, which we'll fill in later. index_ = new uint32_t[sectors + 1]; // Start after the end of the index data and header. @@ -120,7 +120,7 @@ void Output::Enqueue(int64_t pos, uint8_t *buffer) { if (blockSize_ != SECTOR_SIZE && pos + SECTOR_SIZE >= srcSize_) { // Our src may not be aligned to the blockSize_, so this sector might never wake up. // So let's send in some padding if needed. - const int64_t paddedSize = (srcSize_ + blockSize_ - 1) & ~static_cast(blockSize_ - 1); + const int64_t paddedSize = SrcSizeAligned() & ~static_cast(blockSize_ - 1); for (int64_t padPos = srcSize_; padPos < paddedSize; padPos += SECTOR_SIZE) { // Sector takes ownership, so we need a new one each time. uint8_t *padBuffer = pool.Alloc(); @@ -220,7 +220,7 @@ void Output::HandleReadySector(Sector *sector) { // If we're working on the last sectors, then the index is ready to write. if (nextPos >= srcSize_) { // Update the final index entry. - const int32_t s = static_cast(srcSize_ >> blockShift_); + const int32_t s = static_cast(SrcSizeAligned() >> blockShift_); index_[s] = static_cast(dstPos >> indexShift_); state_ |= STATE_INDEX_READY; @@ -304,7 +304,7 @@ void Output::Flush() { header->unused[0] = 0; header->unused[1] = 0; - const uint32_t sectors = static_cast(srcSize_ >> blockShift_); + const uint32_t sectors = static_cast(SrcSizeAligned() >> blockShift_); uv_buf_t bufs[2]; bufs[0] = uv_buf_init(reinterpret_cast(header), sizeof(CSOHeader)); @@ -328,4 +328,8 @@ void Output::CheckFinish() { } } +inline int64_t Output::SrcSizeAligned() { + return srcSize_ + blockSize_ - 1; +} + }; diff --git a/src/output.h b/src/output.h index 55a2b446e..f27eced37 100644 --- a/src/output.h +++ b/src/output.h @@ -31,6 +31,7 @@ class Output { int32_t Align(int64_t &pos); void HandleReadySector(Sector *sector); bool ShouldCompress(int64_t pos, uint8_t *buffer); + inline int64_t SrcSizeAligned(); enum State { STATE_INIT = 0x00,