diff options
author | 2021-08-22 09:06:15 +1000 | |
---|---|---|
committer | 2021-08-22 09:06:15 +1000 | |
commit | e8bbea1fc6e94e14768509d322f6c624403ffb36 (patch) | |
tree | 74dd1606a900d83de8aecff17a6737af4113308d /src/lib/util/chdcodec.cpp | |
parent | e319bde5fc3696d7f48f62b15b6366c4377fe5d1 (diff) |
formats, osd, util: Started refactoring file I/O stuff. (#8456)
Added more modern generic I/O interfaces with implementation backed by stdio, osd_file and core_file, replacing io_generic. Also replaced core_file's build-in zlib compression with a filter.
unzip.cpp, un7z.cpp: Added option to supply abstract I/O interface rather than filename.
Converted osd_file, core_file, archive_file, chd_file and device_image_interface to use std::error_condition rather than their own error enums.
Allow mounting TI-99 RPK from inside archives.
Diffstat (limited to 'src/lib/util/chdcodec.cpp')
-rw-r--r-- | src/lib/util/chdcodec.cpp | 260 |
1 files changed, 151 insertions, 109 deletions
diff --git a/src/lib/util/chdcodec.cpp b/src/lib/util/chdcodec.cpp index 4f5c23b3104..eca9403b56c 100644 --- a/src/lib/util/chdcodec.cpp +++ b/src/lib/util/chdcodec.cpp @@ -8,24 +8,29 @@ ***************************************************************************/ -#include <cassert> +#include "chdcodec.h" -#include "chd.h" -#include "hashing.h" #include "avhuff.h" -#include "flac.h" #include "cdrom.h" -#include <zlib.h> -#include "lzma/C/LzmaEnc.h" +#include "chd.h" +#include "flac.h" +#include "hashing.h" + #include "lzma/C/LzmaDec.h" +#include "lzma/C/LzmaEnc.h" + +#include <zlib.h> + #include <new> +namespace { + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** -static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; +constexpr uint8_t f_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; @@ -35,7 +40,7 @@ static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff // ======================> chd_zlib_allocator -// allocation helper clas for zlib +// allocation helper class for zlib class chd_zlib_allocator { public: @@ -51,7 +56,8 @@ private: static voidpf fast_alloc(voidpf opaque, uInt items, uInt size); static void fast_free(voidpf opaque, voidpf address); - static const int MAX_ZLIB_ALLOCS = 64; + static constexpr int MAX_ZLIB_ALLOCS = 64; + uint32_t * m_allocptr[MAX_ZLIB_ALLOCS]; }; @@ -111,7 +117,7 @@ private: static void *fast_alloc(void *p, size_t size); static void fast_free(void *p, void *address); - static const int MAX_LZMA_ALLOCS = 64; + static constexpr int MAX_LZMA_ALLOCS = 64; uint32_t * m_allocptr[MAX_LZMA_ALLOCS]; }; @@ -287,7 +293,7 @@ private: // ======================> chd_cd_compressor -template<class _BaseCompressor, class _SubcodeCompressor> +template<class BaseCompressor, class SubcodeCompressor> class chd_cd_compressor : public chd_compressor { public: @@ -300,7 +306,7 @@ public: { // make sure the CHD's hunk size is an even multiple of the frame size if (hunkbytes % CD_FRAME_SIZE != 0) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } // core functionality @@ -323,10 +329,10 @@ public: // clear out ECC data if we can uint8_t *sector = &m_buffer[framenum * CD_MAX_SECTOR_DATA]; - if (memcmp(sector, s_cd_sync_header, sizeof(s_cd_sync_header)) == 0 && ecc_verify(sector)) + if (memcmp(sector, f_cd_sync_header, sizeof(f_cd_sync_header)) == 0 && ecc_verify(sector)) { dest[framenum / 8] |= 1 << (framenum % 8); - memset(sector, 0, sizeof(s_cd_sync_header)); + memset(sector, 0, sizeof(f_cd_sync_header)); ecc_clear(sector); } } @@ -334,7 +340,7 @@ public: // encode the base portion uint32_t complen = m_base_compressor.compress(&m_buffer[0], frames * CD_MAX_SECTOR_DATA, &dest[header_bytes]); if (complen >= srclen) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // write compressed length dest[ecc_bytes + 0] = complen >> ((complen_bytes - 1) * 8); @@ -348,15 +354,15 @@ public: private: // internal state - _BaseCompressor m_base_compressor; - _SubcodeCompressor m_subcode_compressor; + BaseCompressor m_base_compressor; + SubcodeCompressor m_subcode_compressor; std::vector<uint8_t> m_buffer; }; // ======================> chd_cd_decompressor -template<class _BaseDecompressor, class _SubcodeDecompressor> +template<class BaseDecompressor, class SubcodeDecompressor> class chd_cd_decompressor : public chd_decompressor { public: @@ -369,7 +375,7 @@ public: { // make sure the CHD's hunk size is an even multiple of the frame size if (hunkbytes % CD_FRAME_SIZE != 0) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } // core functionality @@ -400,7 +406,7 @@ public: uint8_t *sector = &dest[framenum * CD_FRAME_SIZE]; if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) { - memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); + memcpy(sector, f_cd_sync_header, sizeof(f_cd_sync_header)); ecc_generate(sector); } } @@ -408,8 +414,8 @@ public: private: // internal state - _BaseDecompressor m_base_decompressor; - _SubcodeDecompressor m_subcode_decompressor; + BaseDecompressor m_base_decompressor; + SubcodeDecompressor m_subcode_decompressor; std::vector<uint8_t> m_buffer; }; @@ -460,25 +466,65 @@ private: // CODEC LIST //************************************************************************** +// an entry in the list +struct codec_entry +{ + chd_codec_type m_type; + bool m_lossy; + const char * m_name; + chd_compressor::ptr (*m_construct_compressor)(chd_file &, uint32_t, bool); + chd_decompressor::ptr (*m_construct_decompressor)(chd_file &, uint32_t, bool); + + template <class CompressorClass> + static chd_compressor::ptr construct_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy) + { + return std::make_unique<CompressorClass>(chd, hunkbytes, lossy); + } + + template <class DecompressorClass> + static chd_decompressor::ptr construct_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy) + { + return std::make_unique<DecompressorClass>(chd, hunkbytes, lossy); + } +}; + + // static list of available known codecs -const chd_codec_list::codec_entry chd_codec_list::s_codec_list[] = +const codec_entry f_codec_list[] = { // general codecs - { CHD_CODEC_ZLIB, false, "Deflate", &chd_codec_list::construct_compressor<chd_zlib_compressor>, &chd_codec_list::construct_decompressor<chd_zlib_decompressor> }, - { CHD_CODEC_LZMA, false, "LZMA", &chd_codec_list::construct_compressor<chd_lzma_compressor>, &chd_codec_list::construct_decompressor<chd_lzma_decompressor> }, - { CHD_CODEC_HUFFMAN, false, "Huffman", &chd_codec_list::construct_compressor<chd_huffman_compressor>, &chd_codec_list::construct_decompressor<chd_huffman_decompressor> }, - { CHD_CODEC_FLAC, false, "FLAC", &chd_codec_list::construct_compressor<chd_flac_compressor>, &chd_codec_list::construct_decompressor<chd_flac_decompressor> }, + { CHD_CODEC_ZLIB, false, "Deflate", &codec_entry::construct_compressor<chd_zlib_compressor>, &codec_entry::construct_decompressor<chd_zlib_decompressor> }, + { CHD_CODEC_LZMA, false, "LZMA", &codec_entry::construct_compressor<chd_lzma_compressor>, &codec_entry::construct_decompressor<chd_lzma_decompressor> }, + { CHD_CODEC_HUFFMAN, false, "Huffman", &codec_entry::construct_compressor<chd_huffman_compressor>, &codec_entry::construct_decompressor<chd_huffman_decompressor> }, + { CHD_CODEC_FLAC, false, "FLAC", &codec_entry::construct_compressor<chd_flac_compressor>, &codec_entry::construct_decompressor<chd_flac_decompressor> }, // general codecs with CD frontend - { CHD_CODEC_CD_ZLIB, false, "CD Deflate", &chd_codec_list::construct_compressor<chd_cd_compressor<chd_zlib_compressor, chd_zlib_compressor> >, &chd_codec_list::construct_decompressor<chd_cd_decompressor<chd_zlib_decompressor, chd_zlib_decompressor> > }, - { CHD_CODEC_CD_LZMA, false, "CD LZMA", &chd_codec_list::construct_compressor<chd_cd_compressor<chd_lzma_compressor, chd_zlib_compressor> >, &chd_codec_list::construct_decompressor<chd_cd_decompressor<chd_lzma_decompressor, chd_zlib_decompressor> > }, - { CHD_CODEC_CD_FLAC, false, "CD FLAC", &chd_codec_list::construct_compressor<chd_cd_flac_compressor>, &chd_codec_list::construct_decompressor<chd_cd_flac_decompressor> }, + { CHD_CODEC_CD_ZLIB, false, "CD Deflate", &codec_entry::construct_compressor<chd_cd_compressor<chd_zlib_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_zlib_decompressor, chd_zlib_decompressor> > }, + { CHD_CODEC_CD_LZMA, false, "CD LZMA", &codec_entry::construct_compressor<chd_cd_compressor<chd_lzma_compressor, chd_zlib_compressor> >, &codec_entry::construct_decompressor<chd_cd_decompressor<chd_lzma_decompressor, chd_zlib_decompressor> > }, + { CHD_CODEC_CD_FLAC, false, "CD FLAC", &codec_entry::construct_compressor<chd_cd_flac_compressor>, &codec_entry::construct_decompressor<chd_cd_flac_decompressor> }, // A/V codecs - { CHD_CODEC_AVHUFF, false, "A/V Huffman", &chd_codec_list::construct_compressor<chd_avhuff_compressor>, &chd_codec_list::construct_decompressor<chd_avhuff_decompressor> }, + { CHD_CODEC_AVHUFF, false, "A/V Huffman", &codec_entry::construct_compressor<chd_avhuff_compressor>, &codec_entry::construct_decompressor<chd_avhuff_decompressor> }, }; +//------------------------------------------------- +// find_in_list - create a new compressor +// instance of the given type +//------------------------------------------------- + +const codec_entry *find_in_list(chd_codec_type type) +{ + // find in the list and construct the class + for (auto & elem : f_codec_list) + if (elem.m_type == type) + return &elem; + return nullptr; +} + +} // anonymous namespace + + //************************************************************************** // CHD CODEC @@ -512,7 +558,7 @@ chd_codec::~chd_codec() void chd_codec::configure(int param, void *config) { // if not overridden, it is always a failure - throw CHDERR_INVALID_PARAMETER; + throw std::error_condition(std::errc::invalid_argument); } @@ -556,11 +602,11 @@ chd_decompressor::chd_decompressor(chd_file &chd, uint32_t hunkbytes, bool lossy // instance of the given type //------------------------------------------------- -chd_compressor *chd_codec_list::new_compressor(chd_codec_type type, chd_file &chd) +chd_compressor::ptr chd_codec_list::new_compressor(chd_codec_type type, chd_file &chd) { // find in the list and construct the class - const codec_entry *entry = find_in_list(type); - return (entry == nullptr) ? nullptr : (*entry->m_construct_compressor)(chd, chd.hunk_bytes(), entry->m_lossy); + codec_entry const *const entry = find_in_list(type); + return entry ? (*entry->m_construct_compressor)(chd, chd.hunk_bytes(), entry->m_lossy) : nullptr; } @@ -569,39 +615,36 @@ chd_compressor *chd_codec_list::new_compressor(chd_codec_type type, chd_file &ch // instance of the given type //------------------------------------------------- -chd_decompressor *chd_codec_list::new_decompressor(chd_codec_type type, chd_file &chd) +chd_decompressor::ptr chd_codec_list::new_decompressor(chd_codec_type type, chd_file &chd) { // find in the list and construct the class const codec_entry *entry = find_in_list(type); - return (entry == nullptr) ? nullptr : (*entry->m_construct_decompressor)(chd, chd.hunk_bytes(), entry->m_lossy); + return entry ? (*entry->m_construct_decompressor)(chd, chd.hunk_bytes(), entry->m_lossy) : nullptr; } //------------------------------------------------- -// codec_name - return the name of the given -// codec +// codec_exists - determine whether a codec type +// corresponds to a supported codec //------------------------------------------------- -const char *chd_codec_list::codec_name(chd_codec_type type) +bool chd_codec_list::codec_exists(chd_codec_type type) { // find in the list and construct the class - const codec_entry *entry = find_in_list(type); - return (entry == nullptr) ? nullptr : entry->m_name; + return bool(find_in_list(type)); } //------------------------------------------------- -// find_in_list - create a new compressor -// instance of the given type +// codec_name - return the name of the given +// codec //------------------------------------------------- -const chd_codec_list::codec_entry *chd_codec_list::find_in_list(chd_codec_type type) +const char *chd_codec_list::codec_name(chd_codec_type type) { // find in the list and construct the class - for (auto & elem : s_codec_list) - if (elem.m_type == type) - return &elem; - return nullptr; + const codec_entry *entry = find_in_list(type); + return entry ? entry->m_name : nullptr; } @@ -615,25 +658,24 @@ const chd_codec_list::codec_entry *chd_codec_list::find_in_list(chd_codec_type t //------------------------------------------------- chd_compressor_group::chd_compressor_group(chd_file &chd, uint32_t compressor_list[4]) - : m_hunkbytes(chd.hunk_bytes()), - m_compress_test(m_hunkbytes) + : m_hunkbytes(chd.hunk_bytes()) + , m_compress_test(m_hunkbytes) #if CHDCODEC_VERIFY_COMPRESSION - ,m_decompressed(m_hunkbytes) + , m_decompressed(m_hunkbytes) #endif { // verify the compression types and initialize the codecs for (int codecnum = 0; codecnum < std::size(m_compressor); codecnum++) { - m_compressor[codecnum] = nullptr; if (compressor_list[codecnum] != CHD_CODEC_NONE) { m_compressor[codecnum] = chd_codec_list::new_compressor(compressor_list[codecnum], chd); - if (m_compressor[codecnum] == nullptr) - throw CHDERR_UNKNOWN_COMPRESSION; + if (!m_compressor[codecnum]) + throw std::error_condition(chd_file::error::UNKNOWN_COMPRESSION); #if CHDCODEC_VERIFY_COMPRESSION m_decompressor[codecnum] = chd_codec_list::new_decompressor(compressor_list[codecnum], chd); - if (m_decompressor[codecnum] == nullptr) - throw CHDERR_UNKNOWN_COMPRESSION; + if (!m_decompressor[codecnum]) + throw std::error_condition(chd_file::error::UNKNOWN_COMPRESSION); #endif } } @@ -646,9 +688,7 @@ chd_compressor_group::chd_compressor_group(chd_file &chd, uint32_t compressor_li chd_compressor_group::~chd_compressor_group() { - // delete the codecs and the test buffer - for (auto & elem : m_compressor) - delete elem; + // codecs and test buffer deleted automatically } @@ -664,7 +704,7 @@ int8_t chd_compressor_group::find_best_compressor(const uint8_t *src, uint8_t *c complen = m_hunkbytes; int8_t compression = -1; for (int codecnum = 0; codecnum < std::size(m_compressor); codecnum++) - if (m_compressor[codecnum] != nullptr) + if (m_compressor[codecnum]) { // attempt to compress, swallowing errors try @@ -702,7 +742,9 @@ printf(" codec%d=%d bytes \n", codecnum, compbytes); memcpy(compressed, &m_compress_test[0], compbytes); } } - catch (...) { } + catch (...) + { + } } // if the best is none, copy it over @@ -835,7 +877,7 @@ chd_zlib_compressor::chd_zlib_compressor(chd_file &chd, uint32_t hunkbytes, bool if (zerr == Z_MEM_ERROR) throw std::bad_alloc(); else if (zerr != Z_OK) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } @@ -864,14 +906,14 @@ uint32_t chd_zlib_compressor::compress(const uint8_t *src, uint32_t srclen, uint m_deflater.total_out = 0; int zerr = deflateReset(&m_deflater); if (zerr != Z_OK) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // do it zerr = deflate(&m_deflater, Z_FINISH); // if we ended up with more data than we started with, return an error if (zerr != Z_STREAM_END || m_deflater.total_out >= srclen) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // otherwise, return the length return m_deflater.total_out; @@ -900,7 +942,7 @@ chd_zlib_decompressor::chd_zlib_decompressor(chd_file &chd, uint32_t hunkbytes, if (zerr == Z_MEM_ERROR) throw std::bad_alloc(); else if (zerr != Z_OK) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } @@ -930,14 +972,14 @@ void chd_zlib_decompressor::decompress(const uint8_t *src, uint32_t complen, uin m_inflater.total_out = 0; int zerr = inflateReset(&m_inflater); if (zerr != Z_OK) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // do it zerr = inflate(&m_inflater, Z_FINISH); if (zerr != Z_STREAM_END) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); if (m_inflater.total_out != destlen) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); } @@ -1071,20 +1113,20 @@ uint32_t chd_lzma_compressor::compress(const uint8_t *src, uint32_t srclen, uint // allocate the encoder CLzmaEncHandle encoder = LzmaEnc_Create(&m_allocator); if (encoder == nullptr) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); try { // configure the encoder SRes res = LzmaEnc_SetProps(encoder, &m_props); if (res != SZ_OK) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // run it SizeT complen = srclen; res = LzmaEnc_MemEncode(encoder, dest, &complen, src, srclen, 0, nullptr, &m_allocator, &m_allocator); if (res != SZ_OK) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // clean up LzmaEnc_Destroy(encoder, &m_allocator, &m_allocator); @@ -1140,24 +1182,24 @@ chd_lzma_decompressor::chd_lzma_decompressor(chd_file &chd, uint32_t hunkbytes, // convert to decoder properties CLzmaEncHandle enc = LzmaEnc_Create(&m_allocator); if (!enc) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK) { LzmaEnc_Destroy(enc, &m_allocator, &m_allocator); - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); } Byte decoder_props[LZMA_PROPS_SIZE]; SizeT props_size = sizeof(decoder_props); if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK) { LzmaEnc_Destroy(enc, &m_allocator, &m_allocator); - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); } LzmaEnc_Destroy(enc, &m_allocator, &m_allocator); // do memory allocations if (LzmaDec_Allocate(&m_decoder, decoder_props, LZMA_PROPS_SIZE, &m_allocator) != SZ_OK) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); } @@ -1188,7 +1230,7 @@ void chd_lzma_decompressor::decompress(const uint8_t *src, uint32_t complen, uin ELzmaStatus status; SRes res = LzmaDec_DecodeToBuf(&m_decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status); if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); } @@ -1216,7 +1258,7 @@ uint32_t chd_huffman_compressor::compress(const uint8_t *src, uint32_t srclen, u { uint32_t complen; if (m_encoder.encode(src, srclen, dest, srclen, complen) != HUFFERR_NONE) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); return complen; } @@ -1244,7 +1286,7 @@ chd_huffman_decompressor::chd_huffman_decompressor(chd_file &chd, uint32_t hunkb void chd_huffman_decompressor::decompress(const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { if (m_decoder.decode(src, complen, dest, destlen) != HUFFERR_NONE) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); } @@ -1282,19 +1324,19 @@ uint32_t chd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, uint // reset and encode big-endian m_encoder.reset(dest + 1, hunkbytes() - 1); if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, !m_big_endian)) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); uint32_t complen_be = m_encoder.finish(); // reset and encode little-endian m_encoder.reset(dest + 1, hunkbytes() - 1); if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, m_big_endian)) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); uint32_t complen_le = m_encoder.finish(); // pick the best one and add a byte uint32_t complen = std::min(complen_le, complen_be); if (complen + 1 >= hunkbytes()) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // if big-endian was better, re-do it dest[0] = 'L'; @@ -1303,7 +1345,7 @@ uint32_t chd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, uint dest[0] = 'B'; m_encoder.reset(dest + 1, hunkbytes() - 1); if (!m_encoder.encode_interleaved(reinterpret_cast<const int16_t *>(src), srclen / 4, !m_big_endian)) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); m_encoder.finish(); } return complen + 1; @@ -1358,13 +1400,13 @@ void chd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, uin else if (src[0] == 'B') swap_endian = !m_big_endian; else - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // reset and decode if (!m_decoder.reset(44100, 2, chd_flac_compressor::blocksize(destlen), src + 1, complen - 1)) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(dest), destlen / 4, swap_endian)) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // finish up m_decoder.finish(); @@ -1386,7 +1428,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes { // make sure the CHD's hunk size is an even multiple of the frame size if (hunkbytes % CD_FRAME_SIZE != 0) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); // determine whether we want native or swapped samples uint16_t native_endian = 0; @@ -1409,7 +1451,7 @@ chd_cd_flac_compressor::chd_cd_flac_compressor(chd_file &chd, uint32_t hunkbytes if (zerr == Z_MEM_ERROR) throw std::bad_alloc(); else if (zerr != Z_OK) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } @@ -1442,7 +1484,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u m_encoder.reset(dest, hunkbytes()); uint8_t *buffer = &m_buffer[0]; if (!m_encoder.encode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian)) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // finish up uint32_t complen = m_encoder.finish(); @@ -1456,7 +1498,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u m_deflater.total_out = 0; int zerr = deflateReset(&m_deflater); if (zerr != Z_OK) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); // do it zerr = deflate(&m_deflater, Z_FINISH); @@ -1464,7 +1506,7 @@ uint32_t chd_cd_flac_compressor::compress(const uint8_t *src, uint32_t srclen, u // if we ended up with more data than we started with, return an error complen += m_deflater.total_out; if (zerr != Z_STREAM_END || complen >= srclen) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); return complen; } @@ -1515,7 +1557,7 @@ chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkb { // make sure the CHD's hunk size is an even multiple of the frame size if (hunkbytes % CD_FRAME_SIZE != 0) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); // determine whether we want native or swapped samples uint16_t native_endian = 0; @@ -1532,7 +1574,7 @@ chd_cd_flac_decompressor::chd_cd_flac_decompressor(chd_file &chd, uint32_t hunkb if (zerr == Z_MEM_ERROR) throw std::bad_alloc(); else if (zerr != Z_OK) - throw CHDERR_CODEC_ERROR; + throw std::error_condition(chd_file::error::CODEC_ERROR); } /** @@ -1569,10 +1611,10 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, // reset and decode uint32_t frames = destlen / CD_FRAME_SIZE; if (!m_decoder.reset(44100, 2, chd_cd_flac_compressor::blocksize(frames * CD_MAX_SECTOR_DATA), src, complen)) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); uint8_t *buffer = &m_buffer[0]; if (!m_decoder.decode_interleaved(reinterpret_cast<int16_t *>(buffer), frames * CD_MAX_SECTOR_DATA/4, m_swap_endian)) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // inflate the subcode data uint32_t offset = m_decoder.finish(); @@ -1584,14 +1626,14 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, m_inflater.total_out = 0; int zerr = inflateReset(&m_inflater); if (zerr != Z_OK) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // do it zerr = inflate(&m_inflater, Z_FINISH); if (zerr != Z_STREAM_END) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); if (m_inflater.total_out != frames * CD_MAX_SUBCODE_DATA) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // reassemble the data for (uint32_t framenum = 0; framenum < frames; framenum++) @@ -1620,15 +1662,15 @@ void chd_cd_flac_decompressor::decompress(const uint8_t *src, uint32_t complen, */ chd_avhuff_compressor::chd_avhuff_compressor(chd_file &chd, uint32_t hunkbytes, bool lossy) - : chd_compressor(chd, hunkbytes, lossy), - m_postinit(false) + : chd_compressor(chd, hunkbytes, lossy) + , m_postinit(false) { try { // attempt to do a post-init now postinit(); } - catch (chd_error &) + catch (std::error_condition const &) { // if we're creating a new CHD, it won't work but that's ok } @@ -1665,14 +1707,14 @@ uint32_t chd_avhuff_compressor::compress(const uint8_t *src, uint32_t srclen, ui int size = avhuff_encoder::raw_data_size(src); while (size < srclen) if (src[size++] != 0) - throw CHDERR_INVALID_DATA; + throw std::error_condition(chd_file::error::INVALID_DATA); } // encode the audio and video uint32_t complen; avhuff_error averr = m_encoder.encode_data(src, dest, complen); if (averr != AVHERR_NONE || complen > srclen) - throw CHDERR_COMPRESSION_ERROR; + throw std::error_condition(chd_file::error::COMPRESSION_ERROR); return complen; } @@ -1693,21 +1735,21 @@ void chd_avhuff_compressor::postinit() { // get the metadata std::string metadata; - chd_error err = chd().read_metadata(AV_METADATA_TAG, 0, metadata); - if (err != CHDERR_NONE) + std::error_condition err = chd().read_metadata(AV_METADATA_TAG, 0, metadata); + if (err) throw err; // extract the info int fps, fpsfrac, width, height, interlaced, channels, rate; if (sscanf(metadata.c_str(), AV_METADATA_FORMAT, &fps, &fpsfrac, &width, &height, &interlaced, &channels, &rate) != 7) - throw CHDERR_INVALID_METADATA; + throw std::error_condition(chd_file::error::INVALID_METADATA); // compute the bytes per frame uint32_t fps_times_1million = fps * 1000000 + fpsfrac; uint32_t max_samples_per_frame = (uint64_t(rate) * 1000000 + fps_times_1million - 1) / fps_times_1million; uint32_t bytes_per_frame = 12 + channels * max_samples_per_frame * 2 + width * height * 2; if (bytes_per_frame > hunkbytes()) - throw CHDERR_INVALID_METADATA; + throw std::error_condition(chd_file::error::INVALID_METADATA); // done with post-init m_postinit = true; @@ -1757,7 +1799,7 @@ void chd_avhuff_decompressor::decompress(const uint8_t *src, uint32_t complen, u // decode the audio and video avhuff_error averr = m_decoder.decode_data(src, complen, dest); if (averr != AVHERR_NONE) - throw CHDERR_DECOMPRESSION_ERROR; + throw std::error_condition(chd_file::error::DECOMPRESSION_ERROR); // pad short frames with 0 if (dest != nullptr) @@ -1790,5 +1832,5 @@ void chd_avhuff_decompressor::configure(int param, void *config) // anything else is invalid else - throw CHDERR_INVALID_PARAMETER; + throw std::error_condition(std::errc::invalid_argument); } |