/* All Stuffit compression methods. Copyright (C) 2019, Guillaume Gonnet This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "stuffit/methods.h" #include "stuffit/methods/rle90.h" #include "stuffit/methods/compress.h" #include "stuffit/methods/algorithm13.h" #include "stuffit/methods/arsenic.h" #include #include namespace maconv { namespace stuffit { // Get a compression method (from a method number). CompMethodPtr GetCompressionMethod(uint8_t method) { switch (method) { case 0: // No compression. return std::make_unique(); case 1: // RLE 90 algorithm. return std::make_unique(); case 2: // Compress algorithm (LZW). return std::make_unique(); case 13: // LZSS and Huffman. return std::make_unique(); case 15: // Arsenic algorithm. return std::make_unique(); default: return nullptr; } } // Extract data from the compressed fork. void CompressionMethod::Extract(const StuffitCompInfo &info, uint8_t *data, std::vector &mem_pool) { uint32_t capacity = info.size ? info.size : info.comp_size; this->data = data + info.offset; this->end = this->data + info.comp_size; Initialize(); std::unique_ptr buffer; buffer.reset((uint8_t *)malloc(capacity)); total_size = 0; // Uncompress the data chunk by chunks. for (uint32_t len = 0; true;) { len = ReadBytes(buffer.get() + total_size, capacity - total_size); if (len == -1) break; total_size += len; if (len == 0 || total_size == capacity) { capacity = (capacity * 3) / 2; buffer.reset((uint8_t *)realloc((void *)buffer.release(), capacity)); } } // Store the uncompressed buffer in the mempool. uncompressed = buffer.get(); mem_pool.emplace_back(std::move(buffer)); } // Extract data from the compressed fork. void NoneMethod::Extract(const StuffitCompInfo &info, uint8_t *data, std::vector &mem_pool) { total_size = info.size ? info.size : info.comp_size; uncompressed = data + info.offset; } } // namespace stuffit } // namespace maconv