Skip to content

Commit

Permalink
backported support for loading uncompressed chd files
Browse files Browse the repository at this point in the history
handle errors from both map_read as well as decompress_v5_map
  • Loading branch information
inolen committed Aug 29, 2018
1 parent 6726f52 commit e1acac6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 23 deletions.
58 changes: 35 additions & 23 deletions src/chd.c
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,6 @@ chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple
CODEC INTERFACES
***************************************************************************/


static const codec_interface codec_interfaces[] =
{
/* "none" or no compression */
Expand Down Expand Up @@ -1081,18 +1080,28 @@ uint16_t crc16(const void *data, uint32_t length)
return crc;
}

/*-------------------------------------------------
compressed - test if CHD file is compressed
+-------------------------------------------------*/

static inline int compressed(chd_header* header) {
return header->compression[0] != CHD_CODEC_NONE;
}

/*-------------------------------------------------
decompress_v5_map - decompress the v5 map
-------------------------------------------------*/

static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
{
if (header->mapoffset == 0)
int rawmapsize = map_size_v5(header);

if (!compressed(header))
{
#if 0
memset(header->rawmap, 0xff,map_size_v5(header));
#endif
return CHDERR_READ_ERROR;
header->rawmap = (uint8_t*)malloc(rawmapsize);
core_fseek(chd->file, header->mapoffset, SEEK_SET);
core_fread(chd->file, header->rawmap, rawmapsize);
return CHDERR_NONE;
}

/* read the reader */
Expand All @@ -1111,7 +1120,7 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
core_fread(chd->file, compressed, mapbytes);
struct bitstream* bitbuf = create_bitstream(compressed, sizeof(uint8_t) * mapbytes);
header->rawmap = (uint8_t*)malloc(sizeof(uint8_t) * map_size_v5(header));
header->rawmap = (uint8_t*)malloc(rawmapsize);

/* first decode the compression types */
struct huffman_decoder* decoder = create_huffman_decoder(16, 8);
Expand Down Expand Up @@ -1300,13 +1309,14 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **
if (newchd->header.version < 5)
{
err = map_read(newchd);
if (err != CHDERR_NONE)
EARLY_EXIT(err);
}
else
{
err = decompress_v5_map(newchd, &(newchd->header));
}
if (err != CHDERR_NONE)
EARLY_EXIT(err);


/* allocate and init the hunk cache */
newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
Expand Down Expand Up @@ -1910,7 +1920,7 @@ static chd_error header_read(chd_file *chd, chd_header *header)
memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);

/* determine properties of map entries */
header->mapentrybytes = 12; /* TODO compressed() ? 12 : 4; */
header->mapentrybytes = compressed(header) ? 12 : 4;

/* hack */
header->totalhunks = header->hunkcount;
Expand Down Expand Up @@ -2039,22 +2049,24 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des
uint16_t blockcrc;
uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];

#if 0
/* uncompressed case - TODO */
if (!compressed())
/* uncompressed case */
if (!compressed(&chd->header))
{
blockoffs = uint64_t(be_read(rawmap, 4)) * uint64_t(m_hunkbytes);
if (blockoffs != 0)
file_read(blockoffs, dest, m_hunkbytes);
blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
if (blockoffs != 0) {
core_fseek(chd->file, blockoffs, SEEK_SET);
core_fread(chd->file, dest, chd->header.hunkbytes);
/* TODO
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;
throw CHDERR_REQUIRES_PARENT; */
} else if (chd->parent) {
err = hunk_read_into_memory(chd->parent, hunknum, dest);
if (err != CHDERR_NONE)
return err;
} else {
memset(dest, 0, chd->header.hunkbytes);
}
}
#endif

/* compressed case */
blocklen = get_bigendian_uint24(&rawmap[1]);
Expand Down
1 change: 1 addition & 0 deletions src/chd.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ extern "C" {
#define CHDCOMPRESSION_ZLIB_PLUS 2
#define CHDCOMPRESSION_AV 3

#define CHD_CODEC_NONE 0
#define CHD_CODEC_ZLIB CHD_MAKE_TAG('z','l','i','b')
/* general codecs with CD frontend */
#define CHD_CODEC_CD_ZLIB CHD_MAKE_TAG('c','d','z','l')
Expand Down

0 comments on commit e1acac6

Please sign in to comment.