dep/libchdr: Rebase to upstream 2a1119c

This commit is contained in:
Stenzek
2024-02-18 15:14:07 +09:00
parent a1da72202b
commit 0e6a9f637b
6 changed files with 304 additions and 32 deletions

View File

@ -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;