dep/libchdr: Rebase to upstream 2a1119c

This commit is contained in:
Stenzek 2024-02-18 15:14:07 +09:00
parent a1da72202b
commit 0e6a9f637b
No known key found for this signature in database
6 changed files with 304 additions and 32 deletions

View File

@ -15,5 +15,5 @@ add_library(libchdr
) )
target_include_directories(libchdr PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") target_include_directories(libchdr PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(libchdr PRIVATE ZLIB::ZLIB lzma) target_link_libraries(libchdr PRIVATE ZLIB::ZLIB Zstd::Zstd lzma)

View File

@ -1,6 +1,6 @@
/* /*
FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file. FLAC audio decoder. Choice of public domain or MIT-0. See license statements at the end of this file.
dr_flac - v0.12.39 - 2022-09-17 dr_flac - v0.12.42 - 2023-11-02
David Reid - mackron@gmail.com David Reid - mackron@gmail.com
@ -235,12 +235,12 @@ extern "C" {
#define DRFLAC_VERSION_MAJOR 0 #define DRFLAC_VERSION_MAJOR 0
#define DRFLAC_VERSION_MINOR 12 #define DRFLAC_VERSION_MINOR 12
#define DRFLAC_VERSION_REVISION 39 #define DRFLAC_VERSION_REVISION 42
#define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION) #define DRFLAC_VERSION_STRING DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MAJOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_MINOR) "." DRFLAC_XSTRINGIFY(DRFLAC_VERSION_REVISION)
#include <stddef.h> /* For size_t. */ #include <stddef.h> /* For size_t. */
/* Sized types. */ /* Sized Types */
typedef signed char drflac_int8; typedef signed char drflac_int8;
typedef unsigned char drflac_uint8; typedef unsigned char drflac_uint8;
typedef signed short drflac_int16; typedef signed short drflac_int16;
@ -273,7 +273,9 @@ typedef drflac_uint8 drflac_bool8;
typedef drflac_uint32 drflac_bool32; typedef drflac_uint32 drflac_bool32;
#define DRFLAC_TRUE 1 #define DRFLAC_TRUE 1
#define DRFLAC_FALSE 0 #define DRFLAC_FALSE 0
/* End Sized Types */
/* Decorations */
#if !defined(DRFLAC_API) #if !defined(DRFLAC_API)
#if defined(DRFLAC_DLL) #if defined(DRFLAC_DLL)
#if defined(_WIN32) #if defined(_WIN32)
@ -303,6 +305,7 @@ typedef drflac_uint32 drflac_bool32;
#define DRFLAC_PRIVATE static #define DRFLAC_PRIVATE static
#endif #endif
#endif #endif
/* End Decorations */
#if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */ #if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */
#define DRFLAC_DEPRECATED __declspec(deprecated) #define DRFLAC_DEPRECATED __declspec(deprecated)
@ -321,6 +324,16 @@ typedef drflac_uint32 drflac_bool32;
DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision); DRFLAC_API void drflac_version(drflac_uint32* pMajor, drflac_uint32* pMinor, drflac_uint32* pRevision);
DRFLAC_API const char* drflac_version_string(void); DRFLAC_API const char* drflac_version_string(void);
/* Allocation Callbacks */
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drflac_allocation_callbacks;
/* End Allocation Callbacks */
/* /*
As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed, As data is read from the client it is placed into an internal buffer for fast access. This controls the size of that buffer. Larger values means more speed,
but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8. but also more memory. In my testing there is diminishing returns after about 4KB, but you can fiddle with this to suit your own needs. Must be a multiple of 8.
@ -329,11 +342,22 @@ but also more memory. In my testing there is diminishing returns after about 4KB
#define DR_FLAC_BUFFER_SIZE 4096 #define DR_FLAC_BUFFER_SIZE 4096
#endif #endif
/* Check if we can enable 64-bit optimizations. */
/* Architecture Detection */
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__) #if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
#define DRFLAC_64BIT #define DRFLAC_64BIT
#endif #endif
#if defined(__x86_64__) || defined(_M_X64)
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
/* End Architecture Detection */
#ifdef DRFLAC_64BIT #ifdef DRFLAC_64BIT
typedef drflac_uint64 drflac_cache_t; typedef drflac_uint64 drflac_cache_t;
#else #else
@ -562,14 +586,6 @@ will be set to one of the DRFLAC_METADATA_BLOCK_TYPE_* tokens.
typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata); typedef void (* drflac_meta_proc)(void* pUserData, drflac_metadata* pMetadata);
typedef struct
{
void* pUserData;
void* (* onMalloc)(size_t sz, void* pUserData);
void* (* onRealloc)(void* p, size_t sz, void* pUserData);
void (* onFree)(void* p, void* pUserData);
} drflac_allocation_callbacks;
/* Structure for internal use. Only used for decoders opened with drflac_open_memory. */ /* Structure for internal use. Only used for decoders opened with drflac_open_memory. */
typedef struct typedef struct
{ {
@ -1351,6 +1367,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
/* Inline */
#ifdef _MSC_VER #ifdef _MSC_VER
#define DRFLAC_INLINE __forceinline #define DRFLAC_INLINE __forceinline
#elif defined(__GNUC__) #elif defined(__GNUC__)
@ -1377,15 +1394,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
#else #else
#define DRFLAC_INLINE #define DRFLAC_INLINE
#endif #endif
/* End Inline */
/* CPU architecture. */
#if defined(__x86_64__) || defined(_M_X64)
#define DRFLAC_X64
#elif defined(__i386) || defined(_M_IX86)
#define DRFLAC_X86
#elif defined(__arm__) || defined(_M_ARM) || defined(__arm64) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
#define DRFLAC_ARM
#endif
/* /*
Intrinsics Support Intrinsics Support
@ -1623,6 +1632,7 @@ static DRFLAC_INLINE drflac_bool32 drflac_has_sse41(void)
#define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */ #define DRFLAC_MAX_SIMD_VECTOR_SIZE 64 /* 64 for AVX-512 in the future. */
/* Result Codes */
typedef drflac_int32 drflac_result; typedef drflac_int32 drflac_result;
#define DRFLAC_SUCCESS 0 #define DRFLAC_SUCCESS 0
#define DRFLAC_ERROR -1 /* A generic error. */ #define DRFLAC_ERROR -1 /* A generic error. */
@ -1678,7 +1688,10 @@ typedef drflac_int32 drflac_result;
#define DRFLAC_CANCELLED -51 #define DRFLAC_CANCELLED -51
#define DRFLAC_MEMORY_ALREADY_MAPPED -52 #define DRFLAC_MEMORY_ALREADY_MAPPED -52
#define DRFLAC_AT_END -53 #define DRFLAC_AT_END -53
#define DRFLAC_CRC_MISMATCH -128
#define DRFLAC_CRC_MISMATCH -100
/* End Result Codes */
#define DRFLAC_SUBFRAME_CONSTANT 0 #define DRFLAC_SUBFRAME_CONSTANT 0
#define DRFLAC_SUBFRAME_VERBATIM 1 #define DRFLAC_SUBFRAME_VERBATIM 1
@ -1838,7 +1851,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
#if defined(_MSC_VER) && !defined(__clang__) #if defined(_MSC_VER) && !defined(__clang__)
return _byteswap_ulong(n); return _byteswap_ulong(n);
#elif defined(__GNUC__) || defined(__clang__) #elif defined(__GNUC__) || defined(__clang__)
#if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */ #if defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 6) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- 64-bit inline assembly has not been tested, so disabling for now. */
/* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */ /* Inline assembly optimized implementation for ARM. In my testing, GCC does not generate optimized code with __builtin_bswap32(). */
drflac_uint32 r; drflac_uint32 r;
__asm__ __volatile__ ( __asm__ __volatile__ (
@ -2802,7 +2815,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
return r; return r;
} }
#elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */ #elif defined(DRFLAC_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(DRFLAC_64BIT) /* <-- I haven't tested 64-bit inline assembly, so only enabling this for the 32-bit build for now. */
{ {
unsigned int r; unsigned int r;
__asm__ __volatile__ ( __asm__ __volatile__ (
@ -6479,7 +6492,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
for (;;) { for (;;) {
drflac_metadata metadata; drflac_metadata metadata;
drflac_uint8 isLastBlock = 0; drflac_uint8 isLastBlock = 0;
drflac_uint8 blockType; drflac_uint8 blockType = 0;
drflac_uint32 blockSize; drflac_uint32 blockSize;
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) { if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == DRFLAC_FALSE) {
return DRFLAC_FALSE; return DRFLAC_FALSE;
@ -8141,6 +8154,7 @@ static drflac* drflac_open_with_metadata_private(drflac_read_proc onRead, drflac
#include <wchar.h> /* For wcslen(), wcsrtombs() */ #include <wchar.h> /* For wcslen(), wcsrtombs() */
#endif #endif
/* Errno */
/* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */ /* drflac_result_from_errno() is only used for fopen() and wfopen() so putting it inside DR_WAV_NO_STDIO for now. If something else needs this later we can move it out. */
#include <errno.h> #include <errno.h>
static drflac_result drflac_result_from_errno(int e) static drflac_result drflac_result_from_errno(int e)
@ -8544,7 +8558,9 @@ static drflac_result drflac_result_from_errno(int e)
default: return DRFLAC_ERROR; default: return DRFLAC_ERROR;
} }
} }
/* End Errno */
/* fopen */
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode) static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
{ {
#if defined(_MSC_VER) && _MSC_VER >= 1400 #if defined(_MSC_VER) && _MSC_VER >= 1400
@ -8702,6 +8718,7 @@ static drflac_result drflac_wfopen(FILE** ppFile, const wchar_t* pFilePath, cons
return DRFLAC_SUCCESS; return DRFLAC_SUCCESS;
} }
#endif #endif
/* End fopen */
static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead) static size_t drflac__on_read_stdio(void* pUserData, void* bufferOut, size_t bytesToRead)
{ {
@ -11666,6 +11683,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
/* High Level APIs */ /* High Level APIs */
/* SIZE_MAX */
#if defined(SIZE_MAX) #if defined(SIZE_MAX)
#define DRFLAC_SIZE_MAX SIZE_MAX #define DRFLAC_SIZE_MAX SIZE_MAX
#else #else
@ -11675,6 +11693,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
#define DRFLAC_SIZE_MAX 0xFFFFFFFF #define DRFLAC_SIZE_MAX 0xFFFFFFFF
#endif #endif
#endif #endif
/* End SIZE_MAX */
/* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */ /* Using a macro as the definition of the drflac__full_decode_and_close_*() API family. Sue me. */
@ -12058,6 +12077,16 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
/* /*
REVISION HISTORY REVISION HISTORY
================ ================
v0.12.42 - 2023-11-02
- Fix build for ARMv6-M.
- Fix a compilation warning with GCC.
v0.12.41 - 2023-06-17
- Fix an incorrect date in revision history. No functional change.
v0.12.40 - 2023-05-22
- Minor code restructure. No functional change.
v0.12.39 - 2022-09-17 v0.12.39 - 2022-09-17
- Fix compilation with DJGPP. - Fix compilation with DJGPP.
- Fix compilation error with Visual Studio 2019 and the ARM build. - Fix compilation error with Visual Studio 2019 and the ARM build.
@ -12488,7 +12517,7 @@ For more information, please refer to <http://unlicense.org/>
=============================================================================== ===============================================================================
ALTERNATIVE 2 - MIT No Attribution ALTERNATIVE 2 - MIT No Attribution
=============================================================================== ===============================================================================
Copyright 2020 David Reid Copyright 2023 David Reid
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View File

@ -208,10 +208,12 @@ extern "C" {
#define CHD_CODEC_LZMA CHD_MAKE_TAG('l','z','m','a') #define CHD_CODEC_LZMA CHD_MAKE_TAG('l','z','m','a')
#define CHD_CODEC_HUFFMAN CHD_MAKE_TAG('h','u','f','f') #define CHD_CODEC_HUFFMAN CHD_MAKE_TAG('h','u','f','f')
#define CHD_CODEC_FLAC CHD_MAKE_TAG('f','l','a','c') #define CHD_CODEC_FLAC CHD_MAKE_TAG('f','l','a','c')
#define CHD_CODEC_ZSTD CHD_MAKE_TAG('z', 's', 't', 'd')
/* general codecs with CD frontend */ /* general codecs with CD frontend */
#define CHD_CODEC_CD_ZLIB CHD_MAKE_TAG('c','d','z','l') #define CHD_CODEC_CD_ZLIB CHD_MAKE_TAG('c','d','z','l')
#define CHD_CODEC_CD_LZMA CHD_MAKE_TAG('c','d','l','z') #define CHD_CODEC_CD_LZMA CHD_MAKE_TAG('c','d','l','z')
#define CHD_CODEC_CD_FLAC CHD_MAKE_TAG('c','d','f','l') #define CHD_CODEC_CD_FLAC CHD_MAKE_TAG('c','d','f','l')
#define CHD_CODEC_CD_ZSTD CHD_MAKE_TAG('c','d','z','s')
/* A/V codec configuration parameters */ /* A/V codec configuration parameters */
#define AV_CODEC_COMPRESS_CONFIG 1 #define AV_CODEC_COMPRESS_CONFIG 1

View File

@ -1,13 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\msvc\vsprops\Configurations.props" /> <Import Project="..\msvc\vsprops\Configurations.props" />
<ItemGroup Condition="'$(Configuration)'!='DebugUWP' And '$(Configuration)'!='ReleaseUWP'"> <ItemGroup>
<ProjectReference Include="..\lzma\lzma.vcxproj"> <ProjectReference Include="..\lzma\lzma.vcxproj">
<Project>{dd944834-7899-4c1c-a4c1-064b5009d239}</Project> <Project>{dd944834-7899-4c1c-a4c1-064b5009d239}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\zlib\zlib.vcxproj"> <ProjectReference Include="..\zlib\zlib.vcxproj">
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project> <Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\zstd\zstd.vcxproj">
<Project>{73ee0c55-6ffe-44e7-9c12-baa52434a797}</Project>
</ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\libchdr_bitstream.c" /> <ClCompile Include="src\libchdr_bitstream.c" />
@ -33,7 +36,7 @@
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\zstd\lib;$(ProjectDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="..\msvc\vsprops\Targets.props" /> <Import Project="..\msvc\vsprops\Targets.props" />

View File

@ -48,13 +48,14 @@
#include <libchdr/cdrom.h> #include <libchdr/cdrom.h>
#include <libchdr/flac.h> #include <libchdr/flac.h>
#include <libchdr/huffman.h> #include <libchdr/huffman.h>
#include <zstd.h>
#include "LzmaEnc.h" #include "LzmaEnc.h"
#include "LzmaDec.h" #include "LzmaDec.h"
#if defined(__PS3__) || defined(__PSL1GHT__) #if defined(__PS3__) || defined(__PSL1GHT__)
#define __MACTYPES__ #define __MACTYPES__
#endif #endif
#include "zlib.h" #include <zlib.h>
#undef TRUE #undef TRUE
#undef FALSE #undef FALSE
@ -234,6 +235,12 @@ struct _huff_codec_data
struct huffman_decoder* decoder; struct huffman_decoder* decoder;
}; };
typedef struct _zstd_codec_data zstd_codec_data;
struct _zstd_codec_data
{
ZSTD_DStream *dstream;
};
/* codec-private data for the CDZL codec */ /* codec-private data for the CDZL codec */
typedef struct _cdzl_codec_data cdzl_codec_data; typedef struct _cdzl_codec_data cdzl_codec_data;
struct _cdzl_codec_data { struct _cdzl_codec_data {
@ -276,6 +283,16 @@ struct _cdfl_codec_data {
uint8_t* buffer; uint8_t* buffer;
}; };
typedef struct _cdzs_codec_data cdzs_codec_data;
struct _cdzs_codec_data
{
zstd_codec_data base_decompressor;
#ifdef WANT_SUBCODE
zstd_codec_data subcode_decompressor;
#endif
uint8_t* buffer;
};
/* internal representation of an open CHD file */ /* internal representation of an open CHD file */
struct _chd_file struct _chd_file
{ {
@ -303,9 +320,11 @@ struct _chd_file
lzma_codec_data lzma_codec_data; /* lzma codec data */ lzma_codec_data lzma_codec_data; /* lzma codec data */
huff_codec_data huff_codec_data; /* huff codec data */ huff_codec_data huff_codec_data; /* huff codec data */
flac_codec_data flac_codec_data; /* flac codec data */ flac_codec_data flac_codec_data; /* flac codec data */
zstd_codec_data zstd_codec_data; /* zstd codec data */
cdzl_codec_data cdzl_codec_data; /* cdzl codec data */ cdzl_codec_data cdzl_codec_data; /* cdzl codec data */
cdlz_codec_data cdlz_codec_data; /* cdlz codec data */ cdlz_codec_data cdlz_codec_data; /* cdlz codec data */
cdfl_codec_data cdfl_codec_data; /* cdfl codec data */ cdfl_codec_data cdfl_codec_data; /* cdfl codec data */
cdzs_codec_data cdzs_codec_data; /* cdzs codec data */
#ifdef NEED_CACHE_HUNK #ifdef NEED_CACHE_HUNK
UINT32 maxhunk; /* maximum hunk accessed */ UINT32 maxhunk; /* maximum hunk accessed */
@ -373,6 +392,12 @@ static chd_error flac_codec_init(void *codec, uint32_t hunkbytes);
static void flac_codec_free(void *codec); static void flac_codec_free(void *codec);
static chd_error flac_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); static chd_error flac_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
/* zstd compression codec */
static chd_error zstd_codec_init(void *codec, uint32_t hunkbytes);
static void zstd_codec_free(void *codec);
static chd_error zstd_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
/* cdzl compression codec */ /* cdzl compression codec */
static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes); static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
static void cdzl_codec_free(void* codec); static void cdzl_codec_free(void* codec);
@ -388,6 +413,11 @@ static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
static void cdfl_codec_free(void* codec); static void cdfl_codec_free(void* codec);
static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
/* cdzs compression codec */
static chd_error cdzs_codec_init(void *codec, uint32_t hunkbytes);
static void cdzs_codec_free(void *codec);
static chd_error cdzs_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
/*************************************************************************** /***************************************************************************
* LZMA ALLOCATOR HELPER * LZMA ALLOCATOR HELPER
*************************************************************************** ***************************************************************************
@ -812,11 +842,12 @@ static chd_error huff_codec_decompress(void *codec, const uint8_t *src, uint32_t
if (err != HUFFERR_NONE) if (err != HUFFERR_NONE)
{ {
free(bitbuf); free(bitbuf);
return err; return CHDERR_DECOMPRESSION_ERROR;
} }
// then decode the data // then decode the data
for (uint32_t cur = 0; cur < destlen; cur++) uint32_t cur;
for (cur = 0; cur < destlen; cur++)
dest[cur] = huffman_decode_one(huff_codec->decoder, bitbuf); dest[cur] = huffman_decode_one(huff_codec->decoder, bitbuf);
bitstream_flush(bitbuf); bitstream_flush(bitbuf);
chd_error result = bitstream_overflow(bitbuf) ? CHDERR_DECOMPRESSION_ERROR : CHDERR_NONE; chd_error result = bitstream_overflow(bitbuf) ? CHDERR_DECOMPRESSION_ERROR : CHDERR_NONE;
@ -986,6 +1017,163 @@ static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t
return CHDERR_NONE; return CHDERR_NONE;
} }
/***************************************************************************
* ZSTD DECOMPRESSOR
***************************************************************************
*/
/*-------------------------------------------------
* zstd_codec_init - constructor
*-------------------------------------------------
*/
static chd_error zstd_codec_init(void* codec, uint32_t hunkbytes)
{
zstd_codec_data* zstd_codec = (zstd_codec_data*) codec;
zstd_codec->dstream = ZSTD_createDStream();
if (!zstd_codec->dstream) {
printf("NO DSTREAM CREATED!\n");
return CHDERR_DECOMPRESSION_ERROR;
}
return CHDERR_NONE;
}
/*-------------------------------------------------
* zstd_codec_free
*-------------------------------------------------
*/
static void zstd_codec_free(void* codec)
{
zstd_codec_data* zstd_codec = (zstd_codec_data*) codec;
ZSTD_freeDStream(zstd_codec->dstream);
}
/*-------------------------------------------------
* decompress - decompress data using the ZSTD
* codec
*-------------------------------------------------
*/
static chd_error zstd_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
{
/* initialize */
zstd_codec_data* zstd_codec = (zstd_codec_data*) codec;
//reset decompressor
size_t zstd_res = ZSTD_initDStream(zstd_codec->dstream);
if (ZSTD_isError(zstd_res))
{
printf("INITI DSTREAM FAILED!\n");
return CHDERR_DECOMPRESSION_ERROR;
}
ZSTD_inBuffer input = {src, complen, 0};
ZSTD_outBuffer output = {dest, destlen, 0 };
while ((input.pos < input.size) && (output.pos < output.size))
{
zstd_res = ZSTD_decompressStream(zstd_codec->dstream, &output, &input);
if (ZSTD_isError(zstd_res))
{
printf("DECOMPRESSION ERROR IN LOOP\n");
return CHDERR_DECOMPRESSION_ERROR;
}
}
if (output.pos != output.size)
{
printf("OUTPUT DOESN'T MATCH!\n");
return CHDERR_DECOMPRESSION_ERROR;
}
return CHDERR_NONE;
}
/* cdzs */
static chd_error cdzs_codec_init(void* codec, uint32_t hunkbytes)
{
chd_error ret;
cdzs_codec_data* cdzs = (cdzs_codec_data*) codec;
/* allocate buffer */
cdzs->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
if (cdzs->buffer == NULL)
return CHDERR_OUT_OF_MEMORY;
/* make sure the CHD's hunk size is an even multiple of the frame size */
ret = zstd_codec_init(&cdzs->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
if (ret != CHDERR_NONE)
return ret;
#ifdef WANT_SUBCODE
ret = zstd_codec_init(&cdzs->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
if (ret != CHDERR_NONE)
return ret;
#endif
if (hunkbytes % CD_FRAME_SIZE != 0)
return CHDERR_CODEC_ERROR;
return CHDERR_NONE;
}
static void cdzs_codec_free(void* codec)
{
cdzs_codec_data* cdzs = (cdzs_codec_data*) codec;
free(cdzs->buffer);
zstd_codec_free(&cdzs->base_decompressor);
#ifdef WANT_SUBCODE
zstd_codec_free(&cdzs->subcode_decompressor);
#endif
}
static chd_error cdzs_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
{
uint32_t framenum;
cdzs_codec_data* cdzs = (cdzs_codec_data*)codec;
/* determine header bytes */
uint32_t frames = destlen / CD_FRAME_SIZE;
uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
uint32_t ecc_bytes = (frames + 7) / 8;
uint32_t header_bytes = ecc_bytes + complen_bytes;
/* extract compressed length of base */
uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
if (complen_bytes > 2)
complen_base = (complen_base << 8) | src[ecc_bytes + 2];
/* reset and decode */
zstd_codec_decompress(&cdzs->base_decompressor, &src[header_bytes], complen_base, &cdzs->buffer[0], frames * CD_MAX_SECTOR_DATA);
#ifdef WANT_SUBCODE
zstd_codec_decompress(&cdzs->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdzs->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
#endif
/* reassemble the data */
for (framenum = 0; framenum < frames; framenum++)
{
uint8_t *sector;
memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzs->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
#ifdef WANT_SUBCODE
memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzs->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
#endif
#ifdef WANT_RAW_DATA_SECTOR
/* reconstitute the ECC data and sync header */
sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
{
memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
ecc_generate(sector);
}
#endif
}
return CHDERR_NONE;
}
/*************************************************************************** /***************************************************************************
CODEC INTERFACES CODEC INTERFACES
***************************************************************************/ ***************************************************************************/
@ -1068,6 +1256,16 @@ static const codec_interface codec_interfaces[] =
flac_codec_decompress, flac_codec_decompress,
NULL NULL
}, },
/* V5 zstd compression */
{
CHD_CODEC_ZSTD,
"ZStandard",
FALSE,
zstd_codec_init,
zstd_codec_free,
zstd_codec_decompress,
NULL
},
/* V5 CD zlib compression */ /* V5 CD zlib compression */
{ {
@ -1101,6 +1299,17 @@ static const codec_interface codec_interfaces[] =
cdfl_codec_decompress, cdfl_codec_decompress,
NULL NULL
}, },
/* V5 CD zstd compression */
{
CHD_CODEC_CD_ZSTD,
"cdzs (CD ZStandard)",
FALSE,
cdzs_codec_init,
cdzs_codec_free,
cdzs_codec_decompress,
NULL
}
}; };
/*************************************************************************** /***************************************************************************
@ -1702,6 +1911,10 @@ CHD_EXPORT chd_error chd_open_core_file(core_file *file, int mode, chd_file *par
codec = &newchd->flac_codec_data; codec = &newchd->flac_codec_data;
break; break;
case CHD_CODEC_ZSTD:
codec = &newchd->zstd_codec_data;
break;
case CHD_CODEC_CD_ZLIB: case CHD_CODEC_CD_ZLIB:
codec = &newchd->cdzl_codec_data; codec = &newchd->cdzl_codec_data;
break; break;
@ -1713,6 +1926,10 @@ CHD_EXPORT chd_error chd_open_core_file(core_file *file, int mode, chd_file *par
case CHD_CODEC_CD_FLAC: case CHD_CODEC_CD_FLAC:
codec = &newchd->cdfl_codec_data; codec = &newchd->cdfl_codec_data;
break; break;
case CHD_CODEC_CD_ZSTD:
codec = &newchd->cdzs_codec_data;
break;
} }
if (codec == NULL) if (codec == NULL)
@ -1885,6 +2102,10 @@ CHD_EXPORT void chd_close(chd_file *chd)
codec = &chd->flac_codec_data; codec = &chd->flac_codec_data;
break; break;
case CHD_CODEC_ZSTD:
codec = &chd->zstd_codec_data;
break;
case CHD_CODEC_CD_ZLIB: case CHD_CODEC_CD_ZLIB:
codec = &chd->cdzl_codec_data; codec = &chd->cdzl_codec_data;
break; break;
@ -1896,6 +2117,10 @@ CHD_EXPORT void chd_close(chd_file *chd)
case CHD_CODEC_CD_FLAC: case CHD_CODEC_CD_FLAC:
codec = &chd->cdfl_codec_data; codec = &chd->cdfl_codec_data;
break; break;
case CHD_CODEC_CD_ZSTD:
codec = &chd->cdzs_codec_data;
break;
} }
if (codec) if (codec)
@ -2554,7 +2779,9 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
/* read it into the decompression buffer */ /* read it into the decompression buffer */
compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length); compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
if (compressed_bytes == NULL) if (compressed_bytes == NULL)
{
return CHDERR_READ_ERROR; return CHDERR_READ_ERROR;
}
/* now decompress using the codec */ /* now decompress using the codec */
err = CHDERR_NONE; err = CHDERR_NONE;
@ -2664,6 +2891,10 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
codec = &chd->flac_codec_data; codec = &chd->flac_codec_data;
break; break;
case CHD_CODEC_ZSTD:
codec = &chd->zstd_codec_data;
break;
case CHD_CODEC_CD_ZLIB: case CHD_CODEC_CD_ZLIB:
codec = &chd->cdzl_codec_data; codec = &chd->cdzl_codec_data;
break; break;
@ -2675,6 +2906,10 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
case CHD_CODEC_CD_FLAC: case CHD_CODEC_CD_FLAC:
codec = &chd->cdfl_codec_data; codec = &chd->cdfl_codec_data;
break; break;
case CHD_CODEC_CD_ZSTD:
codec = &chd->cdzs_codec_data;
break;
} }
if (codec==NULL) if (codec==NULL)
return CHDERR_CODEC_ERROR; return CHDERR_CODEC_ERROR;

View File

@ -295,6 +295,9 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
} }
} }
/* make sure we free the local huffman decoder */
delete_huffman_decoder(smallhuff);
/* make sure we ended up with the right number */ /* make sure we ended up with the right number */
if (curcode != decoder->numcodes) if (curcode != decoder->numcodes)
return HUFFERR_INVALID_DATA; return HUFFERR_INVALID_DATA;