/* * This file is part of VoidArchiveTool. * * Copyright (C) 2025 Yanczi * * Void Archive Toolis free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "CompressionManager.h" CompressionManager::CompressionManager() :cctx(ZSTD_createCCtx()) ,dctx(ZSTD_createDCtx()) { // Ustawienia frameless size_t rc = 0; // Wyłącza ramkę i przestawia strumień na czyste bloki rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_format, ZSTD_f_zstd1_magicless); // Wyłącza sumę kontrolną na poziomie ramki rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 0); // Wyłącza zapisywanie „content size” w nagłówku ramki rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_contentSizeFlag, 0); // Wyłącza zapisywanie identyfikatora słownika rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_dictIDFlag, 0); // Ustawia poziom kompresji rc |= ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, zstd::compression_level); if (ZSTD_isError(rc)) { std::cerr << "ZSTD_CCtx_setParameter error" << std::endl; ZSTD_freeCCtx(cctx); } /*====Tutaj Dekompresja=============================================================*/ size_t r = 0; // Przestawia dekompresję na czyste bloki bez nagłówka r |= ZSTD_DCtx_setParameter(dctx, ZSTD_d_format, ZSTD_f_zstd1_magicless); if (ZSTD_isError(r)) { std::cerr << "ZSTD_DCtx_setParameter error" << std::endl; ZSTD_freeDCtx(dctx); } } CompressionManager::~CompressionManager() { ZSTD_freeCCtx(cctx); ZSTD_freeDCtx(dctx); } //----------------------------------------------------------------------------- // Kompresja ZSTD frameless //----------------------------------------------------------------------------- std::vector CompressionManager::compress(const std::vector& input) { // Obsługa pustego chunku: zwracamy pusty wynik (0 bajtów). if (input.empty()) return {}; const size_t srcSize = input.size(); // Szacowanie rozmiaru skompresowanego vectoru const size_t maxDst = ZSTD_compressBound(srcSize); std::vector out(maxDst); // Faktyczna kompresja size_t written = ZSTD_compress2(cctx, out.data(), maxDst, input.data(), srcSize); if (ZSTD_isError(written)) { std::cerr << "ZSTD_compress error: " << ZSTD_getErrorName(written) << std::endl; return {}; } out.resize(written); return out; } //----------------------------------------------------------------------------- // Dekompresja ZSTD //----------------------------------------------------------------------------- std::vector CompressionManager::decompress(const std::vector& input, const size_t& expected) { std::vector output(expected); size_t dsize = ZSTD_decompressDCtx(dctx, output.data(), expected, input.data(), input.size()); if (ZSTD_isError(dsize)) { std::cerr << "ZSTD_decompressDCtx error: " << ZSTD_getErrorName(dsize) << "\n"; return {}; } return output; }