Merge pull request #6052 from orbea/libchdr

Backport changes from libchdr upstream
This commit is contained in:
Twinaphex 2018-01-06 07:10:36 +01:00 committed by GitHub
commit 74942551ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 216 additions and 262 deletions

View File

@ -1,7 +1,6 @@
/* license:BSD-3-Clause
* copyright-holders:Aaron Giles
*/
/***************************************************************************
***************************************************************************
bitstream.c

View File

@ -1,8 +1,6 @@
/* license:BSD-3-Clause
*
* copyright-holders:Aaron Giles
*/
/***************************************************************************
***************************************************************************
cdrom.c

View File

@ -62,8 +62,6 @@
#define PRINTF_MAX_HUNK (0)
/***************************************************************************
CONSTANTS
***************************************************************************/
@ -137,15 +135,12 @@ enum
COMPRESSION_PARENT_1
};
/***************************************************************************
MACROS
***************************************************************************/
#define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@ -163,7 +158,6 @@ struct _codec_interface
chd_error (*config)(void *codec, int param, void *config); /* configure */
};
/* a single map entry */
typedef struct _map_entry map_entry;
struct _map_entry
@ -174,7 +168,6 @@ struct _map_entry
UINT8 flags; /* misc flags */
};
/* a single metadata entry */
typedef struct _metadata_entry metadata_entry;
struct _metadata_entry
@ -289,7 +282,6 @@ struct _chd_file
#endif
};
/***************************************************************************
GLOBAL VARIABLES
***************************************************************************/
@ -297,16 +289,13 @@ struct _chd_file
static const UINT8 nullmd5[CHD_MD5_BYTES] = { 0 };
static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };
/***************************************************************************
PROTOTYPES
***************************************************************************/
/* internal header operations */
static chd_error header_validate(const chd_header *header);
static chd_error header_read(core_file *file, chd_header *header);
static chd_error header_read(chd_file *chd, chd_header *header);
/* internal hunk read/write */
#ifdef NEED_CACHE_HUNK
@ -320,7 +309,6 @@ static chd_error map_read(chd_file *chd);
/* metadata management */
static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry);
/* zlib compression codec */
static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes);
static void zlib_codec_free(void *codec);
@ -434,7 +422,6 @@ void *lzma_fast_alloc(void *p, size_t size)
return addr + 1;
}
/*-------------------------------------------------
* lzma_fast_free - fast free for lzma, which
* allocates and frees memory frequently
@ -469,7 +456,6 @@ void lzma_fast_free(void *p, void *address)
***************************************************************************
*/
/*-------------------------------------------------
* lzma_codec_init - constructor
*-------------------------------------------------
@ -525,7 +511,6 @@ chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
return CHDERR_NONE;
}
/*-------------------------------------------------
* lzma_codec_free
*-------------------------------------------------
@ -541,7 +526,6 @@ void lzma_codec_free(void* codec)
LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator);
}
/*-------------------------------------------------
* decompress - decompress data using the LZMA
* codec
@ -650,7 +634,6 @@ chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t comple
return CHDERR_NONE;
}
/* cdzl */
chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes)
@ -742,8 +725,6 @@ chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple
***************************************************************************
*/
/*------------------------------------------------------
* cdfl_codec_blocksize - return the optimal block size
*------------------------------------------------------
@ -940,7 +921,6 @@ static INLINE UINT64 get_bigendian_uint64(const UINT8 *base)
((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
}
/*-------------------------------------------------
put_bigendian_uint64 - write a UINT64 to
the data stream in bigendian order
@ -994,7 +974,6 @@ static INLINE UINT32 get_bigendian_uint32(const UINT8 *base)
return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
}
/*-------------------------------------------------
put_bigendian_uint32 - write a UINT32 to
the data stream in bigendian order
@ -1008,7 +987,6 @@ static INLINE void put_bigendian_uint24(UINT8 *base, UINT32 value)
base[2] = value;
}
/*-------------------------------------------------
put_bigendian_uint24 - write a UINT24 to
the data stream in bigendian order
@ -1042,7 +1020,6 @@ static INLINE UINT16 get_bigendian_uint16(const UINT8 *base)
return (base[0] << 8) | base[1];
}
/*-------------------------------------------------
put_bigendian_uint16 - write a UINT16 to
the data stream in bigendian order
@ -1054,7 +1031,6 @@ static INLINE void put_bigendian_uint16(UINT8 *base, UINT16 value)
base[1] = value;
}
/*-------------------------------------------------
map_extract - extract a single map
entry from the datastream
@ -1068,7 +1044,6 @@ static INLINE void map_extract(const UINT8 *base, map_entry *entry)
entry->flags = base[15];
}
/*-------------------------------------------------
map_assemble - write a single map
entry to the datastream
@ -1091,7 +1066,6 @@ static INLINE int map_size_v5(chd_header* header)
return header->hunkcount * header->mapentrybytes;
}
/*-------------------------------------------------
crc16 - calculate CRC16 (from hashing.cpp)
-------------------------------------------------*/
@ -1331,12 +1305,10 @@ static INLINE void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 h
#endif
}
/***************************************************************************
CHD FILE MANAGEMENT
***************************************************************************/
/*-------------------------------------------------
chd_open_file - open a CHD file for access
-------------------------------------------------*/
@ -1365,7 +1337,7 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **
newchd->file = file;
/* now attempt to read the header */
err = header_read(newchd->file, &newchd->header);
err = header_read(newchd, &newchd->header);
if (err != CHDERR_NONE)
EARLY_EXIT(err);
@ -1416,7 +1388,7 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **
}
#ifdef NEED_CACHE_HUNK
/* allocate and init the hunk cache */
/* allocate and init the hunk cache */
newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
if (newchd->cache == NULL || newchd->compare == NULL)
@ -1555,7 +1527,6 @@ cleanup:
return err;
}
/*-------------------------------------------------
chd_close - close a CHD file for access
-------------------------------------------------*/
@ -1632,7 +1603,6 @@ void chd_close(chd_file *chd)
free(chd);
}
/*-------------------------------------------------
chd_core_file - return the associated
core_file
@ -1643,7 +1613,6 @@ core_file *chd_core_file(chd_file *chd)
return chd->file;
}
/*-------------------------------------------------
chd_error_string - return an error string for
the given CHD error
@ -1685,8 +1654,6 @@ const char *chd_error_string(chd_error err)
}
}
/***************************************************************************
CHD HEADER MANAGEMENT
***************************************************************************/
@ -1705,8 +1672,6 @@ const chd_header *chd_get_header(chd_file *chd)
return &chd->header;
}
/***************************************************************************
CORE DATA READ/WRITE
***************************************************************************/
@ -1726,10 +1691,6 @@ chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
}
/***************************************************************************
METADATA MANAGEMENT
***************************************************************************/
@ -1789,8 +1750,6 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex,
return CHDERR_NONE;
}
/***************************************************************************
CODEC INTERFACES
***************************************************************************/
@ -1805,7 +1764,6 @@ chd_error chd_codec_config(chd_file *chd, int param, void *config)
return CHDERR_INVALID_PARAMETER;
}
/*-------------------------------------------------
chd_get_codec_name - get the name of a
particular codec
@ -1816,7 +1774,6 @@ const char *chd_get_codec_name(UINT32 codec)
return "Unknown";
}
/***************************************************************************
INTERNAL HEADER OPERATIONS
***************************************************************************/
@ -1885,13 +1842,37 @@ static chd_error header_validate(const chd_header *header)
return CHDERR_NONE;
}
/*-------------------------------------------------
header_guess_unitbytes - for older CHD formats,
guess at the bytes/unit based on metadata
-------------------------------------------------*/
static UINT32 header_guess_unitbytes(chd_file *chd)
{
/* look for hard disk metadata; if found, then the unit size == sector size */
char metadata[512];
int i0, i1, i2, i3;
if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
return i3;
/* look for CD-ROM metadata; if found, then the unit size == CD frame size */
if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
return CD_FRAME_SIZE;
/* otherwise, just map 1:1 with the hunk size */
return chd->header.hunkbytes;
}
/*-------------------------------------------------
header_read - read a CHD header into the
internal data structure
-------------------------------------------------*/
static chd_error header_read(core_file *file, chd_header *header)
static chd_error header_read(chd_file *chd, chd_header *header)
{
UINT8 rawheader[CHD_MAX_HEADER_SIZE];
UINT32 count;
@ -1901,12 +1882,12 @@ static chd_error header_read(core_file *file, chd_header *header)
return CHDERR_INVALID_PARAMETER;
/* punt if invalid file */
if (file == NULL)
if (chd->file == NULL)
return CHDERR_INVALID_FILE;
/* seek and read */
core_fseek(file, 0, SEEK_SET);
count = core_fread(file, rawheader, sizeof(rawheader));
core_fseek(chd->file, 0, SEEK_SET);
count = core_fread(chd->file, rawheader, sizeof(rawheader));
if (count != sizeof(rawheader))
return CHDERR_READ_ERROR;
@ -1949,6 +1930,8 @@ static chd_error header_read(core_file *file, chd_header *header)
memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
header->hunkbytes = seclen * header->obsolete_hunksize;
header->unitbytes = header_guess_unitbytes(chd);
header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
header->metaoffset = 0;
}
@ -1961,6 +1944,8 @@ static chd_error header_read(core_file *file, chd_header *header)
memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
header->hunkbytes = get_bigendian_uint32(&rawheader[76]);
header->unitbytes = header_guess_unitbytes(chd);
header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
}
@ -1972,6 +1957,8 @@ static chd_error header_read(core_file *file, chd_header *header)
header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
header->metaoffset = get_bigendian_uint64(&rawheader[36]);
header->hunkbytes = get_bigendian_uint32(&rawheader[44]);
header->unitbytes = header_guess_unitbytes(chd);
header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
@ -1981,23 +1968,23 @@ static chd_error header_read(core_file *file, chd_header *header)
else if (header->version == 5)
{
/* TODO */
header->compression[0] = get_bigendian_uint32(&rawheader[16]);
header->compression[1] = get_bigendian_uint32(&rawheader[20]);
header->compression[2] = get_bigendian_uint32(&rawheader[24]);
header->compression[3] = get_bigendian_uint32(&rawheader[28]);
header->logicalbytes = get_bigendian_uint64(&rawheader[32]);
header->mapoffset = get_bigendian_uint64(&rawheader[40]);
header->metaoffset = get_bigendian_uint64(&rawheader[48]);
header->hunkbytes = get_bigendian_uint32(&rawheader[56]);
header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
header->unitbytes = get_bigendian_uint32(&rawheader[60]);
header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
header->compression[0] = get_bigendian_uint32(&rawheader[16]);
header->compression[1] = get_bigendian_uint32(&rawheader[20]);
header->compression[2] = get_bigendian_uint32(&rawheader[24]);
header->compression[3] = get_bigendian_uint32(&rawheader[28]);
header->logicalbytes = get_bigendian_uint64(&rawheader[32]);
header->mapoffset = get_bigendian_uint64(&rawheader[40]);
header->metaoffset = get_bigendian_uint64(&rawheader[48]);
header->hunkbytes = get_bigendian_uint32(&rawheader[56]);
header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
header->unitbytes = get_bigendian_uint32(&rawheader[60]);
header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
/* determine properties of map entries */
header->mapentrybytes = 12; /*TODO compressed() ? 12 : 4; */
header->mapentrybytes = 12; /* TODO compressed() ? 12 : 4; */
/* hack */
header->totalhunks = header->hunkcount;
@ -2013,7 +2000,6 @@ static chd_error header_read(core_file *file, chd_header *header)
return CHDERR_NONE;
}
/***************************************************************************
INTERNAL HUNK READ/WRITE
***************************************************************************/
@ -2055,181 +2041,180 @@ static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
{
chd_error err;
chd_error err;
/* punt if no file */
if (chd->file == NULL)
return CHDERR_INVALID_FILE;
/* punt if no file */
if (chd->file == NULL)
return CHDERR_INVALID_FILE;
/* return an error if out of range */
if (hunknum >= chd->header.totalhunks)
return CHDERR_HUNK_OUT_OF_RANGE;
/* return an error if out of range */
if (hunknum >= chd->header.totalhunks)
return CHDERR_HUNK_OUT_OF_RANGE;
if (dest == NULL)
return CHDERR_INVALID_PARAMETER;
if (dest == NULL)
return CHDERR_INVALID_PARAMETER;
if (chd->header.version < 5)
{
void* codec;
map_entry *entry = &chd->map[hunknum];
UINT32 bytes;
if (chd->header.version < 5)
{
void* codec;
map_entry *entry = &chd->map[hunknum];
UINT32 bytes;
/* switch off the entry type */
switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
{
/* compressed data */
case V34_MAP_ENTRY_TYPE_COMPRESSED:
/* switch off the entry type */
switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
{
/* compressed data */
case V34_MAP_ENTRY_TYPE_COMPRESSED:
/* read it into the decompression buffer */
if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
bytes = core_fread(chd->file, chd->compressed, entry->length);
if (bytes != entry->length)
return CHDERR_READ_ERROR;
/* read it into the decompression buffer */
if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
bytes = core_fread(chd->file, chd->compressed, entry->length);
if (bytes != entry->length)
return CHDERR_READ_ERROR;
/* now decompress using the codec */
err = CHDERR_NONE;
codec = &chd->zlib_codec_data;
if (chd->codecintf[0]->decompress != NULL)
err = (*chd->codecintf[0]->decompress)(codec, chd->compressed, entry->length, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE)
return err;
break;
/* now decompress using the codec */
err = CHDERR_NONE;
codec = &chd->zlib_codec_data;
if (chd->codecintf[0]->decompress != NULL)
err = (*chd->codecintf[0]->decompress)(codec, chd->compressed, entry->length, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE)
return err;
break;
/* uncompressed data */
case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
bytes = core_fread(chd->file, dest, chd->header.hunkbytes);
if (bytes != chd->header.hunkbytes)
return CHDERR_READ_ERROR;
break;
/* uncompressed data */
case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
if (core_fseek(chd->file, entry->offset, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
bytes = core_fread(chd->file, dest, chd->header.hunkbytes);
if (bytes != chd->header.hunkbytes)
return CHDERR_READ_ERROR;
break;
/* mini-compressed data */
case V34_MAP_ENTRY_TYPE_MINI:
put_bigendian_uint64(&dest[0], entry->offset);
for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
dest[bytes] = dest[bytes - 8];
break;
/* mini-compressed data */
case V34_MAP_ENTRY_TYPE_MINI:
put_bigendian_uint64(&dest[0], entry->offset);
for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
dest[bytes] = dest[bytes - 8];
break;
/* self-referenced data */
case V34_MAP_ENTRY_TYPE_SELF_HUNK:
/* self-referenced data */
case V34_MAP_ENTRY_TYPE_SELF_HUNK:
#ifdef NEED_CACHE_HUNK
if (chd->cachehunk == entry->offset && dest == chd->cache)
break;
if (chd->cachehunk == entry->offset && dest == chd->cache)
break;
#endif
return hunk_read_into_memory(chd, entry->offset, dest);
return hunk_read_into_memory(chd, entry->offset, dest);
/* parent-referenced data */
case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
err = hunk_read_into_memory(chd->parent, entry->offset, dest);
if (err != CHDERR_NONE)
return err;
break;
}
return CHDERR_NONE;
}
else
{
void* codec = NULL;
/* get a pointer to the map entry */
uint64_t blockoffs;
uint32_t blocklen;
/* parent-referenced data */
case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
err = hunk_read_into_memory(chd->parent, entry->offset, dest);
if (err != CHDERR_NONE)
return err;
break;
}
return CHDERR_NONE;
}
else
{
void* codec = NULL;
/* get a pointer to the map entry */
uint64_t blockoffs;
uint32_t blocklen;
#ifdef VERIFY_BLOCK_CRC
uint16_t blockcrc;
uint16_t blockcrc;
#endif
uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
/* uncompressed case */
/* TODO
if (!compressed())
{
blockoffs = uint64_t(be_read(rawmap, 4)) * uint64_t(m_hunkbytes);
if (blockoffs != 0)
file_read(blockoffs, dest, m_hunkbytes);
else if (m_parent_missing)
throw CHDERR_REQUIRES_PARENT;
else if (m_parent != nullptr)
m_parent->read_hunk(hunknum, dest);
else
memset(dest, 0, m_hunkbytes);
return CHDERR_NONE;
}*/
/* compressed case */
blocklen = get_bigendian_uint24(&rawmap[1]);
blockoffs = get_bigendian_uint48(&rawmap[4]);
#ifdef VERIFY_BLOCK_CRC
blockcrc = get_bigendian_uint16(&rawmap[10]);
#endif
switch (rawmap[0])
{
case COMPRESSION_TYPE_0:
case COMPRESSION_TYPE_1:
case COMPRESSION_TYPE_2:
case COMPRESSION_TYPE_3:
if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
if (core_fread(chd->file, chd->compressed, blocklen) != blocklen)
return CHDERR_READ_ERROR;
switch (chd->codecintf[rawmap[0]]->compression)
{
case CHD_CODEC_CD_LZMA:
codec = &chd->cdlz_codec_data;
break;
case CHD_CODEC_CD_ZLIB:
codec = &chd->cdzl_codec_data;
break;
case CHD_CODEC_CD_FLAC:
codec = &chd->cdfl_codec_data;
break;
}
if (codec==NULL)
return CHDERR_CODEC_ERROR;
err = (*chd->codecintf[rawmap[0]]->decompress)(codec, chd->compressed, blocklen, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE)
return err;
#ifdef VERIFY_BLOCK_CRC
if (crc16(dest, chd->header.hunkbytes) != blockcrc)
return CHDERR_DECOMPRESSION_ERROR;
#endif
return CHDERR_NONE;
case COMPRESSION_NONE:
if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
if (core_fread(chd->file, dest, chd->header.hunkbytes) != chd->header.hunkbytes)
return CHDERR_READ_ERROR;
#ifdef VERIFY_BLOCK_CRC
if (crc16(dest, chd->header.hunkbytes) != blockcrc)
return CHDERR_DECOMPRESSION_ERROR;
#endif
return CHDERR_NONE;
case COMPRESSION_SELF:
return hunk_read_into_memory(chd, blockoffs, dest);
case COMPRESSION_PARENT:
/* TODO */
#if 0
if (m_parent_missing)
return CHDERR_REQUIRES_PARENT;
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
/* uncompressed case - TODO */
if (!compressed())
{
blockoffs = uint64_t(be_read(rawmap, 4)) * uint64_t(m_hunkbytes);
if (blockoffs != 0)
file_read(blockoffs, dest, m_hunkbytes);
else if (m_parent_missing)
throw CHDERR_REQUIRES_PARENT;
else if (m_parent != nullptr)
m_parent->read_hunk(hunknum, dest);
else
memset(dest, 0, m_hunkbytes);
return CHDERR_NONE;
}
#endif
return CHDERR_DECOMPRESSION_ERROR;
}
return CHDERR_NONE;
}
/* compressed case */
blocklen = get_bigendian_uint24(&rawmap[1]);
blockoffs = get_bigendian_uint48(&rawmap[4]);
#ifdef VERIFY_BLOCK_CRC
blockcrc = get_bigendian_uint16(&rawmap[10]);
#endif
switch (rawmap[0])
{
case COMPRESSION_TYPE_0:
case COMPRESSION_TYPE_1:
case COMPRESSION_TYPE_2:
case COMPRESSION_TYPE_3:
if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
if(core_fread(chd->file, chd->compressed, blocklen) != blocklen)
return CHDERR_READ_ERROR;
/* We should not reach this code */
return CHDERR_DECOMPRESSION_ERROR;
switch (chd->codecintf[rawmap[0]]->compression)
{
case CHD_CODEC_CD_LZMA:
codec = &chd->cdlz_codec_data;
break;
case CHD_CODEC_CD_ZLIB:
codec = &chd->cdzl_codec_data;
break;
case CHD_CODEC_CD_FLAC:
codec = &chd->cdfl_codec_data;
break;
}
if (codec==NULL)
return CHDERR_CODEC_ERROR;
err = (*chd->codecintf[rawmap[0]]->decompress)(codec, chd->compressed, blocklen, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE)
return err;
#ifdef VERIFY_BLOCK_CRC
if (crc16(dest, chd->header.hunkbytes) != blockcrc)
return CHDERR_DECOMPRESSION_ERROR;
#endif
return CHDERR_NONE;
case COMPRESSION_NONE:
if (core_fseek(chd->file, blockoffs, SEEK_SET) != 0)
return CHDERR_READ_ERROR;
if (core_fread(chd->file, dest, chd->header.hunkbytes) != chd->header.hunkbytes)
return CHDERR_READ_ERROR;
#ifdef VERIFY_BLOCK_CRC
if (crc16(dest, chd->header.hunkbytes) != blockcrc)
return CHDERR_DECOMPRESSION_ERROR;
#endif
return CHDERR_NONE;
case COMPRESSION_SELF:
return hunk_read_into_memory(chd, blockoffs, dest);
case COMPRESSION_PARENT:
#if 0
/* TODO */
if (m_parent_missing)
return CHDERR_REQUIRES_PARENT;
return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
#endif
return CHDERR_DECOMPRESSION_ERROR;
}
return CHDERR_NONE;
}
/* We should not reach this code */
return CHDERR_DECOMPRESSION_ERROR;
}
/***************************************************************************
INTERNAL MAP ACCESS
***************************************************************************/
@ -2324,9 +2309,6 @@ cleanup:
return err;
}
/***************************************************************************
INTERNAL METADATA ACCESS
***************************************************************************/
@ -2376,8 +2358,6 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai
return CHDERR_METADATA_NOT_FOUND;
}
/***************************************************************************
ZLIB COMPRESSION CODEC
***************************************************************************/
@ -2414,7 +2394,6 @@ static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
return err;
}
/*-------------------------------------------------
zlib_codec_free - free data for the ZLIB
codec
@ -2440,7 +2419,6 @@ static void zlib_codec_free(void *codec)
}
}
/*-------------------------------------------------
zlib_codec_decompress - decomrpess data using
the ZLIB codec
@ -2471,7 +2449,6 @@ static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t
return CHDERR_NONE;
}
/*-------------------------------------------------
zlib_fast_alloc - fast malloc for ZLIB, which
allocates and frees memory frequently
@ -2516,7 +2493,6 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
return ptr + 1;
}
/*-------------------------------------------------
zlib_fast_free - fast free for ZLIB, which
allocates and frees memory frequently

View File

@ -1,7 +1,6 @@
/* license:BSD-3-Clause
* copyright-holders:Aaron Giles
*/
/***************************************************************************
***************************************************************************
flac.c
@ -59,7 +58,6 @@ void flac_decoder_free(flac_decoder* decoder)
FLAC__stream_decoder_delete(decoder->decoder);
}
/*-------------------------------------------------
* reset - reset state with the original
* parameters
@ -82,8 +80,6 @@ static int flac_decoder_internal_reset(flac_decoder* decoder)
return FLAC__stream_decoder_process_until_end_of_metadata(decoder->decoder);
}
/*-------------------------------------------------
* reset - reset state with new memory parameters
* and a custom-generated header
@ -97,18 +93,17 @@ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_
{
0x66, 0x4C, 0x61, 0x43, /* +00: 'fLaC' stream header */
0x80, /* +04: metadata block type 0 (STREAMINFO), */
/* flagged as last block */
/* flagged as last block */
0x00, 0x00, 0x22, /* +05: metadata block length = 0x22 */
0x00, 0x00, /* +08: minimum block size */
0x00, 0x00, /* +0A: maximum block size */
0x00, 0x00, 0x00, /* +0C: minimum frame size (0 == unknown) */
0x00, 0x00, 0x00, /* +0F: maximum frame size (0 == unknown) */
0x0A, 0xC4, 0x42, 0xF0, 0x00, 0x00, 0x00, 0x00, /* +12: sample rate (0x0ac44 == 44100), */
/* numchannels (2), sample bits (16), */
/* samples in stream (0 == unknown) */
/* numchannels (2), sample bits (16), */
/* samples in stream (0 == unknown) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* +1A: MD5 signature (0 == none) */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* */
/* +2A: start of stream data */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* +2A: start of stream data */
};
memcpy(decoder->custom_header, s_header_template, sizeof(s_header_template));
decoder->custom_header[0x08] = decoder->custom_header[0x0a] = block_size >> 8;
@ -125,7 +120,6 @@ int flac_decoder_reset(flac_decoder* decoder, uint32_t sample_rate, uint8_t num_
return flac_decoder_internal_reset(decoder);
}
/*-------------------------------------------------
* decode_interleaved - decode to an interleaved
* sound stream
@ -148,10 +142,8 @@ int flac_decoder_decode_interleaved(flac_decoder* decoder, int16_t *samples, uin
return 1;
}
#if 0
/*
*-------------------------------------------------
/*-------------------------------------------------
* decode - decode to an multiple independent
* data streams
*-------------------------------------------------
@ -200,7 +192,6 @@ uint32_t flac_decoder_finish(flac_decoder* decoder)
return position;
}
/*-------------------------------------------------
* read_callback - handle reads from the input
* stream
@ -242,7 +233,6 @@ FLAC__StreamDecoderReadStatus flac_decoder_read_callback(void* client_data, FLAC
return (*bytes < expected) ? FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM : FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
/*-------------------------------------------------
* metadata_callback - handle STREAMINFO metadata
*-------------------------------------------------
@ -262,7 +252,6 @@ void flac_decoder_metadata_callback_static(const FLAC__StreamDecoder *decoder, c
fldecoder->channels = metadata->data.stream_info.channels;
}
/*-------------------------------------------------
* tell_callback - handle requests to find out
* where in the input stream we are
@ -275,7 +264,6 @@ FLAC__StreamDecoderTellStatus flac_decoder_tell_callback_static(const FLAC__Stre
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
/*-------------------------------------------------
* write_callback - handle writes to the output
* stream

View File

@ -1,6 +1,6 @@
/* license:BSD-3-Clause
* copyright-holders:Aaron Giles
***************************************************************************
****************************************************************************
huffman.c
@ -111,10 +111,9 @@
#define MAKE_LOOKUP(code,bits) (((code) << 5) | ((bits) & 0x1f))
/***************************************************************************
* IMPLEMENTATION
* **************************************************************************
***************************************************************************
*/
/*-------------------------------------------------
@ -313,7 +312,6 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder,
return bitstream_overflow(bitbuf) ? HUFFERR_INPUT_BUFFER_TOO_SMALL : HUFFERR_NONE;
}
/*-------------------------------------------------
* compute_tree_from_histo - common backend for
* computing a tree based on the data histogram
@ -355,8 +353,6 @@ enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decod
return huffman_assign_canonical_codes(decoder);
}
/***************************************************************************
* INTERNAL FUNCTIONS
***************************************************************************
@ -379,7 +375,6 @@ static int huffman_tree_node_compare(const void *item1, const void *item2)
return (int)node1->bits - (int)node2->bits;
}
/*-------------------------------------------------
* build_tree - build a huffman tree based on the
* data distribution
@ -418,10 +413,10 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint
for (i = 0; i < listitems; i++)
fprintf(stderr, "weight: %d code: %d\n",
list[i]->m_weight, list[i]->m_bits);
*/ sort the list by weight, largest weight first */
}
#endif
/* sort the list by weight, largest weight first */
qsort(&list[0], listitems, sizeof(list[0]), huffman_tree_node_compare);
#if 0
@ -490,7 +485,6 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint
return maxbits;
}
/*-------------------------------------------------
* assign_canonical_codes - assign canonical codes
* to all the nodes based on the number of bits
@ -533,7 +527,6 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode
return HUFFERR_NONE;
}
/*-------------------------------------------------
* build_lookup_table - build a lookup table for
* fast decoding

View File

@ -1,6 +1,6 @@
/* license:BSD-3-Clause
* copyright-holders:Aaron Giles
***************************************************************************
***************************************************************************
bitstream.h

View File

@ -1,6 +1,6 @@
/* license:BSD-3-Clause */
/* copyright-holders:Aaron Giles */
/***************************************************************************
/* license:BSD-3-Clause
* copyright-holders:Aaron Giles
***************************************************************************
cdrom.h