mirror of
https://github.com/holub/mame
synced 2025-04-22 00:11:58 +03:00
chd.cpp, chdcodec.cpp, flac.cpp: Use multibyte.h functions
* multibyte.h: Add functions for reading and writing 48-bit values
This commit is contained in:
parent
5077dcbe1c
commit
94ff3857e2
@ -16,6 +16,7 @@
|
||||
#include "coretmpl.h"
|
||||
#include "flac.h"
|
||||
#include "hashing.h"
|
||||
#include "multibyte.h"
|
||||
|
||||
#include "eminline.h"
|
||||
|
||||
@ -128,36 +129,6 @@ struct chd_file::metadata_hash
|
||||
// INLINE FUNCTIONS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// be_read - extract a big-endian number from
|
||||
// a byte buffer
|
||||
//-------------------------------------------------
|
||||
|
||||
inline uint64_t chd_file::be_read(const uint8_t *base, int numbytes) const
|
||||
{
|
||||
uint64_t result = 0;
|
||||
while (numbytes--)
|
||||
result = (result << 8) | *base++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// be_write - write a big-endian number to a byte
|
||||
// buffer
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void chd_file::be_write(uint8_t *base, uint64_t value, int numbytes)
|
||||
{
|
||||
base += numbytes;
|
||||
while (numbytes--)
|
||||
{
|
||||
*--base = value;
|
||||
value >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// be_read_sha1 - fetch a sha1_t from a data
|
||||
// stream in bigendian order
|
||||
@ -471,7 +442,7 @@ std::error_condition chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compr
|
||||
{
|
||||
case V34_MAP_ENTRY_TYPE_COMPRESSED:
|
||||
compressor = CHD_CODEC_ZLIB;
|
||||
compbytes = be_read(&rawmap[12], 2) + (rawmap[14] << 16);
|
||||
compbytes = get_u16be(&rawmap[12]) + (rawmap[14] << 16);
|
||||
break;
|
||||
|
||||
case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
|
||||
@ -503,7 +474,7 @@ std::error_condition chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compr
|
||||
// uncompressed case
|
||||
if (!compressed())
|
||||
{
|
||||
if (be_read(&rawmap[0], 4) == 0)
|
||||
if (get_u32be(&rawmap[0]) == 0)
|
||||
{
|
||||
compressor = CHD_CODEC_PARENT;
|
||||
compbytes = 0;
|
||||
@ -524,7 +495,7 @@ std::error_condition chd_file::hunk_info(uint32_t hunknum, chd_codec_type &compr
|
||||
case COMPRESSION_TYPE_2:
|
||||
case COMPRESSION_TYPE_3:
|
||||
compressor = m_compression[rawmap[0]];
|
||||
compbytes = be_read(&rawmap[1], 3);
|
||||
compbytes = get_u24be(&rawmap[1]);
|
||||
break;
|
||||
|
||||
case COMPRESSION_NONE:
|
||||
@ -917,12 +888,12 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
||||
case 3:
|
||||
case 4:
|
||||
rawmap = &m_rawmap[16 * hunknum];
|
||||
blockoffs = be_read(&rawmap[0], 8);
|
||||
blockcrc = be_read(&rawmap[8], 4);
|
||||
blockoffs = get_u64be(&rawmap[0]);
|
||||
blockcrc = get_u32be(&rawmap[8]);
|
||||
switch (rawmap[15] & V34_MAP_ENTRY_FLAG_TYPE_MASK)
|
||||
{
|
||||
case V34_MAP_ENTRY_TYPE_COMPRESSED:
|
||||
blocklen = be_read(&rawmap[12], 2) + (rawmap[14] << 16);
|
||||
blocklen = get_u16be(&rawmap[12]) + (rawmap[14] << 16);
|
||||
file_read(blockoffs, &m_compressed[0], blocklen);
|
||||
m_decompressor[0]->decompress(&m_compressed[0], blocklen, dest, m_hunkbytes);
|
||||
if (!(rawmap[15] & V34_MAP_ENTRY_FLAG_NO_CRC) && dest != nullptr && util::crc32_creator::simple(dest, m_hunkbytes) != blockcrc)
|
||||
@ -936,7 +907,7 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
||||
return std::error_condition();
|
||||
|
||||
case V34_MAP_ENTRY_TYPE_MINI:
|
||||
be_write(dest, blockoffs, 8);
|
||||
put_u64be(dest, blockoffs);
|
||||
for (uint32_t bytes = 8; bytes < m_hunkbytes; bytes++)
|
||||
dest[bytes] = dest[bytes - 8];
|
||||
if (!(rawmap[15] & V34_MAP_ENTRY_FLAG_NO_CRC) && util::crc32_creator::simple(dest, m_hunkbytes) != blockcrc)
|
||||
@ -960,7 +931,7 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
||||
// uncompressed case
|
||||
if (!compressed())
|
||||
{
|
||||
blockoffs = uint64_t(be_read(rawmap, 4)) * uint64_t(m_hunkbytes);
|
||||
blockoffs = mulu_32x32(get_u32be(rawmap), m_hunkbytes);
|
||||
if (blockoffs != 0)
|
||||
file_read(blockoffs, dest, m_hunkbytes);
|
||||
else if (m_parent_missing)
|
||||
@ -973,9 +944,9 @@ std::error_condition chd_file::read_hunk(uint32_t hunknum, void *buffer)
|
||||
}
|
||||
|
||||
// compressed case
|
||||
blocklen = be_read(&rawmap[1], 3);
|
||||
blockoffs = be_read(&rawmap[4], 6);
|
||||
blockcrc = be_read(&rawmap[10], 2);
|
||||
blocklen = get_u24be(&rawmap[1]);
|
||||
blockoffs = get_u48be(&rawmap[4]);
|
||||
blockcrc = get_u16be(&rawmap[10]);
|
||||
switch (rawmap[0])
|
||||
{
|
||||
case COMPRESSION_TYPE_0:
|
||||
@ -1059,7 +1030,7 @@ std::error_condition chd_file::write_hunk(uint32_t hunknum, const void *buffer)
|
||||
|
||||
// see if we have allocated the space on disk for this hunk
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 4];
|
||||
uint32_t rawentry = be_read(rawmap, 4);
|
||||
uint32_t rawentry = get_u32be(rawmap);
|
||||
|
||||
// if not, allocate one now
|
||||
if (rawentry == 0)
|
||||
@ -1082,7 +1053,7 @@ std::error_condition chd_file::write_hunk(uint32_t hunknum, const void *buffer)
|
||||
rawentry = file_append(buffer, m_hunkbytes, m_hunkbytes) / m_hunkbytes;
|
||||
|
||||
// write the map entry back
|
||||
be_write(rawmap, rawentry, 4);
|
||||
put_u32be(rawmap, rawentry);
|
||||
file_write(m_mapoffset + hunknum * 4, rawmap, 4);
|
||||
|
||||
// update the cached hunk if we just wrote it
|
||||
@ -1443,7 +1414,7 @@ std::error_condition chd_file::write_metadata(chd_metadata_tag metatag, uint32_t
|
||||
if (inputlen != metaentry.length)
|
||||
{
|
||||
uint8_t length[3];
|
||||
be_write(length, inputlen, 3);
|
||||
put_u24be(length, inputlen);
|
||||
file_write(metaentry.offset + 5, length, sizeof(length));
|
||||
}
|
||||
|
||||
@ -1461,10 +1432,10 @@ std::error_condition chd_file::write_metadata(chd_metadata_tag metatag, uint32_t
|
||||
{
|
||||
// now build us a new entry
|
||||
uint8_t raw_meta_header[METADATA_HEADER_SIZE];
|
||||
be_write(&raw_meta_header[0], metatag, 4);
|
||||
put_u32be(&raw_meta_header[0], metatag);
|
||||
raw_meta_header[4] = flags;
|
||||
be_write(&raw_meta_header[5], (inputlen & 0x00ffffff) | (flags << 24), 3);
|
||||
be_write(&raw_meta_header[8], 0, 8);
|
||||
put_u24be(&raw_meta_header[5], inputlen & 0x00ffffff);
|
||||
put_u64be(&raw_meta_header[8], 0);
|
||||
|
||||
// append the new header, then the data
|
||||
uint64_t offset = file_append(raw_meta_header, sizeof(raw_meta_header));
|
||||
@ -1603,7 +1574,7 @@ util::sha1_t chd_file::compute_overall_sha1(util::sha1_t rawsha1)
|
||||
|
||||
// create an entry for this metadata and add it
|
||||
metadata_hash hashentry;
|
||||
be_write(hashentry.tag, metaentry.metatag, 4);
|
||||
put_u32be(hashentry.tag, metaentry.metatag);
|
||||
hashentry.sha1 = util::sha1_creator::simple(&filedata[0], metaentry.length);
|
||||
hasharray.push_back(hashentry);
|
||||
}
|
||||
@ -1768,22 +1739,22 @@ uint32_t chd_file::guess_unitbytes()
|
||||
void chd_file::parse_v3_header(uint8_t *rawheader, util::sha1_t &parentsha1)
|
||||
{
|
||||
// verify header length
|
||||
if (be_read(&rawheader[8], 4) != V3_HEADER_SIZE)
|
||||
if (get_u32be(&rawheader[8]) != V3_HEADER_SIZE)
|
||||
throw std::error_condition(error::INVALID_FILE);
|
||||
|
||||
// extract core info
|
||||
m_logicalbytes = be_read(&rawheader[28], 8);
|
||||
m_logicalbytes = get_u64be(&rawheader[28]);
|
||||
m_mapoffset = 120;
|
||||
m_metaoffset = be_read(&rawheader[36], 8);
|
||||
m_hunkbytes = be_read(&rawheader[76], 4);
|
||||
m_hunkcount = be_read(&rawheader[24], 4);
|
||||
m_metaoffset = get_u64be(&rawheader[36]);
|
||||
m_hunkbytes = get_u32be(&rawheader[76]);
|
||||
m_hunkcount = get_u32be(&rawheader[24]);
|
||||
|
||||
// extract parent SHA-1
|
||||
uint32_t flags = be_read(&rawheader[16], 4);
|
||||
uint32_t flags = get_u32be(&rawheader[16]);
|
||||
m_allow_writes = (flags & 2) == 0;
|
||||
|
||||
// determine compression
|
||||
switch (be_read(&rawheader[20], 4))
|
||||
switch (get_u32be(&rawheader[20]))
|
||||
{
|
||||
case 0: m_compression[0] = CHD_CODEC_NONE; break;
|
||||
case 1: m_compression[0] = CHD_CODEC_ZLIB; break;
|
||||
@ -1831,22 +1802,22 @@ void chd_file::parse_v3_header(uint8_t *rawheader, util::sha1_t &parentsha1)
|
||||
void chd_file::parse_v4_header(uint8_t *rawheader, util::sha1_t &parentsha1)
|
||||
{
|
||||
// verify header length
|
||||
if (be_read(&rawheader[8], 4) != V4_HEADER_SIZE)
|
||||
if (get_u32be(&rawheader[8]) != V4_HEADER_SIZE)
|
||||
throw std::error_condition(error::INVALID_FILE);
|
||||
|
||||
// extract core info
|
||||
m_logicalbytes = be_read(&rawheader[28], 8);
|
||||
m_logicalbytes = get_u64be(&rawheader[28]);
|
||||
m_mapoffset = 108;
|
||||
m_metaoffset = be_read(&rawheader[36], 8);
|
||||
m_hunkbytes = be_read(&rawheader[44], 4);
|
||||
m_hunkcount = be_read(&rawheader[24], 4);
|
||||
m_metaoffset = get_u64be(&rawheader[36]);
|
||||
m_hunkbytes = get_u32be(&rawheader[44]);
|
||||
m_hunkcount = get_u32be(&rawheader[24]);
|
||||
|
||||
// extract parent SHA-1
|
||||
uint32_t flags = be_read(&rawheader[16], 4);
|
||||
uint32_t flags = get_u32be(&rawheader[16]);
|
||||
m_allow_writes = (flags & 2) == 0;
|
||||
|
||||
// determine compression
|
||||
switch (be_read(&rawheader[20], 4))
|
||||
switch (get_u32be(&rawheader[20]))
|
||||
{
|
||||
case 0: m_compression[0] = CHD_CODEC_NONE; break;
|
||||
case 1: m_compression[0] = CHD_CODEC_ZLIB; break;
|
||||
@ -1891,23 +1862,23 @@ void chd_file::parse_v4_header(uint8_t *rawheader, util::sha1_t &parentsha1)
|
||||
void chd_file::parse_v5_header(uint8_t *rawheader, util::sha1_t &parentsha1)
|
||||
{
|
||||
// verify header length
|
||||
if (be_read(&rawheader[8], 4) != V5_HEADER_SIZE)
|
||||
if (get_u32be(&rawheader[8]) != V5_HEADER_SIZE)
|
||||
throw std::error_condition(error::INVALID_FILE);
|
||||
|
||||
// extract core info
|
||||
m_logicalbytes = be_read(&rawheader[32], 8);
|
||||
m_mapoffset = be_read(&rawheader[40], 8);
|
||||
m_metaoffset = be_read(&rawheader[48], 8);
|
||||
m_hunkbytes = be_read(&rawheader[56], 4);
|
||||
m_logicalbytes = get_u64be(&rawheader[32]);
|
||||
m_mapoffset = get_u64be(&rawheader[40]);
|
||||
m_metaoffset = get_u64be(&rawheader[48]);
|
||||
m_hunkbytes = get_u32be(&rawheader[56]);
|
||||
m_hunkcount = (m_logicalbytes + m_hunkbytes - 1) / m_hunkbytes;
|
||||
m_unitbytes = be_read(&rawheader[60], 4);
|
||||
m_unitbytes = get_u32be(&rawheader[60]);
|
||||
m_unitcount = (m_logicalbytes + m_unitbytes - 1) / m_unitbytes;
|
||||
|
||||
// determine compression
|
||||
m_compression[0] = be_read(&rawheader[16], 4);
|
||||
m_compression[1] = be_read(&rawheader[20], 4);
|
||||
m_compression[2] = be_read(&rawheader[24], 4);
|
||||
m_compression[3] = be_read(&rawheader[28], 4);
|
||||
m_compression[0] = get_u32be(&rawheader[16]);
|
||||
m_compression[1] = get_u32be(&rawheader[20]);
|
||||
m_compression[2] = get_u32be(&rawheader[24]);
|
||||
m_compression[3] = get_u32be(&rawheader[28]);
|
||||
|
||||
m_allow_writes = !compressed();
|
||||
|
||||
@ -1961,14 +1932,14 @@ std::error_condition chd_file::compress_v5_map()
|
||||
uint32_t max_complen = 0;
|
||||
uint8_t lastcomp = 0;
|
||||
int count = 0;
|
||||
for (int hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
for (uint32_t hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
{
|
||||
uint8_t curcomp = m_rawmap[hunknum * 12 + 0];
|
||||
|
||||
// promote self block references to more compact forms
|
||||
if (curcomp == COMPRESSION_SELF)
|
||||
{
|
||||
uint32_t refhunk = be_read(&m_rawmap[hunknum * 12 + 4], 6);
|
||||
uint32_t refhunk = get_u48be(&m_rawmap[hunknum * 12 + 4]);
|
||||
if (refhunk == last_self)
|
||||
curcomp = COMPRESSION_SELF_0;
|
||||
else if (refhunk == last_self + 1)
|
||||
@ -1981,8 +1952,8 @@ std::error_condition chd_file::compress_v5_map()
|
||||
// promote parent block references to more compact forms
|
||||
else if (curcomp == COMPRESSION_PARENT)
|
||||
{
|
||||
uint32_t refunit = be_read(&m_rawmap[hunknum * 12 + 4], 6);
|
||||
if (refunit == (uint64_t(hunknum) * uint64_t(m_hunkbytes)) / m_unitbytes)
|
||||
uint32_t refunit = get_u48be(&m_rawmap[hunknum * 12 + 4]);
|
||||
if (refunit == mulu_32x32(hunknum, m_hunkbytes) / m_unitbytes)
|
||||
curcomp = COMPRESSION_PARENT_SELF;
|
||||
else if (refunit == last_parent)
|
||||
curcomp = COMPRESSION_PARENT_0;
|
||||
@ -1995,7 +1966,7 @@ std::error_condition chd_file::compress_v5_map()
|
||||
|
||||
// track maximum compressed length
|
||||
else //if (curcomp >= COMPRESSION_TYPE_0 && curcomp <= COMPRESSION_TYPE_3)
|
||||
max_complen = std::max(max_complen, uint32_t(be_read(&m_rawmap[hunknum * 12 + 1], 3)));
|
||||
max_complen = std::max<uint32_t>(max_complen, get_u24be(&m_rawmap[hunknum * 12 + 1]));
|
||||
|
||||
// track repeats
|
||||
if (curcomp == lastcomp)
|
||||
@ -2053,12 +2024,12 @@ std::error_condition chd_file::compress_v5_map()
|
||||
count = 0;
|
||||
uint8_t *src = &compression_rle[0];
|
||||
uint64_t firstoffs = 0;
|
||||
for (int hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
for (uint32_t hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
{
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
uint32_t length = be_read(&rawmap[1], 3);
|
||||
uint64_t offset = be_read(&rawmap[4], 6);
|
||||
uint16_t crc = be_read(&rawmap[10], 2);
|
||||
uint32_t length = get_u24be(&rawmap[1]);
|
||||
uint64_t offset = get_u48be(&rawmap[4]);
|
||||
uint16_t crc = get_u16be(&rawmap[10]);
|
||||
|
||||
// if no count remaining, fetch the next entry
|
||||
if (count == 0)
|
||||
@ -2116,9 +2087,9 @@ std::error_condition chd_file::compress_v5_map()
|
||||
// write the map header
|
||||
uint32_t complen = bitbuf.flush();
|
||||
assert(!bitbuf.overflow());
|
||||
be_write(&compressed[0], complen, 4);
|
||||
be_write(&compressed[4], firstoffs, 6);
|
||||
be_write(&compressed[10], mapcrc, 2);
|
||||
put_u32be(&compressed[0], complen);
|
||||
put_u48be(&compressed[4], firstoffs);
|
||||
put_u16be(&compressed[10], mapcrc);
|
||||
compressed[12] = lengthbits;
|
||||
compressed[13] = selfbits;
|
||||
compressed[14] = parentbits;
|
||||
@ -2129,7 +2100,7 @@ std::error_condition chd_file::compress_v5_map()
|
||||
|
||||
// then write the map offset
|
||||
uint8_t rawbuf[sizeof(uint64_t)];
|
||||
be_write(rawbuf, m_mapoffset, 8);
|
||||
put_u64be(rawbuf, m_mapoffset);
|
||||
file_write(m_mapoffset_offset, rawbuf, sizeof(rawbuf));
|
||||
return std::error_condition();
|
||||
}
|
||||
@ -2162,9 +2133,9 @@ void chd_file::decompress_v5_map()
|
||||
// read the reader
|
||||
uint8_t rawbuf[16];
|
||||
file_read(m_mapoffset, rawbuf, sizeof(rawbuf));
|
||||
uint32_t const mapbytes = be_read(&rawbuf[0], 4);
|
||||
uint64_t const firstoffs = be_read(&rawbuf[4], 6);
|
||||
util::crc16_t const mapcrc = be_read(&rawbuf[10], 2);
|
||||
uint32_t const mapbytes = get_u32be(&rawbuf[0]);
|
||||
uint64_t const firstoffs = get_u48be(&rawbuf[4]);
|
||||
util::crc16_t const mapcrc = get_u16be(&rawbuf[10]);
|
||||
uint8_t const lengthbits = rawbuf[12];
|
||||
uint8_t const selfbits = rawbuf[13];
|
||||
uint8_t const parentbits = rawbuf[14];
|
||||
@ -2181,7 +2152,7 @@ void chd_file::decompress_v5_map()
|
||||
throw std::error_condition(error::DECOMPRESSION_ERROR);
|
||||
uint8_t lastcomp = 0;
|
||||
int repcount = 0;
|
||||
for (int hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
for (uint32_t hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
{
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
if (repcount > 0)
|
||||
@ -2202,7 +2173,7 @@ void chd_file::decompress_v5_map()
|
||||
uint64_t curoffset = firstoffs;
|
||||
uint32_t last_self = 0;
|
||||
uint64_t last_parent = 0;
|
||||
for (int hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
for (uint32_t hunknum = 0; hunknum < m_hunkcount; hunknum++)
|
||||
{
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
uint64_t offset = curoffset;
|
||||
@ -2244,7 +2215,7 @@ void chd_file::decompress_v5_map()
|
||||
|
||||
case COMPRESSION_PARENT_SELF:
|
||||
rawmap[0] = COMPRESSION_PARENT;
|
||||
last_parent = offset = (uint64_t(hunknum) * uint64_t(m_hunkbytes)) / m_unitbytes;
|
||||
last_parent = offset = mulu_32x32(hunknum, m_hunkbytes) / m_unitbytes;
|
||||
break;
|
||||
|
||||
case COMPRESSION_PARENT_1:
|
||||
@ -2255,9 +2226,9 @@ void chd_file::decompress_v5_map()
|
||||
offset = last_parent;
|
||||
break;
|
||||
}
|
||||
be_write(&rawmap[1], length, 3);
|
||||
be_write(&rawmap[4], offset, 6);
|
||||
be_write(&rawmap[10], crc, 2);
|
||||
put_u24be(&rawmap[1], length);
|
||||
put_u48be(&rawmap[4], offset);
|
||||
put_u16be(&rawmap[10], crc);
|
||||
}
|
||||
|
||||
// verify the final CRC
|
||||
@ -2316,17 +2287,17 @@ std::error_condition chd_file::create_common()
|
||||
// create our V5 header
|
||||
uint8_t rawheader[V5_HEADER_SIZE];
|
||||
memcpy(&rawheader[0], "MComprHD", 8);
|
||||
be_write(&rawheader[8], V5_HEADER_SIZE, 4);
|
||||
be_write(&rawheader[12], m_version, 4);
|
||||
be_write(&rawheader[16], m_compression[0], 4);
|
||||
be_write(&rawheader[20], m_compression[1], 4);
|
||||
be_write(&rawheader[24], m_compression[2], 4);
|
||||
be_write(&rawheader[28], m_compression[3], 4);
|
||||
be_write(&rawheader[32], m_logicalbytes, 8);
|
||||
be_write(&rawheader[40], compressed() ? 0 : V5_HEADER_SIZE, 8);
|
||||
be_write(&rawheader[48], m_metaoffset, 8);
|
||||
be_write(&rawheader[56], m_hunkbytes, 4);
|
||||
be_write(&rawheader[60], m_unitbytes, 4);
|
||||
put_u32be(&rawheader[8], V5_HEADER_SIZE);
|
||||
put_u32be(&rawheader[12], m_version);
|
||||
put_u32be(&rawheader[16], m_compression[0]);
|
||||
put_u32be(&rawheader[20], m_compression[1]);
|
||||
put_u32be(&rawheader[24], m_compression[2]);
|
||||
put_u32be(&rawheader[28], m_compression[3]);
|
||||
put_u64be(&rawheader[32], m_logicalbytes);
|
||||
put_u64be(&rawheader[40], compressed() ? 0 : V5_HEADER_SIZE);
|
||||
put_u64be(&rawheader[48], m_metaoffset);
|
||||
put_u32be(&rawheader[56], m_hunkbytes);
|
||||
put_u32be(&rawheader[60], m_unitbytes);
|
||||
be_write_sha1(&rawheader[64], util::sha1_t::null);
|
||||
be_write_sha1(&rawheader[84], util::sha1_t::null);
|
||||
be_write_sha1(&rawheader[104], (m_parent != nullptr) ? m_parent->sha1() : util::sha1_t::null);
|
||||
@ -2413,7 +2384,7 @@ std::error_condition chd_file::open_common(bool writeable)
|
||||
if (memcmp(rawheader, "MComprHD", 8) != 0)
|
||||
throw std::error_condition(error::INVALID_FILE);
|
||||
|
||||
m_version = be_read(&rawheader[12], 4);
|
||||
m_version = get_u32be(&rawheader[12]);
|
||||
|
||||
// read the header if we support it
|
||||
util::sha1_t parentsha1 = util::sha1_t::null;
|
||||
@ -2562,9 +2533,9 @@ void chd_file::hunk_write_compressed(uint32_t hunknum, int8_t compression, const
|
||||
// update the map entry
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
rawmap[0] = (compression == -1) ? COMPRESSION_NONE : compression;
|
||||
be_write(&rawmap[1], complength, 3);
|
||||
be_write(&rawmap[4], offset, 6);
|
||||
be_write(&rawmap[10], crc16, 2);
|
||||
put_u24be(&rawmap[1], complength);
|
||||
put_u48be(&rawmap[4], offset);
|
||||
put_u16be(&rawmap[10], crc16);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2593,9 +2564,9 @@ void chd_file::hunk_copy_from_self(uint32_t hunknum, uint32_t otherhunk)
|
||||
// update the map entry
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
rawmap[0] = COMPRESSION_SELF;
|
||||
be_write(&rawmap[1], 0, 3);
|
||||
be_write(&rawmap[4], otherhunk, 6);
|
||||
be_write(&rawmap[10], 0, 2);
|
||||
put_u24be(&rawmap[1], 0);
|
||||
put_u48be(&rawmap[4], otherhunk);
|
||||
put_u16be(&rawmap[10], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2617,9 +2588,9 @@ void chd_file::hunk_copy_from_parent(uint32_t hunknum, uint64_t parentunit)
|
||||
// update the map entry
|
||||
uint8_t *rawmap = &m_rawmap[hunknum * 12];
|
||||
rawmap[0] = COMPRESSION_PARENT;
|
||||
be_write(&rawmap[1], 0, 3);
|
||||
be_write(&rawmap[4], parentunit, 6);
|
||||
be_write(&rawmap[10], 0, 2);
|
||||
put_u24be(&rawmap[1], 0);
|
||||
put_u48be(&rawmap[4], parentunit);
|
||||
put_u16be(&rawmap[10], 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2659,10 +2630,10 @@ bool chd_file::metadata_find(chd_metadata_tag metatag, int32_t metaindex, metada
|
||||
file_read(metaentry.offset, raw_meta_header, sizeof(raw_meta_header));
|
||||
|
||||
// extract the data
|
||||
metaentry.metatag = be_read(&raw_meta_header[0], 4);
|
||||
metaentry.metatag = get_u32be(&raw_meta_header[0]);
|
||||
metaentry.flags = raw_meta_header[4];
|
||||
metaentry.length = be_read(&raw_meta_header[5], 3);
|
||||
metaentry.next = be_read(&raw_meta_header[8], 8);
|
||||
metaentry.length = get_u24be(&raw_meta_header[5]);
|
||||
metaentry.next = get_u64be(&raw_meta_header[8]);
|
||||
|
||||
// if we got a match, proceed
|
||||
if (metatag == CHDMETATAG_WILDCARD || metaentry.metatag == metatag)
|
||||
@ -2706,7 +2677,7 @@ void chd_file::metadata_set_previous_next(uint64_t prevoffset, uint64_t nextoffs
|
||||
|
||||
// create a big-endian version
|
||||
uint8_t rawbuf[sizeof(uint64_t)];
|
||||
be_write(rawbuf, nextoffset, 8);
|
||||
put_u64be(rawbuf, nextoffset);
|
||||
|
||||
// write to the header and update our local copy
|
||||
file_write(offset, rawbuf, sizeof(rawbuf));
|
||||
|
@ -367,8 +367,6 @@ private:
|
||||
struct metadata_hash;
|
||||
|
||||
// inline helpers
|
||||
uint64_t be_read(const uint8_t *base, int numbytes) const;
|
||||
void be_write(uint8_t *base, uint64_t value, int numbytes);
|
||||
util::sha1_t be_read_sha1(const uint8_t *base) const;
|
||||
void be_write_sha1(uint8_t *base, util::sha1_t value);
|
||||
void file_read(uint64_t offset, void *dest, uint32_t length) const;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "chd.h"
|
||||
#include "flac.h"
|
||||
#include "hashing.h"
|
||||
#include "multibyte.h"
|
||||
|
||||
#include "lzma/C/LzmaDec.h"
|
||||
#include "lzma/C/LzmaEnc.h"
|
||||
@ -343,10 +344,10 @@ public:
|
||||
throw std::error_condition(chd_file::error::COMPRESSION_ERROR);
|
||||
|
||||
// write compressed length
|
||||
dest[ecc_bytes + 0] = complen >> ((complen_bytes - 1) * 8);
|
||||
dest[ecc_bytes + 1] = complen >> ((complen_bytes - 2) * 8);
|
||||
if (complen_bytes > 2)
|
||||
dest[ecc_bytes + 2] = complen >> ((complen_bytes - 3) * 8);
|
||||
put_u24be(&dest[ecc_bytes], complen);
|
||||
else
|
||||
put_u16be(&dest[ecc_bytes], complen);
|
||||
|
||||
// encode the subcode
|
||||
return header_bytes + complen + m_subcode_compressor.compress(&m_buffer[frames * cdrom_file::MAX_SECTOR_DATA], frames * cdrom_file::MAX_SUBCODE_DATA, &dest[header_bytes + complen]);
|
||||
@ -388,9 +389,7 @@ public:
|
||||
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];
|
||||
uint32_t complen_base = (complen_bytes > 2) ? get_u24be(&src[ecc_bytes]) : get_u16be(&src[ecc_bytes]);
|
||||
|
||||
// reset and decode
|
||||
m_base_decompressor.decompress(&src[header_bytes], complen_base, &m_buffer[0], frames * cdrom_file::MAX_SECTOR_DATA);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "flac.h"
|
||||
|
||||
#include "ioprocs.h"
|
||||
#include "multibyte.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@ -256,7 +257,7 @@ FLAC__StreamEncoderWriteStatus flac_encoder::write_callback(const FLAC__byte buf
|
||||
// if we haven't hit the end of metadata, process a new piece
|
||||
assert(bytes - offset >= 4);
|
||||
m_found_audio = ((buffer[offset] & 0x80) != 0);
|
||||
m_ignore_bytes = (buffer[offset + 1] << 16) | (buffer[offset + 2] << 8) | buffer[offset + 3];
|
||||
m_ignore_bytes = get_u24be(&buffer[offset + 1]);
|
||||
offset += 4;
|
||||
}
|
||||
else
|
||||
@ -415,11 +416,9 @@ bool flac_decoder::reset(uint32_t sample_rate, uint8_t num_channels, uint32_t bl
|
||||
// +2A: start of stream data
|
||||
};
|
||||
memcpy(m_custom_header, s_header_template, sizeof(s_header_template));
|
||||
m_custom_header[0x08] = m_custom_header[0x0a] = block_size >> 8;
|
||||
m_custom_header[0x09] = m_custom_header[0x0b] = block_size & 0xff;
|
||||
m_custom_header[0x12] = sample_rate >> 12;
|
||||
m_custom_header[0x13] = sample_rate >> 4;
|
||||
m_custom_header[0x14] = (sample_rate << 4) | ((num_channels - 1) << 1);
|
||||
put_u16be(&m_custom_header[0x08], block_size);
|
||||
put_u16be(&m_custom_header[0x0a], block_size);
|
||||
put_u24be(&m_custom_header[0x12], (sample_rate << 4) | ((num_channels - 1) << 1));
|
||||
|
||||
// configure the header ahead of the provided buffer
|
||||
m_file = nullptr;
|
||||
|
@ -43,6 +43,16 @@ inline constexpr u32 get_u32be(const u8 *const buf) noexcept
|
||||
| ((const u32)buf[3] << 0);
|
||||
}
|
||||
|
||||
inline constexpr u64 get_u48be(const u8 *const buf) noexcept
|
||||
{
|
||||
return ((const u64)buf[0] << 40)
|
||||
| ((const u64)buf[1] << 36)
|
||||
| ((const u64)buf[2] << 24)
|
||||
| ((const u64)buf[3] << 16)
|
||||
| ((const u64)buf[4] << 8)
|
||||
| ((const u64)buf[5] << 0);
|
||||
}
|
||||
|
||||
inline constexpr u64 get_u64be(const u8 *const buf) noexcept
|
||||
{
|
||||
return ((const u64)buf[0] << 56)
|
||||
@ -76,6 +86,16 @@ inline void put_u32be(u8 *buf, const u32 data) noexcept
|
||||
buf[3] = data >> 0;
|
||||
}
|
||||
|
||||
inline void put_u48be(u8 *buf, const u64 data) noexcept
|
||||
{
|
||||
buf[0] = data >> 40;
|
||||
buf[1] = data >> 36;
|
||||
buf[2] = data >> 24;
|
||||
buf[3] = data >> 16;
|
||||
buf[4] = data >> 8;
|
||||
buf[5] = data >> 0;
|
||||
}
|
||||
|
||||
inline void put_u64be(u8 *buf, const u64 data) noexcept
|
||||
{
|
||||
buf[0] = data >> 56;
|
||||
@ -107,6 +127,11 @@ inline constexpr s32 get_s32be(const u8 *const buf) noexcept
|
||||
return get_u32be(buf);
|
||||
}
|
||||
|
||||
inline constexpr s64 get_s48be(const u8 *const buf) noexcept
|
||||
{
|
||||
return util::sext(get_u48be(buf), 48);
|
||||
}
|
||||
|
||||
inline constexpr s64 get_s64be(const u8 *const buf) noexcept
|
||||
{
|
||||
return get_u64be(buf);
|
||||
@ -127,6 +152,11 @@ inline void put_s32be(u8 *buf, const s32 data) noexcept
|
||||
put_u32be(buf, data);
|
||||
}
|
||||
|
||||
inline void put_s48be(u8 *buf, const s64 data) noexcept
|
||||
{
|
||||
put_u48be(buf, data);
|
||||
}
|
||||
|
||||
inline void put_s64be(u8 *buf, const s64 data) noexcept
|
||||
{
|
||||
put_u64be(buf, data);
|
||||
@ -157,6 +187,16 @@ inline constexpr u32 get_u32le(const u8 *const buf) noexcept
|
||||
| ((const u32)buf[3] << 24);
|
||||
}
|
||||
|
||||
inline constexpr u64 get_u48le(const u8 *const buf) noexcept
|
||||
{
|
||||
return ((const u64)buf[0] << 0)
|
||||
| ((const u64)buf[1] << 8)
|
||||
| ((const u64)buf[2] << 16)
|
||||
| ((const u64)buf[3] << 24)
|
||||
| ((const u64)buf[4] << 32)
|
||||
| ((const u64)buf[5] << 40);
|
||||
}
|
||||
|
||||
inline constexpr u64 get_u64le(const u8 *const buf) noexcept
|
||||
{
|
||||
return ((const u64)buf[0] << 0)
|
||||
@ -190,6 +230,16 @@ inline void put_u32le(u8 *buf, const u32 data) noexcept
|
||||
buf[3] = data >> 24;
|
||||
}
|
||||
|
||||
inline void put_u48le(u8 *buf, const u64 data) noexcept
|
||||
{
|
||||
buf[0] = data >> 0;
|
||||
buf[1] = data >> 8;
|
||||
buf[2] = data >> 16;
|
||||
buf[3] = data >> 24;
|
||||
buf[4] = data >> 32;
|
||||
buf[5] = data >> 40;
|
||||
}
|
||||
|
||||
inline void put_u64le(u8 *buf, const u64 data) noexcept
|
||||
{
|
||||
buf[0] = data >> 0;
|
||||
@ -221,6 +271,11 @@ inline constexpr s32 get_s32le(const u8 *const buf) noexcept
|
||||
return get_u32le(buf);
|
||||
}
|
||||
|
||||
inline constexpr s64 get_s48le(const u8 *const buf) noexcept
|
||||
{
|
||||
return util::sext(get_u48le(buf), 48);
|
||||
}
|
||||
|
||||
inline constexpr s64 get_s64le(const u8 *const buf) noexcept
|
||||
{
|
||||
return get_u64le(buf);
|
||||
@ -241,6 +296,11 @@ inline void put_s32le(u8 *buf, const s32 data) noexcept
|
||||
put_u32le(buf, data);
|
||||
}
|
||||
|
||||
inline void put_s48le(u8 *buf, const s64 data) noexcept
|
||||
{
|
||||
put_u48le(buf, data);
|
||||
}
|
||||
|
||||
inline void put_s64le(u8 *buf, const s64 data) noexcept
|
||||
{
|
||||
put_u64le(buf, data);
|
||||
|
Loading…
Reference in New Issue
Block a user