(libchdr) More resyncs

This commit is contained in:
twinaphex 2020-07-01 19:21:40 +02:00
parent 436f161cc3
commit 9e9fb47c05
1 changed files with 30 additions and 25 deletions

View File

@ -95,18 +95,22 @@
#define NO_MATCH (~0) #define NO_MATCH (~0)
#define MAP_ENTRY_TYPE_INVALID 0x0000 /* invalid type */
#define MAP_ENTRY_TYPE_COMPRESSED 0x0001 /* standard compression */
#define MAP_ENTRY_TYPE_UNCOMPRESSED 0x0002 /* uncompressed data */
#define MAP_ENTRY_TYPE_MINI 0x0003 /* mini: use offset as raw data */
#define MAP_ENTRY_TYPE_SELF_HUNK 0x0004 /* same as another hunk in this file */
#define MAP_ENTRY_TYPE_PARENT_HUNK 0x0005 /* same as a hunk in the parent file */
#define MAP_ENTRY_TYPE_2ND_COMPRESSED 0x0006 /* compressed with secondary algorithm (usually FLAC CDDA) */
#ifdef WANT_RAW_DATA_SECTOR #ifdef WANT_RAW_DATA_SECTOR
const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
#endif #endif
/* V3-V4 entry types */
enum
{
V34_MAP_ENTRY_TYPE_INVALID = 0, /* invalid type */
V34_MAP_ENTRY_TYPE_COMPRESSED = 1, /* standard compression */
V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2, /* uncompressed data */
V34_MAP_ENTRY_TYPE_MINI = 3, /* mini: use offset as raw data */
V34_MAP_ENTRY_TYPE_SELF_HUNK = 4, /* same as another hunk in this file */
V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5, /* same as a hunk in the parent file */
V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6 /* compressed with secondary algorithm (usually FLAC CDDA) */
};
/* V5 compression types */ /* V5 compression types */
enum enum
{ {
@ -147,8 +151,6 @@ enum
MACROS MACROS
***************************************************************************/ ***************************************************************************/
#define SET_ERROR_AND_CLEANUP(err) do { last_error = (err); goto cleanup; } while (0)
#define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0) #define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0)
/*************************************************************************** /***************************************************************************
@ -745,7 +747,7 @@ static INLINE void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 h
entry->offset = get_bigendian_uint64(&base[0]); entry->offset = get_bigendian_uint64(&base[0]);
entry->crc = 0; entry->crc = 0;
entry->length = entry->offset >> 44; entry->length = entry->offset >> 44;
entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? MAP_ENTRY_TYPE_UNCOMPRESSED : MAP_ENTRY_TYPE_COMPRESSED); entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
#ifdef __MWERKS__ #ifdef __MWERKS__
entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL; entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
#else #else
@ -1597,17 +1599,20 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
{ {
map_entry *entry = &chd->map[hunknum]; map_entry *entry = &chd->map[hunknum];
UINT32 bytes; UINT32 bytes;
UINT8* compressed_bytes;
/* switch off the entry type */ /* switch off the entry type */
switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK) switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
{ {
/* compressed data */ /* compressed data */
case MAP_ENTRY_TYPE_COMPRESSED: case V34_MAP_ENTRY_TYPE_COMPRESSED:
{ {
/* read it into the decompression buffer */
void *codec; void *codec;
UINT8 *bytes = hunk_read_compressed(chd, entry->offset, compressed_bytes = hunk_read_compressed(chd, entry->offset,
entry->length); entry->length);
if (bytes == NULL) if (compressed_bytes == NULL)
return CHDERR_READ_ERROR; return CHDERR_READ_ERROR;
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
@ -1615,7 +1620,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
err = CHDERR_NONE; err = CHDERR_NONE;
codec = &chd->zlib_codec_data; codec = &chd->zlib_codec_data;
if (chd->codecintf[0]->decompress != NULL) if (chd->codecintf[0]->decompress != NULL)
err = (*chd->codecintf[0]->decompress)(codec, chd->compressed, entry->length, dest, chd->header.hunkbytes); err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE) if (err != CHDERR_NONE)
return err; return err;
#endif #endif
@ -1623,21 +1628,21 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
break; break;
/* uncompressed data */ /* uncompressed data */
case MAP_ENTRY_TYPE_UNCOMPRESSED: case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest); err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
if (err != CHDERR_NONE) if (err != CHDERR_NONE)
return err; return err;
break; break;
/* mini-compressed data */ /* mini-compressed data */
case MAP_ENTRY_TYPE_MINI: case V34_MAP_ENTRY_TYPE_MINI:
put_bigendian_uint64(&dest[0], entry->offset); put_bigendian_uint64(&dest[0], entry->offset);
for (bytes = 8; bytes < chd->header.hunkbytes; bytes++) for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
dest[bytes] = dest[bytes - 8]; dest[bytes] = dest[bytes - 8];
break; break;
/* self-referenced data */ /* self-referenced data */
case MAP_ENTRY_TYPE_SELF_HUNK: case V34_MAP_ENTRY_TYPE_SELF_HUNK:
#ifdef NEED_CACHE_HUNK #ifdef NEED_CACHE_HUNK
if (chd->cachehunk == entry->offset && dest == chd->cache) if (chd->cachehunk == entry->offset && dest == chd->cache)
break; break;
@ -1645,7 +1650,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
return hunk_read_into_memory(chd, (UINT32)entry->offset, dest); return hunk_read_into_memory(chd, (UINT32)entry->offset, dest);
/* parent-referenced data */ /* parent-referenced data */
case MAP_ENTRY_TYPE_PARENT_HUNK: case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
err = hunk_read_into_memory(chd->parent, (UINT32)entry->offset, dest); err = hunk_read_into_memory(chd->parent, (UINT32)entry->offset, dest);
if (err != CHDERR_NONE) if (err != CHDERR_NONE)
return err; return err;
@ -1663,7 +1668,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
uint16_t blockcrc; uint16_t blockcrc;
#endif #endif
uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum]; uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
UINT8 *bytes; UINT8 *compressed_bytes;
#if 0 #if 0
/* uncompressed case - TODO */ /* uncompressed case - TODO */
@ -1694,8 +1699,8 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
case COMPRESSION_TYPE_1: case COMPRESSION_TYPE_1:
case COMPRESSION_TYPE_2: case COMPRESSION_TYPE_2:
case COMPRESSION_TYPE_3: case COMPRESSION_TYPE_3:
bytes = hunk_read_compressed(chd, blockoffs, blocklen); compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
if (bytes == NULL) if (compressed_bytes == NULL)
return CHDERR_READ_ERROR; return CHDERR_READ_ERROR;
if (!chd->codecintf[rawmap[0]]) if (!chd->codecintf[rawmap[0]])
return CHDERR_UNSUPPORTED_FORMAT; return CHDERR_UNSUPPORTED_FORMAT;
@ -1721,7 +1726,7 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
} }
if (codec==NULL) if (codec==NULL)
return CHDERR_CODEC_ERROR; return CHDERR_CODEC_ERROR;
err = (*chd->codecintf[rawmap[0]]->decompress)(codec, chd->compressed, blocklen, dest, chd->header.hunkbytes); err = (*chd->codecintf[rawmap[0]]->decompress)(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
if (err != CHDERR_NONE) if (err != CHDERR_NONE)
return err; return err;
#ifdef VERIFY_BLOCK_CRC #ifdef VERIFY_BLOCK_CRC
@ -1824,8 +1829,8 @@ static chd_error map_read(chd_file *chd)
/* track the maximum offset */ /* track the maximum offset */
for (j = 0; j < entries; j++) for (j = 0; j < entries; j++)
if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == MAP_ENTRY_TYPE_COMPRESSED || if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
(chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == MAP_ENTRY_TYPE_UNCOMPRESSED) (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length); maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
} }