Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmake/Dependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ find_package(mpg123 REQUIRED)
find_package(PNG REQUIRED)
find_package(ZLIB REQUIRED)

find_helper(ZSTD libzstd zstd.h zstd)
include_directories(${ZSTD_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZSTD_LIBRARIES})

if (USE_LIBSERIALPORT)
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_LIBSERIALPORT)
find_helper(LIBSERIALPORT libserialport libserialport.h serialport)
Expand Down
2 changes: 1 addition & 1 deletion packaging/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/packaging/dmg/AppDMGSet

# Linux DEB settings
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libstdc++6, libsdl2-2.0-0, libsdl2-image-2.0-0, libsdl2-ttf-2.0-0, flac, libmpg123-0, libpng16-16, zlib1g, libserialport0, libportmidi0, libenet7, libmpeg2-4") # Adjust dependencies as needed
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libstdc++6, libsdl2-2.0-0, libsdl2-image-2.0-0, libsdl2-ttf-2.0-0, flac, libmpg123-0, libpng16-16, zlib1g, libzstd1, libserialport0, libportmidi0, libenet7, libmpeg2-4") # Adjust dependencies as needed
if (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" OR CMAKE_SYSTEM_PROCESSOR MATCHES "arm64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
Expand Down
166 changes: 166 additions & 0 deletions src/archivers/chd/chdcodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "7z/LzmaEnc.h"

#include <zlib.h>
#include <zstd.h>

#include <new>

Expand Down Expand Up @@ -102,6 +103,44 @@ namespace {
};


// ======================> chd_zstd_compressor

// Zstandard compressor
class chd_zstd_compressor : public chd_compressor
{
public:
// construction/destruction
chd_zstd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy);
~chd_zstd_compressor();

// core functionality
virtual uint32_t compress(const uint8_t *src, uint32_t srclen, uint8_t *dest) override;

private:
// internal state
ZSTD_CStream * m_stream;
};


// ======================> chd_zstd_decompressor

// Zstandard decompressor
class chd_zstd_decompressor : public chd_decompressor
{
public:
// construction/destruction
chd_zstd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy);
~chd_zstd_decompressor();

// core functionality
virtual void decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) override;

private:
// internal state
ZSTD_DStream * m_stream;
};


// ======================> chd_lzma_allocator

// allocation helper clas for zlib
Expand Down Expand Up @@ -493,12 +532,14 @@ namespace {
const codec_entry f_codec_list[] =
{
// general codecs
{ CHD_CODEC_ZSTD, false, "Zstd", &codec_entry::construct_compressor<chd_zstd_compressor>, &codec_entry::construct_decompressor<chd_zstd_decompressor> },
{ CHD_CODEC_ZLIB, false, "Deflate", &codec_entry::construct_compressor<chd_zlib_compressor>, &codec_entry::construct_decompressor<chd_zlib_decompressor> },
{ CHD_CODEC_LZMA, false, "LZMA", &codec_entry::construct_compressor<chd_lzma_compressor>, &codec_entry::construct_decompressor<chd_lzma_decompressor> },
{ CHD_CODEC_HUFFMAN, false, "Huffman", &codec_entry::construct_compressor<chd_huffman_compressor>, &codec_entry::construct_decompressor<chd_huffman_decompressor> },
{ CHD_CODEC_FLAC, false, "FLAC", &codec_entry::construct_compressor<chd_flac_compressor>, &codec_entry::construct_decompressor<chd_flac_decompressor> },

// general codecs with CD frontend
{ CHD_CODEC_CD_ZSTD, false, "CD Zstd", &codec_entry::construct_compressor<chd_cd_compressor<chd_zstd_compressor, chd_zstd_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_zstd_decompressor, chd_zstd_decompressor> > },
{ CHD_CODEC_CD_ZLIB, false, "CD Deflate", &codec_entry::construct_compressor<chd_cd_compressor<chd_zlib_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_zlib_decompressor, chd_zlib_decompressor> > },
{ CHD_CODEC_CD_LZMA, false, "CD LZMA", &codec_entry::construct_compressor<chd_cd_compressor<chd_lzma_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_lzma_decompressor, chd_zlib_decompressor> > },
{ CHD_CODEC_CD_FLAC, false, "CD FLAC", &codec_entry::construct_compressor<chd_cd_flac_compressor>, &codec_entry::construct_decompressor<chd_cd_flac_decompressor> },
Expand Down Expand Up @@ -984,6 +1025,131 @@ void chd_zlib_decompressor::decompress(const uint8_t* src, uint32_t complen, uin



//**************************************************************************
// ZSTANDARD COMPRESSOR
//**************************************************************************

//-------------------------------------------------
// chd_zstd_compressor - constructor
//-------------------------------------------------

chd_zstd_compressor::chd_zstd_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
: chd_compressor(chd, hunkbytes, lossy)
, m_stream(nullptr)
{
// initialize the stream
m_stream = ZSTD_createCStream();

// convert errors
if (!m_stream)
throw std::bad_alloc();
}


//-------------------------------------------------
// ~chd_zstd_compressor - destructor
//-------------------------------------------------

chd_zstd_compressor::~chd_zstd_compressor()
{
ZSTD_freeCStream(m_stream);
}


//-------------------------------------------------
// compress - compress data using the Zstandard
// codec
//-------------------------------------------------

uint32_t chd_zstd_compressor::compress(const uint8_t *src, uint32_t srclen, uint8_t *dest)
{
// reset the compressor
auto result = ZSTD_initCStream(m_stream, ZSTD_maxCLevel());
if (ZSTD_isError(result))
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);

// do it
ZSTD_inBuffer input{ src, srclen, 0 };
ZSTD_outBuffer output = { dest, srclen, 0 };
while (output.pos < output.size)
{
result = ZSTD_compressStream2(m_stream, &output, &input, ZSTD_e_end);
if (ZSTD_isError(result))
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
else if (!result)
break;
}

// if we ended up with more data than we started with, return an error
if (output.pos == output.size)
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);

// otherwise, return the length
return output.pos;
}



//**************************************************************************
// ZSTANDARD DECOMPRESSOR
//**************************************************************************

//-------------------------------------------------
// chd_zstd_compressor - constructor
//-------------------------------------------------

chd_zstd_decompressor::chd_zstd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy)
: chd_decompressor(chd, hunkbytes, lossy)
, m_stream(nullptr)
{
// initialize the stream
m_stream = ZSTD_createDStream();

// convert errors
if (!m_stream)
throw std::bad_alloc();
}


//-------------------------------------------------
// ~chd_zstd_decompressor - destructor
//-------------------------------------------------

chd_zstd_decompressor::~chd_zstd_decompressor()
{
ZSTD_freeDStream(m_stream);
}


//-------------------------------------------------
// decompress - decompress data using the
// Zstandard codec
//-------------------------------------------------

void chd_zstd_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
{
// reset the decompressor
auto result = ZSTD_initDStream(m_stream);
if (ZSTD_isError(result))
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);

// do it
ZSTD_inBuffer input{ src, complen, 0 };
ZSTD_outBuffer output = { dest, destlen, 0 };
while ((input.pos < input.size) && (output.pos < output.size))
{
result = ZSTD_decompressStream(m_stream, &output, &input);
if (ZSTD_isError(result))
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}

// ensure the expected amount of output was generated
if (output.pos != output.size)
throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR);
}



//**************************************************************************
// LZMA ALLOCATOR HELPER
//**************************************************************************
Expand Down
2 changes: 2 additions & 0 deletions src/archivers/chd/chdcodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,14 @@ constexpr chd_codec_type CHD_CODEC_NONE = 0;

// general codecs
constexpr chd_codec_type CHD_CODEC_ZLIB = CHD_MAKE_TAG('z', 'l', 'i', 'b');
constexpr chd_codec_type CHD_CODEC_ZSTD = CHD_MAKE_TAG('z', 's', 't', 'd');
constexpr chd_codec_type CHD_CODEC_LZMA = CHD_MAKE_TAG('l', 'z', 'm', 'a');
constexpr chd_codec_type CHD_CODEC_HUFFMAN = CHD_MAKE_TAG('h', 'u', 'f', 'f');
constexpr chd_codec_type CHD_CODEC_FLAC = CHD_MAKE_TAG('f', 'l', 'a', 'c');

// general codecs with CD frontend
constexpr chd_codec_type CHD_CODEC_CD_ZLIB = CHD_MAKE_TAG('c', 'd', 'z', 'l');
constexpr chd_codec_type CHD_CODEC_CD_ZSTD = CHD_MAKE_TAG('c', 'd', 'z', 's');
constexpr chd_codec_type CHD_CODEC_CD_LZMA = CHD_MAKE_TAG('c', 'd', 'l', 'z');
constexpr chd_codec_type CHD_CODEC_CD_FLAC = CHD_MAKE_TAG('c', 'd', 'f', 'l');

Expand Down
2 changes: 1 addition & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,7 +1122,7 @@ static void parse_cmdline (int argc, TCHAR **argv)
else
{
auto* const txt = parsetextpath(argv[++i]);
auto* const txt2 = xmalloc(TCHAR, _tcslen(txt) + 5);
auto* const txt2 = xmalloc(TCHAR, _tcslen(txt) + 7);
_tcscpy(txt2, txt);
if (_tcsrchr(txt2, ',') == nullptr)
_tcscat(txt2, _T(",image"));
Expand Down
Loading