// license:BSD-3-Clause // copyright-holders:Aaron Giles /*************************************************************************** chdcodec.h Codecs used by the CHD format ***************************************************************************/ #pragma once #ifndef __CHDCODEC_H__ #define __CHDCODEC_H__ #include "osdcore.h" #define CHDCODEC_VERIFY_COMPRESSION 0 //************************************************************************** // MACROS //************************************************************************** #define CHD_MAKE_TAG(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) //************************************************************************** // TYPE DEFINITIONS //************************************************************************** // forward references class chd_file; // base types typedef UINT32 chd_codec_type; // ======================> chd_codec // common base class for all compressors and decompressors class chd_codec { protected: // can't create these directly chd_codec(chd_file &file, UINT32 hunkbytes, bool lossy); public: // allow public deletion virtual ~chd_codec(); // accessors chd_file &chd() const { return m_chd; } UINT32 hunkbytes() const { return m_hunkbytes; } bool lossy() const { return m_lossy; } // implementation virtual void configure(int param, void *config); private: // internal state chd_file & m_chd; UINT32 m_hunkbytes; bool m_lossy; }; // ======================> chd_compressor // base class for all compressors class chd_compressor : public chd_codec { protected: // can't create these directly chd_compressor(chd_file &file, UINT32 hunkbytes, bool lossy); public: // implementation virtual UINT32 compress(const UINT8 *src, UINT32 srclen, UINT8 *dest) = 0; }; // ======================> chd_decompressor // base class for all decompressors class chd_decompressor : public chd_codec { protected: // can't create these directly chd_decompressor(chd_file &file, UINT32 hunkbytes, bool lossy); public: // implementation virtual void decompress(const UINT8 *src, UINT32 complen, UINT8 *dest, UINT32 destlen) = 0; }; // ======================> chd_codec_list // wrapper to get at the list of codecs class chd_codec_list { public: // create compressors or decompressors static chd_compressor *new_compressor(chd_codec_type type, chd_file &file); static chd_decompressor *new_decompressor(chd_codec_type type, chd_file &file); // utilities static bool codec_exists(chd_codec_type type) { return (find_in_list(type) != nullptr); } static const char *codec_name(chd_codec_type type); private: // an entry in the list struct codec_entry { chd_codec_type m_type; bool m_lossy; const char * m_name; chd_compressor * (*m_construct_compressor)(chd_file &, UINT32, bool); chd_decompressor * (*m_construct_decompressor)(chd_file &, UINT32, bool); }; // internal helper functions static const codec_entry *find_in_list(chd_codec_type type); template static chd_compressor *construct_compressor(chd_file &chd, UINT32 hunkbytes, bool lossy) { return new _CompressorClass(chd, hunkbytes, lossy); } template static chd_decompressor *construct_decompressor(chd_file &chd, UINT32 hunkbytes, bool lossy) { return new _DecompressorClass(chd, hunkbytes, lossy); } // the static list static const codec_entry s_codec_list[]; }; // ======================> chd_compressor_group // helper class that wraps several compressors class chd_compressor_group { public: // construction/destruction chd_compressor_group(chd_file &file, chd_codec_type compressor_list[4]); ~chd_compressor_group(); // find the best compressor INT8 find_best_compressor(const UINT8 *src, UINT8 *compressed, UINT32 &complen); private: // internal state UINT32 m_hunkbytes; // number of bytes in a hunk chd_compressor * m_compressor[4]; // array of active codecs dynamic_buffer m_compress_test; // test buffer for compression #if CHDCODEC_VERIFY_COMPRESSION chd_decompressor * m_decompressor[4]; // array of active codecs dynamic_buffer m_decompressed; // verification buffer #endif }; //************************************************************************** // CONSTANTS //************************************************************************** // currently-defined codecs const chd_codec_type CHD_CODEC_NONE = 0; // general codecs const chd_codec_type CHD_CODEC_ZLIB = CHD_MAKE_TAG('z','l','i','b'); const chd_codec_type CHD_CODEC_LZMA = CHD_MAKE_TAG('l','z','m','a'); const chd_codec_type CHD_CODEC_HUFFMAN = CHD_MAKE_TAG('h','u','f','f'); const chd_codec_type CHD_CODEC_FLAC = CHD_MAKE_TAG('f','l','a','c'); // general codecs with CD frontend const chd_codec_type CHD_CODEC_CD_ZLIB = CHD_MAKE_TAG('c','d','z','l'); const chd_codec_type CHD_CODEC_CD_LZMA = CHD_MAKE_TAG('c','d','l','z'); const chd_codec_type CHD_CODEC_CD_FLAC = CHD_MAKE_TAG('c','d','f','l'); // A/V codecs const chd_codec_type CHD_CODEC_AVHUFF = CHD_MAKE_TAG('a','v','h','u'); // A/V codec configuration parameters enum { AVHUFF_CODEC_DECOMPRESS_CONFIG = 1 }; #endif // __CHDCODEC_H__