mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 00:45:47 -04:00
dep/libchdr: Rebase to upstream 2a1119c
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user