feat: Added basic support for lz4 decompression to the pattern language
This commit is contained in:
parent
0cbc65a52f
commit
1f5e4ceb0c
60
cmake/modules/FindLZ4.cmake
Normal file
60
cmake/modules/FindLZ4.cmake
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
find_path(LZ4_INCLUDE_DIR
|
||||||
|
NAMES lz4.h
|
||||||
|
HINTS "${LZ4_INCLUDEDIR}" "${LZ4_HINTS}/include"
|
||||||
|
PATHS
|
||||||
|
/usr/local/include
|
||||||
|
/usr/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(LZ4_LIBRARY
|
||||||
|
NAMES lz4 liblz4
|
||||||
|
HINTS "${LZ4_LIBDIR}" "${LZ4_HINTS}/lib"
|
||||||
|
PATHS
|
||||||
|
/usr/local/lib
|
||||||
|
/usr/lib
|
||||||
|
)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args( LZ4 DEFAULT_MSG LZ4_LIBRARY LZ4_INCLUDE_DIR )
|
||||||
|
|
||||||
|
if( LZ4_FOUND )
|
||||||
|
include( CheckIncludeFile )
|
||||||
|
include( CMakePushCheckState )
|
||||||
|
|
||||||
|
set( LZ4_INCLUDE_DIRS ${LZ4_INCLUDE_DIR} )
|
||||||
|
set( LZ4_LIBRARIES ${LZ4_LIBRARY} )
|
||||||
|
|
||||||
|
cmake_push_check_state()
|
||||||
|
set( CMAKE_REQUIRED_INCLUDES ${LZ4_INCLUDE_DIRS} )
|
||||||
|
check_include_file( lz4frame.h HAVE_LZ4FRAME_H )
|
||||||
|
cmake_pop_check_state()
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set ( LZ4_DLL_DIR "${LZ4_HINTS}/bin"
|
||||||
|
CACHE PATH "Path to LZ4 DLL"
|
||||||
|
)
|
||||||
|
file( GLOB _lz4_dll RELATIVE "${LZ4_DLL_DIR}"
|
||||||
|
"${LZ4_DLL_DIR}/lz4*.dll"
|
||||||
|
)
|
||||||
|
set ( LZ4_DLL ${_lz4_dll}
|
||||||
|
# We're storing filenames only. Should we use STRING instead?
|
||||||
|
CACHE FILEPATH "LZ4 DLL file name"
|
||||||
|
)
|
||||||
|
file( GLOB _lz4_pdb RELATIVE "${LZ4_DLL_DIR}"
|
||||||
|
"${LZ4_DLL_DIR}/lz4*.pdb"
|
||||||
|
)
|
||||||
|
set ( LZ4_PDB ${_lz4_pdb}
|
||||||
|
CACHE FILEPATH "LZ4 PDB file name"
|
||||||
|
)
|
||||||
|
mark_as_advanced( LZ4_DLL_DIR LZ4_DLL LZ4_PDB )
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set( LZ4_INCLUDE_DIRS )
|
||||||
|
set( LZ4_LIBRARIES )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
mark_as_advanced( LZ4_LIBRARIES LZ4_INCLUDE_DIRS )
|
||||||
|
|
||||||
|
add_library( LZ4::lz4 INTERFACE IMPORTED )
|
||||||
|
set_property( TARGET LZ4::lz4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LZ4_INCLUDE_DIRS} )
|
||||||
|
set_property( TARGET LZ4::lz4 PROPERTY INTERFACE_LINK_LIBRARIES ${LZ4_LIBRARIES} )
|
@ -39,3 +39,7 @@ if (ZSTD_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
|
mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
|
||||||
|
|
||||||
|
add_library(ZSTD::zstd INTERFACE IMPORTED)
|
||||||
|
set_property(TARGET ZSTD::zstd PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${ZSTD_INCLUDE_DIR})
|
||||||
|
set_property(TARGET ZSTD::zstd PROPERTY INTERFACE_LINK_LIBRARIES ${ZSTD_LIBRARY})
|
1
dist/ImHex-9999.ebuild
vendored
1
dist/ImHex-9999.ebuild
vendored
@ -28,5 +28,6 @@ RDEPEND="${DEPEND}
|
|||||||
app-arch/bzip2
|
app-arch/bzip2
|
||||||
app-arch/lzma
|
app-arch/lzma
|
||||||
app-arch/zstd
|
app-arch/zstd
|
||||||
|
app-arch/lz4
|
||||||
"
|
"
|
||||||
BDEPEND="${DEPEND}"
|
BDEPEND="${DEPEND}"
|
||||||
|
3
dist/get_deps_archlinux.sh
vendored
3
dist/get_deps_archlinux.sh
vendored
@ -18,4 +18,5 @@ pacman -S $@ --needed \
|
|||||||
zlib \
|
zlib \
|
||||||
bzip2 \
|
bzip2 \
|
||||||
xz \
|
xz \
|
||||||
zstd
|
zstd \
|
||||||
|
lz4
|
||||||
|
3
dist/get_deps_debian.sh
vendored
3
dist/get_deps_debian.sh
vendored
@ -26,4 +26,5 @@ apt install -y \
|
|||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
libbz2-dev \
|
libbz2-dev \
|
||||||
liblzma-dev \
|
liblzma-dev \
|
||||||
libzstd-dev
|
libzstd-dev \
|
||||||
|
liblz4-dev
|
||||||
|
3
dist/get_deps_fedora.sh
vendored
3
dist/get_deps_fedora.sh
vendored
@ -16,4 +16,5 @@ dnf install -y \
|
|||||||
libzstd-devel \
|
libzstd-devel \
|
||||||
zlib-devel \
|
zlib-devel \
|
||||||
bzip2-devel \
|
bzip2-devel \
|
||||||
xz-devel
|
xz-devel \
|
||||||
|
lz4-devel
|
3
dist/get_deps_msys2.sh
vendored
3
dist/get_deps_msys2.sh
vendored
@ -17,4 +17,5 @@ pacboy -S --needed --noconfirm \
|
|||||||
zlib:p \
|
zlib:p \
|
||||||
bzip2:p \
|
bzip2:p \
|
||||||
xz:p \
|
xz:p \
|
||||||
zstd:p
|
zstd:p \
|
||||||
|
lz4:p
|
||||||
|
3
dist/get_deps_tumbleweed.sh
vendored
3
dist/get_deps_tumbleweed.sh
vendored
@ -16,4 +16,5 @@ zypper install \
|
|||||||
libzstd-devel \
|
libzstd-devel \
|
||||||
zlib-devel \
|
zlib-devel \
|
||||||
bzip3-devel \
|
bzip3-devel \
|
||||||
xz-devel
|
xz-devel \
|
||||||
|
lz4-dev
|
||||||
|
@ -30,16 +30,16 @@ add_imhex_plugin(
|
|||||||
BZIP2
|
BZIP2
|
||||||
LIBLZMA
|
LIBLZMA
|
||||||
ZSTD
|
ZSTD
|
||||||
|
LZ4
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(ZSTD)
|
set(LIBLZMA_HAS_AUTO_DECODER 1)
|
||||||
if(ZSTD_FOUND)
|
set(LIBLZMA_HAS_EASY_ENCODER 1)
|
||||||
set(LIBRARIES ${LIBRARIES} "${ZSTD_LIBRARY}")
|
set(LIBLZMA_HAS_LZMA_PRESET 1)
|
||||||
message(STATUS "Enabling decompression support using ZSTD (${ZSTD_VERSION})")
|
|
||||||
enable_plugin_feature(ZSTD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
addOptionalLibrary(ZLIB ZLIB)
|
addOptionalLibrary(ZLIB ZLIB)
|
||||||
addOptionalLibrary(BZip2 BZip2)
|
addOptionalLibrary(BZip2 BZip2)
|
||||||
addOptionalLibrary(LibLZMA LibLZMA)
|
addOptionalLibrary(LibLZMA LibLZMA)
|
||||||
|
addOptionalLibrary(ZSTD zstd)
|
||||||
|
addOptionalLibrary(LZ4 lz4)
|
||||||
target_link_libraries(decompress PRIVATE ${LIBRARIES})
|
target_link_libraries(decompress PRIVATE ${LIBRARIES})
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
#if IMHEX_FEATURE_ENABLED(ZSTD)
|
#if IMHEX_FEATURE_ENABLED(ZSTD)
|
||||||
#include <zstd.h>
|
#include <zstd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#if IMHEX_FEATURE_ENABLED(LZ4)
|
||||||
|
#include <lz4.h>
|
||||||
|
#include <lz4frame.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace hex::plugin::decompress {
|
namespace hex::plugin::decompress {
|
||||||
|
|
||||||
@ -89,7 +94,7 @@ namespace hex::plugin::decompress {
|
|||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
hex::unused(evaluator, params);
|
hex::unused(evaluator, params);
|
||||||
err::E0012.throwError("hex::dec::zlib_decompress is not available. Please recompile with zlib support.");
|
err::E0012.throwError("hex::dec::zlib_decompress is not available. Please recompile ImHex with zlib support.");
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -136,7 +141,7 @@ namespace hex::plugin::decompress {
|
|||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
hex::unused(evaluator, params);
|
hex::unused(evaluator, params);
|
||||||
err::E0012.throwError("hex::dec::bzlib_decompress is not available. Please recompile with bzip2 support.");
|
err::E0012.throwError("hex::dec::bzlib_decompress is not available. Please recompile ImHex with bzip2 support.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -184,7 +189,7 @@ namespace hex::plugin::decompress {
|
|||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
hex::unused(evaluator, params);
|
hex::unused(evaluator, params);
|
||||||
err::E0012.throwError("hex::dec::lzma_decompress is not available. Please recompile with liblzma support.");
|
err::E0012.throwError("hex::dec::lzma_decompress is not available. Please recompile ImHex with liblzma support.");
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -229,7 +234,50 @@ namespace hex::plugin::decompress {
|
|||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
hex::unused(evaluator, params);
|
hex::unused(evaluator, params);
|
||||||
err::E0012.throwError("hex::dec::zstd_decompress is not available. Please recompile with zstd support.");
|
err::E0012.throwError("hex::dec::zstd_decompress is not available. Please recompile ImHex with zstd support.");
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
|
||||||
|
/* lz4_decompress(compressed_pattern, section_id) */
|
||||||
|
ContentRegistry::PatternLanguage::addFunction(nsHexDec, "lz4_decompress", FunctionParameterCount::exactly(2), [](Evaluator *evaluator, auto params) -> std::optional<Token::Literal> {
|
||||||
|
#if IMHEX_FEATURE_ENABLED(LZ4)
|
||||||
|
auto compressedData = getCompressedData(evaluator, params[0]);
|
||||||
|
auto §ion = evaluator->getSection(params[1].toUnsigned());
|
||||||
|
|
||||||
|
// Create the decompression context
|
||||||
|
LZ4F_decompressionContext_t dctx;
|
||||||
|
LZ4F_errorCode_t err = LZ4F_createDecompressionContext(&dctx, LZ4F_VERSION);
|
||||||
|
if (LZ4F_isError(err)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> outBuffer(1024 * 1024);
|
||||||
|
|
||||||
|
const u8* sourcePointer = compressedData.data();
|
||||||
|
size_t srcSize = compressedData.size();
|
||||||
|
|
||||||
|
while (srcSize > 0) {
|
||||||
|
u8* dstPtr = outBuffer.data();
|
||||||
|
size_t dstCapacity = outBuffer.size();
|
||||||
|
|
||||||
|
// Decompress the data
|
||||||
|
size_t ret = LZ4F_decompress(dctx, dstPtr, &dstCapacity, sourcePointer, &srcSize, nullptr);
|
||||||
|
if (LZ4F_isError(ret)) {
|
||||||
|
LZ4F_freeDecompressionContext(dctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
section.insert(section.end(), outBuffer.begin(), outBuffer.begin() + dstCapacity);
|
||||||
|
sourcePointer += (compressedData.size() - srcSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the decompression context
|
||||||
|
LZ4F_freeDecompressionContext(dctx);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
hex::unused(evaluator, params);
|
||||||
|
err::E0012.throwError("hex::dec::lz4_decompress is not available. Please recompile ImHex with liblz4 support.");
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user