mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-22 05:45:38 +00:00
dep/libchdr: Rebase to upstream 2a1119c
This commit is contained in:
parent
a1da72202b
commit
0e6a9f637b
|
@ -15,5 +15,5 @@ add_library(libchdr
|
|||
)
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
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
|
||||
|
||||
|
@ -235,12 +235,12 @@ extern "C" {
|
|||
|
||||
#define DRFLAC_VERSION_MAJOR 0
|
||||
#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)
|
||||
|
||||
#include <stddef.h> /* For size_t. */
|
||||
|
||||
/* Sized types. */
|
||||
/* Sized Types */
|
||||
typedef signed char drflac_int8;
|
||||
typedef unsigned char drflac_uint8;
|
||||
typedef signed short drflac_int16;
|
||||
|
@ -273,7 +273,9 @@ typedef drflac_uint8 drflac_bool8;
|
|||
typedef drflac_uint32 drflac_bool32;
|
||||
#define DRFLAC_TRUE 1
|
||||
#define DRFLAC_FALSE 0
|
||||
/* End Sized Types */
|
||||
|
||||
/* Decorations */
|
||||
#if !defined(DRFLAC_API)
|
||||
#if defined(DRFLAC_DLL)
|
||||
#if defined(_WIN32)
|
||||
|
@ -303,6 +305,7 @@ typedef drflac_uint32 drflac_bool32;
|
|||
#define DRFLAC_PRIVATE static
|
||||
#endif
|
||||
#endif
|
||||
/* End Decorations */
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1700 /* Visual Studio 2012 */
|
||||
#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 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,
|
||||
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
|
||||
#endif
|
||||
|
||||
/* Check if we can enable 64-bit optimizations. */
|
||||
|
||||
/* Architecture Detection */
|
||||
#if defined(_WIN64) || defined(_LP64) || defined(__LP64__)
|
||||
#define DRFLAC_64BIT
|
||||
#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
|
||||
typedef drflac_uint64 drflac_cache_t;
|
||||
#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 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. */
|
||||
typedef struct
|
||||
{
|
||||
|
@ -1351,6 +1367,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Inline */
|
||||
#ifdef _MSC_VER
|
||||
#define DRFLAC_INLINE __forceinline
|
||||
#elif defined(__GNUC__)
|
||||
|
@ -1377,15 +1394,7 @@ DRFLAC_API drflac_bool32 drflac_next_cuesheet_track(drflac_cuesheet_track_iterat
|
|||
#else
|
||||
#define DRFLAC_INLINE
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
/* End Inline */
|
||||
|
||||
/*
|
||||
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. */
|
||||
|
||||
/* Result Codes */
|
||||
typedef drflac_int32 drflac_result;
|
||||
#define DRFLAC_SUCCESS 0
|
||||
#define DRFLAC_ERROR -1 /* A generic error. */
|
||||
|
@ -1678,7 +1688,10 @@ typedef drflac_int32 drflac_result;
|
|||
#define DRFLAC_CANCELLED -51
|
||||
#define DRFLAC_MEMORY_ALREADY_MAPPED -52
|
||||
#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_VERBATIM 1
|
||||
|
@ -1838,7 +1851,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__swap_endian_uint32(drflac_uint32 n)
|
|||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
return _byteswap_ulong(n);
|
||||
#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(). */
|
||||
drflac_uint32 r;
|
||||
__asm__ __volatile__ (
|
||||
|
@ -2802,7 +2815,7 @@ static DRFLAC_INLINE drflac_uint32 drflac__clz_lzcnt(drflac_cache_t x)
|
|||
|
||||
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;
|
||||
__asm__ __volatile__ (
|
||||
|
@ -6479,7 +6492,7 @@ static drflac_bool32 drflac__read_and_decode_metadata(drflac_read_proc onRead, d
|
|||
for (;;) {
|
||||
drflac_metadata metadata;
|
||||
drflac_uint8 isLastBlock = 0;
|
||||
drflac_uint8 blockType;
|
||||
drflac_uint8 blockType = 0;
|
||||
drflac_uint32 blockSize;
|
||||
if (drflac__read_and_decode_block_header(onRead, pUserData, &isLastBlock, &blockType, &blockSize) == 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() */
|
||||
#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. */
|
||||
#include <errno.h>
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* End Errno */
|
||||
|
||||
/* fopen */
|
||||
static drflac_result drflac_fopen(FILE** ppFile, const char* pFilePath, const char* pOpenMode)
|
||||
{
|
||||
#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;
|
||||
}
|
||||
#endif
|
||||
/* End fopen */
|
||||
|
||||
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 */
|
||||
|
||||
/* SIZE_MAX */
|
||||
#if defined(SIZE_MAX)
|
||||
#define DRFLAC_SIZE_MAX SIZE_MAX
|
||||
#else
|
||||
|
@ -11675,6 +11693,7 @@ DRFLAC_API drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 p
|
|||
#define DRFLAC_SIZE_MAX 0xFFFFFFFF
|
||||
#endif
|
||||
#endif
|
||||
/* End SIZE_MAX */
|
||||
|
||||
|
||||
/* 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
|
||||
================
|
||||
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
|
||||
- Fix compilation with DJGPP.
|
||||
- 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
|
||||
===============================================================================
|
||||
Copyright 2020 David Reid
|
||||
Copyright 2023 David Reid
|
||||
|
||||
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
|
||||
|
|
|
@ -208,10 +208,12 @@ extern "C" {
|
|||
#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_FLAC CHD_MAKE_TAG('f','l','a','c')
|
||||
#define CHD_CODEC_ZSTD CHD_MAKE_TAG('z', 's', 't', 'd')
|
||||
/* general codecs with CD frontend */
|
||||
#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_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 */
|
||||
#define AV_CODEC_COMPRESS_CONFIG 1
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\msvc\vsprops\Configurations.props" />
|
||||
<ItemGroup Condition="'$(Configuration)'!='DebugUWP' And '$(Configuration)'!='ReleaseUWP'">
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\lzma\lzma.vcxproj">
|
||||
<Project>{dd944834-7899-4c1c-a4c1-064b5009d239}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\zlib\zlib.vcxproj">
|
||||
<Project>{7ff9fdb9-d504-47db-a16a-b08071999620}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\zstd\zstd.vcxproj">
|
||||
<Project>{73ee0c55-6ffe-44e7-9c12-baa52434a797}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\libchdr_bitstream.c" />
|
||||
|
@ -33,7 +36,7 @@
|
|||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<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>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="..\msvc\vsprops\Targets.props" />
|
||||
|
|
|
@ -48,13 +48,14 @@
|
|||
#include <libchdr/cdrom.h>
|
||||
#include <libchdr/flac.h>
|
||||
#include <libchdr/huffman.h>
|
||||
#include <zstd.h>
|
||||
|
||||
#include "LzmaEnc.h"
|
||||
#include "LzmaDec.h"
|
||||
#if defined(__PS3__) || defined(__PSL1GHT__)
|
||||
#define __MACTYPES__
|
||||
#endif
|
||||
#include "zlib.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
|
@ -234,6 +235,12 @@ struct _huff_codec_data
|
|||
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 */
|
||||
typedef struct _cdzl_codec_data cdzl_codec_data;
|
||||
struct _cdzl_codec_data {
|
||||
|
@ -276,6 +283,16 @@ struct _cdfl_codec_data {
|
|||
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 */
|
||||
struct _chd_file
|
||||
{
|
||||
|
@ -303,9 +320,11 @@ struct _chd_file
|
|||
lzma_codec_data lzma_codec_data; /* lzma codec data */
|
||||
huff_codec_data huff_codec_data; /* huff 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 */
|
||||
cdlz_codec_data cdlz_codec_data; /* cdlz codec data */
|
||||
cdfl_codec_data cdfl_codec_data; /* cdfl codec data */
|
||||
cdzs_codec_data cdzs_codec_data; /* cdzs codec data */
|
||||
|
||||
#ifdef NEED_CACHE_HUNK
|
||||
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 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 */
|
||||
static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
|
||||
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 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
|
||||
***************************************************************************
|
||||
|
@ -812,11 +842,12 @@ static chd_error huff_codec_decompress(void *codec, const uint8_t *src, uint32_t
|
|||
if (err != HUFFERR_NONE)
|
||||
{
|
||||
free(bitbuf);
|
||||
return err;
|
||||
return CHDERR_DECOMPRESSION_ERROR;
|
||||
}
|
||||
|
||||
// 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);
|
||||
bitstream_flush(bitbuf);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* 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
|
||||
***************************************************************************/
|
||||
|
@ -1068,6 +1256,16 @@ static const codec_interface codec_interfaces[] =
|
|||
flac_codec_decompress,
|
||||
NULL
|
||||
},
|
||||
/* V5 zstd compression */
|
||||
{
|
||||
CHD_CODEC_ZSTD,
|
||||
"ZStandard",
|
||||
FALSE,
|
||||
zstd_codec_init,
|
||||
zstd_codec_free,
|
||||
zstd_codec_decompress,
|
||||
NULL
|
||||
},
|
||||
|
||||
/* V5 CD zlib compression */
|
||||
{
|
||||
|
@ -1101,6 +1299,17 @@ static const codec_interface codec_interfaces[] =
|
|||
cdfl_codec_decompress,
|
||||
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;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_ZSTD:
|
||||
codec = &newchd->zstd_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZLIB:
|
||||
codec = &newchd->cdzl_codec_data;
|
||||
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:
|
||||
codec = &newchd->cdfl_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZSTD:
|
||||
codec = &newchd->cdzs_codec_data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (codec == NULL)
|
||||
|
@ -1885,6 +2102,10 @@ CHD_EXPORT void chd_close(chd_file *chd)
|
|||
codec = &chd->flac_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_ZSTD:
|
||||
codec = &chd->zstd_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZLIB:
|
||||
codec = &chd->cdzl_codec_data;
|
||||
break;
|
||||
|
@ -1896,6 +2117,10 @@ CHD_EXPORT void chd_close(chd_file *chd)
|
|||
case CHD_CODEC_CD_FLAC:
|
||||
codec = &chd->cdfl_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZSTD:
|
||||
codec = &chd->cdzs_codec_data;
|
||||
break;
|
||||
}
|
||||
|
||||
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 */
|
||||
compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
|
||||
if (compressed_bytes == NULL)
|
||||
{
|
||||
return CHDERR_READ_ERROR;
|
||||
}
|
||||
|
||||
/* now decompress using the codec */
|
||||
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;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_ZSTD:
|
||||
codec = &chd->zstd_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZLIB:
|
||||
codec = &chd->cdzl_codec_data;
|
||||
break;
|
||||
|
@ -2675,6 +2906,10 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
|
|||
case CHD_CODEC_CD_FLAC:
|
||||
codec = &chd->cdfl_codec_data;
|
||||
break;
|
||||
|
||||
case CHD_CODEC_CD_ZSTD:
|
||||
codec = &chd->cdzs_codec_data;
|
||||
break;
|
||||
}
|
||||
if (codec==NULL)
|
||||
return CHDERR_CODEC_ERROR;
|
||||
|
|
|
@ -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 */
|
||||
if (curcode != decoder->numcodes)
|
||||
return HUFFERR_INVALID_DATA;
|
||||
|
|
Loading…
Reference in a new issue