From 2a61620daee3afbca50839e48448242434220dc9 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 1 Dec 2020 23:34:21 +1000 Subject: [PATCH] dep/libchdr: Sync to upstream (82670d5) --- dep/libchdr/CMakeLists.txt | 18 +- dep/libchdr/LICENSE.txt | 24 + dep/libchdr/README.md | 7 + dep/libchdr/include/libchdr/cdrom.h | 7 +- dep/libchdr/include/libchdr/chd.h | 40 +- dep/libchdr/include/libchdr/chdconfig.h | 10 + dep/libchdr/include/libchdr/coretypes.h | 8 +- dep/libchdr/include/libchdr/flac.h | 2 +- dep/libchdr/include/libchdr/huffman.h | 3 +- dep/libchdr/libchdr.vcxproj | 59 +- dep/libchdr/libchdr.vcxproj.filters | 21 +- .../src/{bitstream.c => libchdr_bitstream.c} | 2 +- dep/libchdr/src/{cdrom.c => libchdr_cdrom.c} | 7 +- dep/libchdr/src/{chd.c => libchdr_chd.c} | 532 +++++++++++------- dep/libchdr/src/{flac.c => libchdr_flac.c} | 3 +- .../src/{huffman.c => libchdr_huffman.c} | 92 ++- dep/libchdr/src/md5.c | 189 ------- dep/libchdr/src/md5.h | 34 -- dep/libchdr/src/sha1.c | 149 ----- dep/libchdr/src/sha1.h | 35 -- 20 files changed, 519 insertions(+), 723 deletions(-) create mode 100644 dep/libchdr/LICENSE.txt create mode 100644 dep/libchdr/README.md create mode 100644 dep/libchdr/include/libchdr/chdconfig.h rename dep/libchdr/src/{bitstream.c => libchdr_bitstream.c} (99%) rename dep/libchdr/src/{cdrom.c => libchdr_cdrom.c} (99%) rename dep/libchdr/src/{chd.c => libchdr_chd.c} (88%) rename dep/libchdr/src/{flac.c => libchdr_flac.c} (99%) rename dep/libchdr/src/{huffman.c => libchdr_huffman.c} (90%) delete mode 100644 dep/libchdr/src/md5.c delete mode 100644 dep/libchdr/src/md5.h delete mode 100644 dep/libchdr/src/sha1.c delete mode 100644 dep/libchdr/src/sha1.h diff --git a/dep/libchdr/CMakeLists.txt b/dep/libchdr/CMakeLists.txt index f858f42fe..cc05b2173 100644 --- a/dep/libchdr/CMakeLists.txt +++ b/dep/libchdr/CMakeLists.txt @@ -2,21 +2,17 @@ add_library(libchdr include/libchdr/bitstream.h include/libchdr/cdrom.h include/libchdr/chd.h + include/libchdr/chdconfig.h include/libchdr/coretypes.h include/libchdr/flac.h include/libchdr/huffman.h - src/bitstream.c - src/cdrom.c - src/chd.c - src/flac.c - src/huffman.c - src/md5.c - src/md5.h - src/sha1.c - src/sha1.h + src/libchdr_bitstream.c + src/libchdr_cdrom.c + src/libchdr_chd.c + src/libchdr_flac.c + src/libchdr_huffman.c ) -target_include_directories(libchdr PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include/libchdr") -target_include_directories(libchdr INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_include_directories(libchdr PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") target_link_libraries(libchdr PRIVATE zlib lzma libFLAC) diff --git a/dep/libchdr/LICENSE.txt b/dep/libchdr/LICENSE.txt new file mode 100644 index 000000000..1c36e5b59 --- /dev/null +++ b/dep/libchdr/LICENSE.txt @@ -0,0 +1,24 @@ +Copyright Romain Tisserand +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/dep/libchdr/README.md b/dep/libchdr/README.md new file mode 100644 index 000000000..940920a53 --- /dev/null +++ b/dep/libchdr/README.md @@ -0,0 +1,7 @@ +# libchdr + +libchdr is a standalone library for reading MAME's CHDv1-v5 formats. + +The code is based off of MAME's old C codebase which read up to CHDv4 with OS-dependent features removed, and CHDv5 support backported from MAME's current C++ codebase. + +libchdr is licensed under the BSD 3-Clause (see [LICENSE.txt](LICENSE.txt)) and uses third party libraries that are each distributed under their own terms (see each library's license in [deps/](deps/)). diff --git a/dep/libchdr/include/libchdr/cdrom.h b/dep/libchdr/include/libchdr/cdrom.h index 65aa18218..816e6a5c4 100644 --- a/dep/libchdr/include/libchdr/cdrom.h +++ b/dep/libchdr/include/libchdr/cdrom.h @@ -14,15 +14,14 @@ #define __CDROM_H__ #include - +#include /*************************************************************************** CONSTANTS ***************************************************************************/ /* tracks are padded to a multiple of this many frames */ -extern const uint32_t CD_TRACK_PADDING; - +#define CD_TRACK_PADDING (4) #define CD_MAX_TRACKS (99) /* AFAIK the theoretical limit */ #define CD_MAX_SECTOR_DATA (2352) #define CD_MAX_SUBCODE_DATA (96) @@ -60,10 +59,12 @@ enum FUNCTION PROTOTYPES ***************************************************************************/ +#ifdef WANT_RAW_DATA_SECTOR /* ECC utilities */ int ecc_verify(const uint8_t *sector); void ecc_generate(uint8_t *sector); void ecc_clear(uint8_t *sector); +#endif diff --git a/dep/libchdr/include/libchdr/chd.h b/dep/libchdr/include/libchdr/chd.h index 83f815880..c9c6b3dd1 100644 --- a/dep/libchdr/include/libchdr/chd.h +++ b/dep/libchdr/include/libchdr/chd.h @@ -46,8 +46,8 @@ extern "C" { #endif -#include "coretypes.h" - +#include +#include /*************************************************************************** @@ -347,6 +347,20 @@ struct _chd_verify_result FUNCTION PROTOTYPES ***************************************************************************/ +#ifdef WIN32 +#ifdef CHD_DLL +#ifdef CHD_DLL_EXPORTS +#define CHD_EXPORT __declspec(dllexport) +#else +#define CHD_EXPORT __declspec(dllimport) +#endif +#else +// Static library. +#define CHD_EXPORT +#endif +#else +#define CHD_EXPORT __attribute__ ((visibility("default"))) +#endif /* ----- CHD file management ----- */ @@ -357,27 +371,27 @@ struct _chd_verify_result /* chd_error chd_create_file(core_file *file, UINT64 logicalbytes, UINT32 hunkbytes, UINT32 compression, chd_file *parent); */ /* open an existing CHD file */ -chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd); -chd_error chd_open_file(core_file* file, int mode, chd_file* parent, chd_file** chd); +CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd); +CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd); /* precache underlying file */ -chd_error chd_precache(chd_file *chd); +CHD_EXPORT chd_error chd_precache(chd_file *chd); /* close a CHD file */ -void chd_close(chd_file *chd); +CHD_EXPORT void chd_close(chd_file *chd); /* return the associated core_file */ -core_file *chd_core_file(chd_file *chd); +CHD_EXPORT core_file *chd_core_file(chd_file *chd); /* return an error string for the given CHD error */ -const char *chd_error_string(chd_error err); +CHD_EXPORT const char *chd_error_string(chd_error err); /* ----- CHD header management ----- */ /* return a pointer to the extracted CHD header data */ -const chd_header *chd_get_header(chd_file *chd); +CHD_EXPORT const chd_header *chd_get_header(chd_file *chd); @@ -385,14 +399,14 @@ const chd_header *chd_get_header(chd_file *chd); /* ----- core data read/write ----- */ /* read one hunk from the CHD file */ -chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer); +CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer); /* ----- metadata management ----- */ /* get indexed metadata of a particular sort */ -chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags); +CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags); @@ -400,10 +414,10 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, /* ----- codec interfaces ----- */ /* set internal codec parameters */ -chd_error chd_codec_config(chd_file *chd, int param, void *config); +CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config); /* return a string description of a codec */ -const char *chd_get_codec_name(UINT32 codec); +CHD_EXPORT const char *chd_get_codec_name(UINT32 codec); #ifdef __cplusplus } diff --git a/dep/libchdr/include/libchdr/chdconfig.h b/dep/libchdr/include/libchdr/chdconfig.h new file mode 100644 index 000000000..752038b48 --- /dev/null +++ b/dep/libchdr/include/libchdr/chdconfig.h @@ -0,0 +1,10 @@ +#ifndef __CHDCONFIG_H__ +#define __CHDCONFIG_H__ + +/* Configure CHDR features here */ +#define WANT_RAW_DATA_SECTOR 1 +#define WANT_SUBCODE 1 +#define NEED_CACHE_HUNK 1 +#define VERIFY_BLOCK_CRC 1 + +#endif diff --git a/dep/libchdr/include/libchdr/coretypes.h b/dep/libchdr/include/libchdr/coretypes.h index 6c4b40e4d..fbe2d7d63 100644 --- a/dep/libchdr/include/libchdr/coretypes.h +++ b/dep/libchdr/include/libchdr/coretypes.h @@ -4,9 +4,8 @@ #include #include -#ifdef _MSC_VER -#include -typedef SSIZE_T ssize_t; +#ifdef __LIBRETRO__ +#include #endif #define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0])) @@ -29,9 +28,10 @@ typedef int8_t INT8; #define core_ftell ftell static size_t core_fsize(core_file *f) { + long rv; long p = ftell(f); fseek(f, 0, SEEK_END); - long rv = ftell(f); + rv = ftell(f); fseek(f, p, SEEK_SET); return rv; } diff --git a/dep/libchdr/include/libchdr/flac.h b/dep/libchdr/include/libchdr/flac.h index 5a3bf2d9c..6cf011f6f 100644 --- a/dep/libchdr/include/libchdr/flac.h +++ b/dep/libchdr/include/libchdr/flac.h @@ -14,7 +14,7 @@ #define __FLAC_H__ #include -#include "FLAC/all.h" +#include /*************************************************************************** * TYPE DEFINITIONS diff --git a/dep/libchdr/include/libchdr/huffman.h b/dep/libchdr/include/libchdr/huffman.h index 8bcc45acd..6c9f51136 100644 --- a/dep/libchdr/include/libchdr/huffman.h +++ b/dep/libchdr/include/libchdr/huffman.h @@ -13,7 +13,7 @@ #ifndef __HUFFMAN_H__ #define __HUFFMAN_H__ -#include "bitstream.h" +#include /*************************************************************************** @@ -73,6 +73,7 @@ struct huffman_decoder /* ======================> huffman_decoder */ struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits); +void delete_huffman_decoder(struct huffman_decoder* decoder); /* single item operations */ uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* bitbuf); diff --git a/dep/libchdr/libchdr.vcxproj b/dep/libchdr/libchdr.vcxproj index b27045f48..8f1d29781 100644 --- a/dep/libchdr/libchdr.vcxproj +++ b/dep/libchdr/libchdr.vcxproj @@ -50,25 +50,6 @@ x64 - - - - - - - - - - - - - - - - - - - {97cbd3cb-cbc7-4d52-abde-f0ae7b794a5d} @@ -80,6 +61,22 @@ {7ff9fdb9-d504-47db-a16a-b08071999620} + + + + + + + + + + + + + + + + {425D6C99-D1C8-43C2-B8AC-4D7B1D941017} Win32Proj @@ -292,7 +289,7 @@ FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -312,7 +309,7 @@ FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -332,7 +329,7 @@ FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -352,7 +349,7 @@ FLAC__NO_DLL;_ITERATOR_DEBUG_LEVEL=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) Default false stdcpp17 @@ -375,7 +372,7 @@ FLAC__NO_DLL;_ITERATOR_DEBUG_LEVEL=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) Default false stdcpp17 @@ -398,7 +395,7 @@ FLAC__NO_DLL;_ITERATOR_DEBUG_LEVEL=1;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) true ProgramDatabase - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) Default false stdcpp17 @@ -420,7 +417,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -441,7 +438,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) true stdcpp17 true @@ -463,7 +460,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -484,7 +481,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) false stdcpp17 true @@ -505,7 +502,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) true stdcpp17 true @@ -527,7 +524,7 @@ MaxSpeed true FLAC__NO_DLL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include\libchdr;%(AdditionalIncludeDirectories) + $(SolutionDir)dep\zlib\include;$(SolutionDir)dep\lzma\include;$(SolutionDir)dep\libFLAC\include;$(ProjectDir)include;%(AdditionalIncludeDirectories) true stdcpp17 true diff --git a/dep/libchdr/libchdr.vcxproj.filters b/dep/libchdr/libchdr.vcxproj.filters index dc5a4e235..5bcf9aa01 100644 --- a/dep/libchdr/libchdr.vcxproj.filters +++ b/dep/libchdr/libchdr.vcxproj.filters @@ -1,22 +1,19 @@  + + + + + + + + + - - - - - - - - - - - - \ No newline at end of file diff --git a/dep/libchdr/src/bitstream.c b/dep/libchdr/src/libchdr_bitstream.c similarity index 99% rename from dep/libchdr/src/bitstream.c rename to dep/libchdr/src/libchdr_bitstream.c index 3f61c938c..c82a67ddc 100644 --- a/dep/libchdr/src/bitstream.c +++ b/dep/libchdr/src/libchdr_bitstream.c @@ -8,8 +8,8 @@ ***************************************************************************/ -#include "bitstream.h" #include +#include /*************************************************************************** * INLINE FUNCTIONS diff --git a/dep/libchdr/src/cdrom.c b/dep/libchdr/src/libchdr_cdrom.c similarity index 99% rename from dep/libchdr/src/cdrom.c rename to dep/libchdr/src/libchdr_cdrom.c index 74a0786d5..58be0155e 100644 --- a/dep/libchdr/src/cdrom.c +++ b/dep/libchdr/src/libchdr_cdrom.c @@ -15,11 +15,12 @@ schemes will differ after track 1! ***************************************************************************/ - #include #include -#include "cdrom.h" +#include + +#ifdef WANT_RAW_DATA_SECTOR /*************************************************************************** DEBUGGING @@ -410,3 +411,5 @@ void ecc_clear(uint8_t *sector) memset(§or[ECC_P_OFFSET], 0, 2 * ECC_P_NUM_BYTES); memset(§or[ECC_Q_OFFSET], 0, 2 * ECC_Q_NUM_BYTES); } + +#endif /* WANT_RAW_DATA_SECTOR */ diff --git a/dep/libchdr/src/chd.c b/dep/libchdr/src/libchdr_chd.c similarity index 88% rename from dep/libchdr/src/chd.c rename to dep/libchdr/src/libchdr_chd.c index b9e12e359..6a058c6a6 100644 --- a/dep/libchdr/src/chd.c +++ b/dep/libchdr/src/libchdr_chd.c @@ -42,19 +42,23 @@ #include #include #include -#include "chd.h" -#include "cdrom.h" -#include "flac.h" -#include "huffman.h" + +#include +#include +#include +#include + #include "LzmaEnc.h" #include "LzmaDec.h" -#include "md5.h" -#include "sha1.h" #include "zlib.h" +#undef TRUE +#undef FALSE #define TRUE 1 #define FALSE 0 +#undef MAX +#undef MIN #define MAX(x, y) (((x) > (y)) ? (x) : (y)) #define MIN(x, y) (((x) < (y)) ? (x) : (y)) @@ -74,7 +78,6 @@ #define MAP_ENTRY_SIZE 16 /* V3 and later */ #define OLD_MAP_ENTRY_SIZE 8 /* V1-V2 */ #define METADATA_HEADER_SIZE 16 /* metadata header size */ -#define CRCMAP_HASH_SIZE 4095 /* number of CRC hashtable entries */ #define MAP_ENTRY_FLAG_TYPE_MASK 0x0f /* what type of hunk */ #define MAP_ENTRY_FLAG_NO_CRC 0x10 /* no CRC is present */ @@ -88,7 +91,9 @@ #define NO_MATCH (~0) +#ifdef WANT_RAW_DATA_SECTOR static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 }; +#endif /* V3-V4 entry types */ enum @@ -171,14 +176,6 @@ struct _map_entry UINT8 flags; /* misc flags */ }; -/* simple linked-list of hunks used for our CRC map */ -typedef struct _crcmap_entry crcmap_entry; -struct _crcmap_entry -{ - UINT32 hunknum; /* hunk number */ - crcmap_entry * next; /* next entry in list */ -}; - /* a single metadata entry */ typedef struct _metadata_entry metadata_entry; struct _metadata_entry @@ -197,6 +194,7 @@ typedef struct _zlib_allocator zlib_allocator; struct _zlib_allocator { UINT32 * allocptr[MAX_ZLIB_ALLOCS]; + UINT32 * allocptr2[MAX_ZLIB_ALLOCS]; }; typedef struct _zlib_codec_data zlib_codec_data; @@ -216,6 +214,7 @@ struct _lzma_allocator void (*Free)(void *p, void *address); /* address can be 0 */ void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */ uint32_t* allocptr[MAX_LZMA_ALLOCS]; + uint32_t* allocptr2[MAX_LZMA_ALLOCS]; }; typedef struct _lzma_codec_data lzma_codec_data; @@ -230,7 +229,9 @@ typedef struct _cdzl_codec_data cdzl_codec_data; struct _cdzl_codec_data { /* internal state */ zlib_codec_data base_decompressor; +#ifdef WANT_SUBCODE zlib_codec_data subcode_decompressor; +#endif uint8_t* buffer; }; @@ -239,7 +240,9 @@ typedef struct _cdlz_codec_data cdlz_codec_data; struct _cdlz_codec_data { /* internal state */ lzma_codec_data base_decompressor; +#ifdef WANT_SUBCODE zlib_codec_data subcode_decompressor; +#endif uint8_t* buffer; }; @@ -249,8 +252,9 @@ struct _cdfl_codec_data { /* internal state */ int swap_endian; flac_decoder decoder; - z_stream inflater; - zlib_allocator allocator; +#ifdef WANT_SUBCODE + zlib_codec_data subcode_decompressor; +#endif uint8_t* buffer; }; @@ -267,11 +271,13 @@ struct _chd_file map_entry * map; /* array of map entries */ +#ifdef NEED_CACHE_HUNK UINT8 * cache; /* hunk cache pointer */ UINT32 cachehunk; /* index of currently cached hunk */ UINT8 * compare; /* hunk compare pointer */ UINT32 comparehunk; /* index of current compare data */ +#endif UINT8 * compressed; /* pointer to buffer for compressed data */ const codec_interface * codecintf[4]; /* interface to the codec */ @@ -281,35 +287,13 @@ struct _chd_file cdlz_codec_data cdlz_codec_data; /* cdlz codec data */ cdfl_codec_data cdfl_codec_data; /* cdfl codec data */ - crcmap_entry * crcmap; /* CRC map entries */ - crcmap_entry * crcfree; /* free list CRC entries */ - crcmap_entry ** crctable; /* table of CRC entries */ - +#ifdef NEED_CACHE_HUNK UINT32 maxhunk; /* maximum hunk accessed */ - - UINT8 compressing; /* are we compressing? */ - MD5_CTX compmd5; /* running MD5 during compression */ - SHA1_CTX compsha1; /* running SHA1 during compression */ - UINT32 comphunk; /* next hunk we will compress */ - - UINT8 verifying; /* are we verifying? */ - MD5_CTX vermd5; /* running MD5 during verification */ - SHA1_CTX versha1; /* running SHA1 during verification */ - UINT32 verhunk; /* next hunk we will verify */ - - UINT32 async_hunknum; /* hunk index for asynchronous operations */ - void * async_buffer; /* buffer pointer for asynchronous operations */ +#endif UINT8 * file_cache; /* cache of underlying file */ }; -/* a single metadata hash entry */ -typedef struct _metadata_hash metadata_hash; -struct _metadata_hash -{ - UINT8 tag[4]; /* tag of the metadata in big-endian */ - UINT8 sha1[CHD_SHA1_BYTES]; /* hash */ -}; /*************************************************************************** GLOBAL VARIABLES @@ -327,7 +311,9 @@ static chd_error header_validate(const chd_header *header); static chd_error header_read(chd_file *chd, chd_header *header); /* internal hunk read/write */ +#ifdef NEED_CACHE_HUNK static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum); +#endif static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest); /* internal map access */ @@ -369,20 +355,21 @@ static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t *************************************************************************** */ -void *lzma_fast_alloc(void *p, size_t size); -void lzma_fast_free(void *p, void *address); +static void *lzma_fast_alloc(void *p, size_t size); +static void lzma_fast_free(void *p, void *address); /*------------------------------------------------- * lzma_allocator_init *------------------------------------------------- */ -void lzma_allocator_init(void* p) +static void lzma_allocator_init(void* p) { lzma_allocator *codec = (lzma_allocator *)(p); /* reset pointer list */ memset(codec->allocptr, 0, sizeof(codec->allocptr)); + memset(codec->allocptr2, 0, sizeof(codec->allocptr2)); codec->Alloc = lzma_fast_alloc; codec->Free = lzma_fast_free; } @@ -392,12 +379,13 @@ void lzma_allocator_init(void* p) *------------------------------------------------- */ -void lzma_allocator_free(void* p ) +static void lzma_allocator_free(void* p ) { + int i; lzma_allocator *codec = (lzma_allocator *)(p); /* free our memory */ - for (int i = 0 ; i < MAX_LZMA_ALLOCS ; i++) + for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++) { if (codec->allocptr[i] != NULL) free(codec->allocptr[i]); @@ -410,41 +398,58 @@ void lzma_allocator_free(void* p ) *------------------------------------------------- */ -void *lzma_fast_alloc(void *p, size_t size) +/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */ +#define LZMA_MIN_ALIGNMENT_BITS 512 +#define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8) + +static void *lzma_fast_alloc(void *p, size_t size) { + int scan; + uint32_t *addr = NULL; lzma_allocator *codec = (lzma_allocator *)(p); + uintptr_t vaddr = 0; /* compute the size, rounding to the nearest 1k */ size = (size + 0x3ff) & ~0x3ff; /* reuse a hunk if we can */ - for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++) + for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) { uint32_t *ptr = codec->allocptr[scan]; if (ptr != NULL && size == *ptr) { /* set the low bit of the size so we don't match next time */ *ptr |= 1; - return ptr + 1; + + /* return aligned address of the block */ + return codec->allocptr2[scan]; } } /* alloc a new one and put it into the list */ - uint32_t *addr = (uint32_t *)malloc(sizeof(uint8_t) * size + sizeof(uintptr_t)); + addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES); if (addr==NULL) return NULL; for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++) { if (codec->allocptr[scan] == NULL) { + /* store block address */ codec->allocptr[scan] = addr; + + /* compute aligned address, store it */ + vaddr = (uintptr_t)addr; + vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1)); + codec->allocptr2[scan] = (uint32_t*)vaddr; break; } } /* set the low bit of the size so we don't match next time */ *addr = size | 1; - return addr + (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2); + + /* return aligned address */ + return (void*)vaddr; } /*------------------------------------------------- @@ -453,21 +458,25 @@ void *lzma_fast_alloc(void *p, size_t size) *------------------------------------------------- */ -void lzma_fast_free(void *p, void *address) +static void lzma_fast_free(void *p, void *address) { + int scan; + uint32_t *ptr = NULL; + lzma_allocator *codec = NULL; + if (address == NULL) return; - lzma_allocator *codec = (lzma_allocator *)(p); + codec = (lzma_allocator *)(p); /* find the hunk */ - uint32_t *ptr = (uint32_t *)(address) - 1; - for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++) + ptr = (uint32_t *)address; + for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++) { - if (ptr == codec->allocptr[scan]) + if (ptr == codec->allocptr2[scan]) { /* clear the low bit of the size to allow matches */ - *ptr &= ~1; + *codec->allocptr[scan] &= ~1; return; } } @@ -483,8 +492,13 @@ void lzma_fast_free(void *p, void *address) *------------------------------------------------- */ -chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) +static chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) { + CLzmaEncHandle enc; + CLzmaEncProps encoder_props; + Byte decoder_props[LZMA_PROPS_SIZE]; + SizeT props_size; + lzma_allocator* alloc; lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; /* construct the decoder */ @@ -496,16 +510,15 @@ chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) * needs to be changed so the encoder properties are written to the file. * configure the properties like the compressor did */ - CLzmaEncProps encoder_props; LzmaEncProps_Init(&encoder_props); encoder_props.level = 9; encoder_props.reduceSize = hunkbytes; LzmaEncProps_Normalize(&encoder_props); /* convert to decoder properties */ - lzma_allocator* alloc = &lzma_codec->allocator; + alloc = &lzma_codec->allocator; lzma_allocator_init(alloc); - CLzmaEncHandle enc = LzmaEnc_Create((ISzAlloc*)alloc); + enc = LzmaEnc_Create((ISzAlloc*)alloc); if (!enc) return CHDERR_DECOMPRESSION_ERROR; if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK) @@ -513,8 +526,7 @@ chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc); return CHDERR_DECOMPRESSION_ERROR; } - Byte decoder_props[LZMA_PROPS_SIZE]; - SizeT props_size = sizeof(decoder_props); + props_size = sizeof(decoder_props); if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK) { LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc); @@ -535,7 +547,7 @@ chd_error lzma_codec_init(void* codec, uint32_t hunkbytes) *------------------------------------------------- */ -void lzma_codec_free(void* codec) +static void lzma_codec_free(void* codec) { lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; @@ -550,33 +562,45 @@ void lzma_codec_free(void* codec) *------------------------------------------------- */ -chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +static chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { + ELzmaStatus status; + SRes res; + SizeT consumedlen, decodedlen; /* initialize */ lzma_codec_data* lzma_codec = (lzma_codec_data*) codec; LzmaDec_Init(&lzma_codec->decoder); /* decode */ - SizeT consumedlen = complen; - SizeT decodedlen = destlen; - ELzmaStatus status; - SRes res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status); + consumedlen = complen; + decodedlen = destlen; + res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status); if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen) return CHDERR_DECOMPRESSION_ERROR; return CHDERR_NONE; } /* cdlz */ -chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes) +static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes) { + chd_error ret; cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; /* allocate buffer */ cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdlz->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; /* make sure the CHD's hunk size is an even multiple of the frame size */ - lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA); + ret = lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; + +#ifdef WANT_SUBCODE + ret = zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA); + if (ret != CHDERR_NONE) + return ret; +#endif if (hunkbytes % CD_FRAME_SIZE != 0) return CHDERR_CODEC_ERROR; @@ -584,17 +608,19 @@ chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes) return CHDERR_NONE; } -void cdlz_codec_free(void* codec) +static void cdlz_codec_free(void* codec) { cdlz_codec_data* cdlz = (cdlz_codec_data*) codec; free(cdlz->buffer); lzma_codec_free(&cdlz->base_decompressor); +#ifdef WANT_SUBCODE zlib_codec_free(&cdlz->subcode_decompressor); +#endif } -chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { - uint8_t *sector; + uint32_t framenum; cdlz_codec_data* cdlz = (cdlz_codec_data*)codec; /* determine header bytes */ @@ -610,14 +636,21 @@ chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t comple /* reset and decode */ lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE zlib_codec_decompress(&cdlz->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdlz->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); +#endif /* reassemble the data */ - for (uint32_t framenum = 0; framenum < frames; framenum++) + for (framenum = 0; framenum < frames; framenum++) { - memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); - memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdlz->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); + uint8_t *sector; + memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdlz->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif + +#ifdef WANT_RAW_DATA_SECTOR /* reconstitute the ECC data and sync header */ sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) @@ -625,38 +658,52 @@ chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t comple memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); ecc_generate(sector); } +#endif } return CHDERR_NONE; } /* cdzl */ -chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes) +static chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes) { + chd_error ret; cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; /* make sure the CHD's hunk size is an even multiple of the frame size */ - zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); - zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA); - - cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); if (hunkbytes % CD_FRAME_SIZE != 0) return CHDERR_CODEC_ERROR; + cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdzl->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; + + ret = zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; + +#ifdef WANT_SUBCODE + ret = zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA); + if (ret != CHDERR_NONE) + return ret; +#endif + return CHDERR_NONE; } -void cdzl_codec_free(void *codec) +static void cdzl_codec_free(void *codec) { cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; zlib_codec_free(&cdzl->base_decompressor); +#ifdef WANT_SUBCODE zlib_codec_free(&cdzl->subcode_decompressor); +#endif free(cdzl->buffer); } -chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { - uint8_t *sector; + uint32_t framenum; cdzl_codec_data* cdzl = (cdzl_codec_data*)codec; /* determine header bytes */ @@ -672,14 +719,21 @@ chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple /* reset and decode */ zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE zlib_codec_decompress(&cdzl->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdzl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); +#endif /* reassemble the data */ - for (uint32_t framenum = 0; framenum < frames; framenum++) + for (framenum = 0; framenum < frames; framenum++) { - memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); - memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); + uint8_t *sector; + memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE + memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif + +#ifdef WANT_RAW_DATA_SECTOR /* reconstitute the ECC data and sync header */ sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE]; if ((src[framenum / 8] & (1 << (framenum % 8))) != 0) @@ -687,6 +741,7 @@ chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header)); ecc_generate(sector); } +#endif } return CHDERR_NONE; } @@ -711,56 +766,60 @@ static uint32_t cdfl_codec_blocksize(uint32_t bytes) return hunkbytes; } -chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) +static chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) { +#ifdef WANT_SUBCODE + chd_error ret; +#endif + uint16_t native_endian = 0; cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; - cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); - /* make sure the CHD's hunk size is an even multiple of the frame size */ if (hunkbytes % CD_FRAME_SIZE != 0) return CHDERR_CODEC_ERROR; + cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); + if (cdfl->buffer == NULL) + return CHDERR_OUT_OF_MEMORY; + /* determine whether we want native or swapped samples */ - uint16_t native_endian = 0; *(uint8_t *)(&native_endian) = 1; cdfl->swap_endian = (native_endian & 1); - /* init the inflater */ - cdfl->inflater.next_in = (Bytef *)cdfl; /* bogus, but that's ok */ - cdfl->inflater.avail_in = 0; -#if 0 - cdfl->allocator.install(cdfl->inflater); +#ifdef WANT_SUBCODE + /* init zlib inflater */ + ret = zlib_codec_init(&cdfl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA); + if (ret != CHDERR_NONE) + return ret; #endif - cdfl->inflater.zalloc = zlib_fast_alloc; - cdfl->inflater.zfree = zlib_fast_free; - cdfl->inflater.opaque = &cdfl->allocator; - int zerr = inflateInit2(&cdfl->inflater, -MAX_WBITS); - - /* convert errors */ - if (zerr == Z_MEM_ERROR) - return CHDERR_OUT_OF_MEMORY; - else if (zerr != Z_OK) - return CHDERR_CODEC_ERROR; /* flac decoder init */ flac_decoder_init(&cdfl->decoder); + if (cdfl->decoder.decoder == NULL) + return CHDERR_OUT_OF_MEMORY; + return CHDERR_NONE; } -void cdfl_codec_free(void *codec) +static void cdfl_codec_free(void *codec) { cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; - free(cdfl->buffer); - inflateEnd(&cdfl->inflater); flac_decoder_free(&cdfl->decoder); - - /* free our fast memory */ - zlib_allocator_free(&cdfl->allocator); +#ifdef WANT_SUBCODE + zlib_codec_free(&cdfl->subcode_decompressor); +#endif + if (cdfl->buffer) + free(cdfl->buffer); } -chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) +static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { + uint32_t framenum; + uint8_t *buffer; +#ifdef WANT_SUBCODE + uint32_t offset; + chd_error ret; +#endif cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; /* reset and decode */ @@ -768,34 +827,27 @@ chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen)) return CHDERR_DECOMPRESSION_ERROR; - uint8_t *buffer = &cdfl->buffer[0]; + buffer = &cdfl->buffer[0]; if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian)) return CHDERR_DECOMPRESSION_ERROR; +#ifdef WANT_SUBCODE /* inflate the subcode data */ - uint32_t offset = flac_decoder_finish(&cdfl->decoder); - cdfl->inflater.next_in = (Bytef *)(src + offset); - cdfl->inflater.avail_in = complen - offset; - cdfl->inflater.total_in = 0; - cdfl->inflater.next_out = &cdfl->buffer[frames * CD_MAX_SECTOR_DATA]; - cdfl->inflater.avail_out = frames * CD_MAX_SUBCODE_DATA; - cdfl->inflater.total_out = 0; - int zerr = inflateReset(&cdfl->inflater); - if (zerr != Z_OK) - return CHDERR_DECOMPRESSION_ERROR; - - /* do it */ - zerr = inflate(&cdfl->inflater, Z_FINISH); - if (zerr != Z_STREAM_END) - return CHDERR_DECOMPRESSION_ERROR; - if (cdfl->inflater.total_out != frames * CD_MAX_SUBCODE_DATA) - return CHDERR_DECOMPRESSION_ERROR; + offset = flac_decoder_finish(&cdfl->decoder); + ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA); + if (ret != CHDERR_NONE) + return ret; +#else + flac_decoder_finish(&cdfl->decoder); +#endif /* reassemble the data */ - for (uint32_t framenum = 0; framenum < frames; framenum++) + for (framenum = 0; framenum < frames; framenum++) { memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA); +#ifdef WANT_SUBCODE memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdfl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA); +#endif } return CHDERR_NONE; @@ -1098,8 +1150,7 @@ uint16_t crc16(const void *data, uint32_t length) /*------------------------------------------------- compressed - test if CHD file is compressed +-------------------------------------------------*/ - -static inline int compressed(chd_header* header) { +static inline int chd_compressed(chd_header* header) { return header->compression[0] != CHD_CODEC_NONE; } @@ -1109,42 +1160,70 @@ static inline int compressed(chd_header* header) { static chd_error decompress_v5_map(chd_file* chd, chd_header* header) { + int result = 0; + int hunknum; + int repcount = 0; + uint8_t lastcomp = 0; + uint32_t last_self = 0; + uint64_t last_parent = 0; + struct bitstream* bitbuf; + uint32_t mapbytes; + uint64_t firstoffs; + uint16_t mapcrc; + uint8_t lengthbits; + uint8_t selfbits; + uint8_t parentbits; + uint8_t *compressed_ptr; + uint8_t rawbuf[16]; + struct huffman_decoder* decoder; + enum huffman_error err; + uint64_t curoffset; int rawmapsize = map_size_v5(header); - if (!compressed(header)) + if (!chd_compressed(header)) { header->rawmap = (uint8_t*)malloc(rawmapsize); core_fseek(chd->file, header->mapoffset, SEEK_SET); - core_fread(chd->file, header->rawmap, rawmapsize); + result = core_fread(chd->file, header->rawmap, rawmapsize); return CHDERR_NONE; } /* read the reader */ - uint8_t rawbuf[16]; core_fseek(chd->file, header->mapoffset, SEEK_SET); - core_fread(chd->file, rawbuf, sizeof(rawbuf)); - uint32_t const mapbytes = get_bigendian_uint32(&rawbuf[0]); - uint64_t const firstoffs = get_bigendian_uint48(&rawbuf[4]); - uint16_t const mapcrc = get_bigendian_uint16(&rawbuf[10]); - uint8_t const lengthbits = rawbuf[12]; - uint8_t const selfbits = rawbuf[13]; - uint8_t const parentbits = rawbuf[14]; + result = core_fread(chd->file, rawbuf, sizeof(rawbuf)); + mapbytes = get_bigendian_uint32(&rawbuf[0]); + firstoffs = get_bigendian_uint48(&rawbuf[4]); + mapcrc = get_bigendian_uint16(&rawbuf[10]); + lengthbits = rawbuf[12]; + selfbits = rawbuf[13]; + parentbits = rawbuf[14]; /* now read the map */ - uint8_t* compressed = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes); + compressed_ptr = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes); 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); + result = core_fread(chd->file, compressed_ptr, mapbytes); + bitbuf = create_bitstream(compressed_ptr, sizeof(uint8_t) * mapbytes); header->rawmap = (uint8_t*)malloc(rawmapsize); /* first decode the compression types */ - struct huffman_decoder* decoder = create_huffman_decoder(16, 8); - enum huffman_error err = huffman_import_tree_rle(decoder, bitbuf); + decoder = create_huffman_decoder(16, 8); + if (decoder == NULL) + { + free(compressed_ptr); + free(bitbuf); + return CHDERR_OUT_OF_MEMORY; + } + + err = huffman_import_tree_rle(decoder, bitbuf); if (err != HUFFERR_NONE) + { + free(compressed_ptr); + free(bitbuf); + delete_huffman_decoder(decoder); return CHDERR_DECOMPRESSION_ERROR; - uint8_t lastcomp = 0; - int repcount = 0; - for (int hunknum = 0; hunknum < header->hunkcount; hunknum++) + } + + for (hunknum = 0; hunknum < header->hunkcount; hunknum++) { uint8_t *rawmap = header->rawmap + (hunknum * 12); if (repcount > 0) @@ -1162,10 +1241,8 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header) } /* then iterate through the hunks and extract the needed data */ - uint64_t curoffset = firstoffs; - uint32_t last_self = 0; - uint64_t last_parent = 0; - for (int hunknum = 0; hunknum < header->hunkcount; hunknum++) + curoffset = firstoffs; + for (hunknum = 0; hunknum < header->hunkcount; hunknum++) { uint8_t *rawmap = header->rawmap + (hunknum * 12); uint64_t offset = curoffset; @@ -1226,11 +1303,10 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header) put_bigendian_uint16(&rawmap[10], crc); } - free(compressed); + /* free memory */ + free(compressed_ptr); free(bitbuf); - free(decoder->lookup); - free(decoder->huffnode); - free(decoder); + delete_huffman_decoder(decoder); /* verify the final CRC */ if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc) @@ -1265,7 +1341,7 @@ static inline void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 h chd_open_file - open a CHD file for access -------------------------------------------------*/ -chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd) +CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd) { chd_file *newchd = NULL; chd_error err; @@ -1330,6 +1406,8 @@ 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 { @@ -1338,7 +1416,7 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** if (err != CHDERR_NONE) EARLY_EXIT(err); - +#ifdef NEED_CACHE_HUNK /* allocate and init the hunk cache */ newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes); newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes); @@ -1346,6 +1424,7 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY); newchd->cachehunk = ~0; newchd->comparehunk = ~0; +#endif /* allocate the temporary compressed buffer */ newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes); @@ -1377,10 +1456,12 @@ chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file ** } else { + int decompnum; /* verify the compression types and initialize the codecs */ - for (int decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++) + for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++) { - for (int i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++) + int i; + for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++) { if (codec_interfaces[i].compression == newchd->header.compression[decompnum]) { @@ -1440,9 +1521,13 @@ cleanup: memory -------------------------------------------------*/ -chd_error chd_precache(chd_file *chd) +CHD_EXPORT chd_error chd_precache(chd_file *chd) { +#ifdef _MSC_VER + size_t size, count; +#else ssize_t size, count; +#endif if (chd->file_cache == NULL) { @@ -1471,11 +1556,10 @@ chd_error chd_precache(chd_file *chd) filename -------------------------------------------------*/ -chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd) +CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd) { chd_error err; core_file *file = NULL; - UINT32 openflags; /* choose the proper mode */ switch(mode) @@ -1514,7 +1598,7 @@ cleanup: chd_close - close a CHD file for access -------------------------------------------------*/ -void chd_close(chd_file *chd) +CHD_EXPORT void chd_close(chd_file *chd) { /* punt if NULL or invalid */ if (chd == NULL || chd->cookie != COOKIE_VALUE) @@ -1528,8 +1612,9 @@ void chd_close(chd_file *chd) } else { + int i; /* Free the codecs */ - for (int i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++) + for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++) { void* codec = NULL; @@ -1570,30 +1655,25 @@ void chd_close(chd_file *chd) if (chd->compressed != NULL) free(chd->compressed); +#ifdef NEED_CACHE_HUNK /* free the hunk cache and compare data */ if (chd->compare != NULL) free(chd->compare); if (chd->cache != NULL) free(chd->cache); +#endif /* free the hunk map */ if (chd->map != NULL) free(chd->map); - /* free the CRC table */ - if (chd->crctable != NULL) - free(chd->crctable); - - /* free the CRC map */ - if (chd->crcmap != NULL) - free(chd->crcmap); - /* close the file */ if (chd->owns_file && chd->file != NULL) core_fclose(chd->file); +#ifdef NEED_CACHE_HUNK if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks); - +#endif if (chd->file_cache) free(chd->file_cache); @@ -1606,7 +1686,7 @@ void chd_close(chd_file *chd) core_file -------------------------------------------------*/ -core_file *chd_core_file(chd_file *chd) +CHD_EXPORT core_file *chd_core_file(chd_file *chd) { return chd->file; } @@ -1616,7 +1696,7 @@ core_file *chd_core_file(chd_file *chd) the given CHD error -------------------------------------------------*/ -const char *chd_error_string(chd_error err) +CHD_EXPORT const char *chd_error_string(chd_error err) { switch (err) { @@ -1661,7 +1741,7 @@ const char *chd_error_string(chd_error err) extracted header data -------------------------------------------------*/ -const chd_header *chd_get_header(chd_file *chd) +CHD_EXPORT const chd_header *chd_get_header(chd_file *chd) { /* punt if NULL or invalid */ if (chd == NULL || chd->cookie != COOKIE_VALUE) @@ -1679,7 +1759,7 @@ const chd_header *chd_get_header(chd_file *chd) file -------------------------------------------------*/ -chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer) +CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer) { /* punt if NULL or invalid */ if (chd == NULL || chd->cookie != COOKIE_VALUE) @@ -1702,7 +1782,7 @@ chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer) of the given type -------------------------------------------------*/ -chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags) +CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags) { metadata_entry metaentry; chd_error err; @@ -1761,7 +1841,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, parameters -------------------------------------------------*/ -chd_error chd_codec_config(chd_file *chd, int param, void *config) +CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config) { return CHDERR_INVALID_PARAMETER; } @@ -1771,7 +1851,7 @@ chd_error chd_codec_config(chd_file *chd, int param, void *config) particular codec -------------------------------------------------*/ -const char *chd_get_codec_name(UINT32 codec) +CHD_EXPORT const char *chd_get_codec_name(UINT32 codec) { return "Unknown"; } @@ -1990,7 +2070,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 = compressed(header) ? 12 : 4; + header->mapentrybytes = chd_compressed(header) ? 12 : 4; /* hack */ header->totalhunks = header->hunkcount; @@ -2017,7 +2097,11 @@ static chd_error header_read(chd_file *chd, chd_header *header) static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size) { +#ifdef _MSC_VER + size_t bytes; +#else ssize_t bytes; +#endif if (chd->file_cache != NULL) { return chd->file_cache + offset; @@ -2039,7 +2123,11 @@ static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size) static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest) { - ssize_t bytes; +#ifdef _MSC_VER + size_t bytes; +#else + ssize_t bytes; +#endif if (chd->file_cache != NULL) { memcpy(dest, chd->file_cache + offset, size); @@ -2054,6 +2142,7 @@ static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t siz return CHDERR_NONE; } +#ifdef NEED_CACHE_HUNK /*------------------------------------------------- hunk_read_into_cache - read a hunk into the CHD's hunk cache @@ -2081,6 +2170,7 @@ static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum) chd->cachehunk = hunknum; return CHDERR_NONE; } +#endif /*------------------------------------------------- hunk_read_into_memory - read a hunk into @@ -2099,6 +2189,9 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des if (hunknum >= chd->header.totalhunks) return CHDERR_HUNK_OUT_OF_RANGE; + if (dest == NULL) + return CHDERR_INVALID_PARAMETER; + if (chd->header.version < 5) { map_entry *entry = &chd->map[hunknum]; @@ -2110,6 +2203,8 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des { /* compressed data */ case V34_MAP_ENTRY_TYPE_COMPRESSED: + { + void *codec = NULL; /* read it into the decompression buffer */ compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length); @@ -2118,12 +2213,13 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des /* now decompress using the codec */ err = CHDERR_NONE; - void* codec = &chd->zlib_codec_data; + codec = &chd->zlib_codec_data; if (chd->codecintf[0]->decompress != NULL) err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes); if (err != CHDERR_NONE) return err; break; + } /* uncompressed data */ case V34_MAP_ENTRY_TYPE_UNCOMPRESSED: @@ -2141,8 +2237,10 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des /* self-referenced data */ case V34_MAP_ENTRY_TYPE_SELF_HUNK: +#ifdef NEED_CACHE_HUNK if (chd->cachehunk == entry->offset && dest == chd->cache) break; +#endif return hunk_read_into_memory(chd, entry->offset, dest); /* parent-referenced data */ @@ -2156,20 +2254,23 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des } else { + void* codec = NULL; /* get a pointer to the map entry */ uint64_t blockoffs; uint32_t blocklen; +#ifdef VERIFY_BLOCK_CRC uint16_t blockcrc; +#endif uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum]; UINT8* compressed_bytes; /* uncompressed case */ - if (!compressed(&chd->header)) + if (!chd_compressed(&chd->header)) { 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); + int result = core_fread(chd->file, dest, chd->header.hunkbytes); /* TODO else if (m_parent_missing) throw CHDERR_REQUIRES_PARENT; */ @@ -2180,13 +2281,17 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des } else { memset(dest, 0, chd->header.hunkbytes); } + + return CHDERR_NONE; } /* compressed case */ blocklen = get_bigendian_uint24(&rawmap[1]); blockoffs = get_bigendian_uint48(&rawmap[4]); +#ifdef VERIFY_BLOCK_CRC blockcrc = get_bigendian_uint16(&rawmap[10]); - void* codec = NULL; +#endif + codec = NULL; switch (rawmap[0]) { case COMPRESSION_TYPE_0: @@ -2215,18 +2320,24 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des break; } if (codec==NULL) + return CHDERR_CODEC_ERROR; + err = chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes); + if (err != CHDERR_NONE) + return err; +#ifdef VERIFY_BLOCK_CRC + if (crc16(dest, chd->header.hunkbytes) != blockcrc) return CHDERR_DECOMPRESSION_ERROR; - chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes); - if (dest != NULL && crc16(dest, chd->header.hunkbytes) != blockcrc) - return CHDERR_DECOMPRESSION_ERROR; +#endif return CHDERR_NONE; case COMPRESSION_NONE: err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest); if (err != CHDERR_NONE) return err; +#ifdef VERIFY_BLOCK_CRC if (crc16(dest, chd->header.hunkbytes) != blockcrc) return CHDERR_DECOMPRESSION_ERROR; +#endif return CHDERR_NONE; case COMPRESSION_SELF: @@ -2392,9 +2503,9 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes) { - zlib_codec_data *data = (zlib_codec_data*)codec; - chd_error err; int zerr; + chd_error err; + zlib_codec_data *data = (zlib_codec_data*)codec; /* clear the buffers */ memset(data, 0, sizeof(zlib_codec_data)); @@ -2477,9 +2588,14 @@ static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t allocates and frees memory frequently -------------------------------------------------*/ +/* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */ +#define ZLIB_MIN_ALIGNMENT_BITS 512 +#define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8) + static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) { zlib_allocator *alloc = (zlib_allocator *)opaque; + uintptr_t paddr = 0; UINT32 *ptr; int i; @@ -2494,12 +2610,14 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) { /* set the low bit of the size so we don't match next time */ *ptr |= 1; - return ptr + 1; + + /* return aligned block address */ + return (voidpf)(alloc->allocptr2[i]); } } /* alloc a new one */ - ptr = (UINT32 *)malloc(size + sizeof(uintptr_t)); + ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES); if (!ptr) return NULL; @@ -2508,12 +2626,16 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) if (!alloc->allocptr[i]) { alloc->allocptr[i] = ptr; + paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1)); + alloc->allocptr2[i] = (uint32_t*)paddr; break; } /* set the low bit of the size so we don't match next time */ *ptr = size | 1; - return ptr + (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2); + + /* return aligned block address */ + return (voidpf)paddr; } /*------------------------------------------------- @@ -2524,15 +2646,15 @@ static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size) static void zlib_fast_free(voidpf opaque, voidpf address) { zlib_allocator *alloc = (zlib_allocator *)opaque; - UINT32 *ptr = (UINT32 *)address - (sizeof(uint32_t) == sizeof(uintptr_t) ? 1 : 2); + UINT32 *ptr = (UINT32 *)address; int i; /* find the hunk */ for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - if (ptr == alloc->allocptr[i]) + if (ptr == alloc->allocptr2[i]) { /* clear the low bit of the size to allow matches */ - *ptr &= ~1; + *(alloc->allocptr[i]) &= ~1; return; } } @@ -2548,4 +2670,4 @@ static void zlib_allocator_free(voidpf opaque) for (i = 0; i < MAX_ZLIB_ALLOCS; i++) if (alloc->allocptr[i]) free(alloc->allocptr[i]); -} \ No newline at end of file +} diff --git a/dep/libchdr/src/flac.c b/dep/libchdr/src/libchdr_flac.c similarity index 99% rename from dep/libchdr/src/flac.c rename to dep/libchdr/src/libchdr_flac.c index 8e31ed6b7..4bea7d498 100644 --- a/dep/libchdr/src/flac.c +++ b/dep/libchdr/src/libchdr_flac.c @@ -10,7 +10,8 @@ #include #include -#include "flac.h" + +#include /*************************************************************************** * FLAC DECODER diff --git a/dep/libchdr/src/huffman.c b/dep/libchdr/src/libchdr_huffman.c similarity index 90% rename from dep/libchdr/src/huffman.c rename to dep/libchdr/src/libchdr_huffman.c index f48210ea5..6a50f1344 100644 --- a/dep/libchdr/src/huffman.c +++ b/dep/libchdr/src/libchdr_huffman.c @@ -101,7 +101,7 @@ #include #include -#include "huffman.h" +#include #define MAX(x,y) ((x) > (y) ? (x) : (y)) @@ -125,11 +125,13 @@ struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits) { + struct huffman_decoder* decoder = NULL; + /* limit to 24 bits */ if (maxbits > 24) return NULL; - struct huffman_decoder* decoder = (struct huffman_decoder*)malloc(sizeof(struct huffman_decoder)); + decoder = (struct huffman_decoder*)malloc(sizeof(struct huffman_decoder)); decoder->numcodes = numcodes; decoder->maxbits = maxbits; decoder->lookup = (lookup_value*)malloc(sizeof(lookup_value) * (1 << maxbits)); @@ -140,6 +142,18 @@ struct huffman_decoder* create_huffman_decoder(int numcodes, int maxbits) return decoder; } +void delete_huffman_decoder(struct huffman_decoder* decoder) +{ + if (decoder != NULL) + { + if (decoder->lookup != NULL) + free(decoder->lookup); + if (decoder->huffnode != NULL) + free(decoder->huffnode); + free(decoder); + } +} + /*------------------------------------------------- * decode_one - decode a single code from the * huffman stream @@ -167,8 +181,10 @@ uint32_t huffman_decode_one(struct huffman_decoder* decoder, struct bitstream* b enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, struct bitstream* bitbuf) { + int numbits, curnode; + enum huffman_error error; + /* bits per entry depends on the maxbits */ - int numbits; if (decoder->maxbits >= 16) numbits = 5; else if (decoder->maxbits >= 8) @@ -177,7 +193,6 @@ enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, stru numbits = 3; /* loop until we read all the nodes */ - int curnode; for (curnode = 0; curnode < decoder->numcodes; ) { /* a non-one value is just raw */ @@ -208,7 +223,7 @@ enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, stru return HUFFERR_INVALID_DATA; /* assign canonical codes for all nodes based on their code lengths */ - enum huffman_error error = huffman_assign_canonical_codes(decoder); + error = huffman_assign_canonical_codes(decoder); if (error != HUFFERR_NONE) return error; @@ -228,12 +243,19 @@ enum huffman_error huffman_import_tree_rle(struct huffman_decoder* decoder, stru enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, struct bitstream* bitbuf) { + int start; + int last = 0; + int count = 0; + int index; + int curcode; + uint8_t rlefullbits = 0; + uint32_t temp; + enum huffman_error error; /* start by parsing the lengths for the small tree */ struct huffman_decoder* smallhuff = create_huffman_decoder(24, 6); smallhuff->huffnode[0].numbits = bitstream_read(bitbuf, 3); - int start = bitstream_read(bitbuf, 3) + 1; - int count = 0; - for (int index = 1; index < 24; index++) + start = bitstream_read(bitbuf, 3) + 1; + for (index = 1; index < 24; index++) { if (index < start || count == 7) smallhuff->huffnode[index].numbits = 0; @@ -245,20 +267,17 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, } /* then regenerate the tree */ - enum huffman_error error = huffman_assign_canonical_codes(smallhuff); + error = huffman_assign_canonical_codes(smallhuff); if (error != HUFFERR_NONE) return error; huffman_build_lookup_table(smallhuff); /* determine the maximum length of an RLE count */ - uint32_t temp = decoder->numcodes - 9; - uint8_t rlefullbits = 0; + temp = decoder->numcodes - 9; while (temp != 0) temp >>= 1, rlefullbits++; /* now process the rest of the data */ - int last = 0; - int curcode; for (curcode = 0; curcode < decoder->numcodes; ) { int value = huffman_decode_one(smallhuff, bitbuf); @@ -298,14 +317,17 @@ enum huffman_error huffman_import_tree_huffman(struct huffman_decoder* decoder, enum huffman_error huffman_compute_tree_from_histo(struct huffman_decoder* decoder) { + int i; + uint32_t lowerweight; + uint32_t upperweight; /* compute the number of data items in the histogram */ uint32_t sdatacount = 0; - for (int i = 0; i < decoder->numcodes; i++) + for (i = 0; i < decoder->numcodes; i++) sdatacount += decoder->datahisto[i]; /* binary search to achieve the optimum encoding */ - uint32_t lowerweight = 0; - uint32_t upperweight = sdatacount * 2; + lowerweight = 0; + upperweight = sdatacount * 2; while (1) { /* build a tree using the current weight */ @@ -359,11 +381,14 @@ static int huffman_tree_node_compare(const void *item1, const void *item2) int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint32_t totalweight) { + int curcode; + int nextalloc; + int listitems = 0; + int maxbits = 0; /* make a list of all non-zero nodes */ struct node_t** list = (struct node_t**)malloc(sizeof(struct node_t*) * decoder->numcodes * 2); - int listitems = 0; memset(decoder->huffnode, 0, decoder->numcodes * sizeof(decoder->huffnode[0])); - for (int curcode = 0; curcode < decoder->numcodes; curcode++) + for (curcode = 0; curcode < decoder->numcodes; curcode++) if (decoder->datahisto[curcode] != 0) { list[listitems++] = &decoder->huffnode[curcode]; @@ -395,9 +420,10 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint #endif /* now build the tree */ - int nextalloc = decoder->numcodes; + nextalloc = decoder->numcodes; while (listitems > 1) { + int curitem; /* remove lowest two items */ struct node_t* node1 = &(*list[--listitems]); struct node_t* node0 = &(*list[--listitems]); @@ -409,7 +435,6 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint newnode->weight = node0->weight + node1->weight; /* insert into list at appropriate location */ - int curitem; for (curitem = 0; curitem < listitems; curitem++) if (newnode->weight > list[curitem]->weight) { @@ -421,9 +446,9 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint } /* compute the number of bits in each code, and fill in another histogram */ - int maxbits = 0; - for (int curcode = 0; curcode < decoder->numcodes; curcode++) + for (curcode = 0; curcode < decoder->numcodes; curcode++) { + struct node_t *curnode; struct node_t* node = &decoder->huffnode[curcode]; node->numbits = 0; node->bits = 0; @@ -432,7 +457,7 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint if (node->weight > 0) { /* determine the number of bits for this node */ - for (struct node_t *curnode = node; curnode->parent != NULL; curnode = curnode->parent) + for (curnode = node; curnode->parent != NULL; curnode = curnode->parent) node->numbits++; if (node->numbits == 0) node->numbits = 1; @@ -453,9 +478,11 @@ int huffman_build_tree(struct huffman_decoder* decoder, uint32_t totaldata, uint enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decoder) { + int curcode, codelen; + uint32_t curstart = 0; /* build up a histogram of bit lengths */ uint32_t bithisto[33] = { 0 }; - for (int curcode = 0; curcode < decoder->numcodes; curcode++) + for (curcode = 0; curcode < decoder->numcodes; curcode++) { struct node_t* node = &decoder->huffnode[curcode]; if (node->numbits > decoder->maxbits) @@ -465,8 +492,7 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode } /* for each code length, determine the starting code number */ - uint32_t curstart = 0; - for (int codelen = 32; codelen > 0; codelen--) + for (codelen = 32; codelen > 0; codelen--) { uint32_t nextstart = (curstart + bithisto[codelen]) >> 1; if (codelen != 1 && nextstart * 2 != (curstart + bithisto[codelen])) @@ -476,7 +502,7 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode } /* now assign canonical codes */ - for (int curcode = 0; curcode < decoder->numcodes; curcode++) + for (curcode = 0; curcode < decoder->numcodes; curcode++) { struct node_t* node = &decoder->huffnode[curcode]; if (node->numbits > 0) @@ -493,20 +519,24 @@ enum huffman_error huffman_assign_canonical_codes(struct huffman_decoder* decode void huffman_build_lookup_table(struct huffman_decoder* decoder) { + int curcode; /* iterate over all codes */ - for (int curcode = 0; curcode < decoder->numcodes; curcode++) + for (curcode = 0; curcode < decoder->numcodes; curcode++) { /* process all nodes which have non-zero bits */ struct node_t* node = &decoder->huffnode[curcode]; if (node->numbits > 0) { + int shift; + lookup_value *dest; + lookup_value *destend; /* set up the entry */ lookup_value value = MAKE_LOOKUP(curcode, node->numbits); /* fill all matching entries */ - int shift = decoder->maxbits - node->numbits; - lookup_value *dest = &decoder->lookup[node->bits << shift]; - lookup_value *destend = &decoder->lookup[((node->bits + 1) << shift) - 1]; + shift = decoder->maxbits - node->numbits; + dest = &decoder->lookup[node->bits << shift]; + destend = &decoder->lookup[((node->bits + 1) << shift) - 1]; while (dest <= destend) *dest++ = value; } diff --git a/dep/libchdr/src/md5.c b/dep/libchdr/src/md5.c deleted file mode 100644 index cdba052e0..000000000 --- a/dep/libchdr/src/md5.c +++ /dev/null @@ -1,189 +0,0 @@ -/********************************************************************* -* Filename: md5.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Implementation of the MD5 hashing algorithm. - Algorithm specification can be found here: - * http://tools.ietf.org/html/rfc1321 - This implementation uses little endian byte order. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include -#include -#include "md5.h" - -/****************************** MACROS ******************************/ -#define ROTLEFT(a,b) ((a << b) | (a >> (32-b))) - -#define F(x,y,z) ((x & y) | (~x & z)) -#define G(x,y,z) ((x & z) | (y & ~z)) -#define H(x,y,z) (x ^ y ^ z) -#define I(x,y,z) (y ^ (x | ~z)) - -#define FF(a,b,c,d,m,s,t) { a += F(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define GG(a,b,c,d,m,s,t) { a += G(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define HH(a,b,c,d,m,s,t) { a += H(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } -#define II(a,b,c,d,m,s,t) { a += I(b,c,d) + m + t; \ - a = b + ROTLEFT(a,s); } - -/*********************** FUNCTION DEFINITIONS ***********************/ -void md5_transform(MD5_CTX *ctx, const BYTE data[]) -{ - WORD a, b, c, d, m[16], i, j; - - // MD5 specifies big endian byte order, but this implementation assumes a little - // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them - // on output (in md5_final()). - for (i = 0, j = 0; i < 16; ++i, j += 4) - m[i] = (data[j]) + (data[j + 1] << 8) + (data[j + 2] << 16) + (data[j + 3] << 24); - - a = ctx->state[0]; - b = ctx->state[1]; - c = ctx->state[2]; - d = ctx->state[3]; - - FF(a,b,c,d,m[0], 7,0xd76aa478); - FF(d,a,b,c,m[1], 12,0xe8c7b756); - FF(c,d,a,b,m[2], 17,0x242070db); - FF(b,c,d,a,m[3], 22,0xc1bdceee); - FF(a,b,c,d,m[4], 7,0xf57c0faf); - FF(d,a,b,c,m[5], 12,0x4787c62a); - FF(c,d,a,b,m[6], 17,0xa8304613); - FF(b,c,d,a,m[7], 22,0xfd469501); - FF(a,b,c,d,m[8], 7,0x698098d8); - FF(d,a,b,c,m[9], 12,0x8b44f7af); - FF(c,d,a,b,m[10],17,0xffff5bb1); - FF(b,c,d,a,m[11],22,0x895cd7be); - FF(a,b,c,d,m[12], 7,0x6b901122); - FF(d,a,b,c,m[13],12,0xfd987193); - FF(c,d,a,b,m[14],17,0xa679438e); - FF(b,c,d,a,m[15],22,0x49b40821); - - GG(a,b,c,d,m[1], 5,0xf61e2562); - GG(d,a,b,c,m[6], 9,0xc040b340); - GG(c,d,a,b,m[11],14,0x265e5a51); - GG(b,c,d,a,m[0], 20,0xe9b6c7aa); - GG(a,b,c,d,m[5], 5,0xd62f105d); - GG(d,a,b,c,m[10], 9,0x02441453); - GG(c,d,a,b,m[15],14,0xd8a1e681); - GG(b,c,d,a,m[4], 20,0xe7d3fbc8); - GG(a,b,c,d,m[9], 5,0x21e1cde6); - GG(d,a,b,c,m[14], 9,0xc33707d6); - GG(c,d,a,b,m[3], 14,0xf4d50d87); - GG(b,c,d,a,m[8], 20,0x455a14ed); - GG(a,b,c,d,m[13], 5,0xa9e3e905); - GG(d,a,b,c,m[2], 9,0xfcefa3f8); - GG(c,d,a,b,m[7], 14,0x676f02d9); - GG(b,c,d,a,m[12],20,0x8d2a4c8a); - - HH(a,b,c,d,m[5], 4,0xfffa3942); - HH(d,a,b,c,m[8], 11,0x8771f681); - HH(c,d,a,b,m[11],16,0x6d9d6122); - HH(b,c,d,a,m[14],23,0xfde5380c); - HH(a,b,c,d,m[1], 4,0xa4beea44); - HH(d,a,b,c,m[4], 11,0x4bdecfa9); - HH(c,d,a,b,m[7], 16,0xf6bb4b60); - HH(b,c,d,a,m[10],23,0xbebfbc70); - HH(a,b,c,d,m[13], 4,0x289b7ec6); - HH(d,a,b,c,m[0], 11,0xeaa127fa); - HH(c,d,a,b,m[3], 16,0xd4ef3085); - HH(b,c,d,a,m[6], 23,0x04881d05); - HH(a,b,c,d,m[9], 4,0xd9d4d039); - HH(d,a,b,c,m[12],11,0xe6db99e5); - HH(c,d,a,b,m[15],16,0x1fa27cf8); - HH(b,c,d,a,m[2], 23,0xc4ac5665); - - II(a,b,c,d,m[0], 6,0xf4292244); - II(d,a,b,c,m[7], 10,0x432aff97); - II(c,d,a,b,m[14],15,0xab9423a7); - II(b,c,d,a,m[5], 21,0xfc93a039); - II(a,b,c,d,m[12], 6,0x655b59c3); - II(d,a,b,c,m[3], 10,0x8f0ccc92); - II(c,d,a,b,m[10],15,0xffeff47d); - II(b,c,d,a,m[1], 21,0x85845dd1); - II(a,b,c,d,m[8], 6,0x6fa87e4f); - II(d,a,b,c,m[15],10,0xfe2ce6e0); - II(c,d,a,b,m[6], 15,0xa3014314); - II(b,c,d,a,m[13],21,0x4e0811a1); - II(a,b,c,d,m[4], 6,0xf7537e82); - II(d,a,b,c,m[11],10,0xbd3af235); - II(c,d,a,b,m[2], 15,0x2ad7d2bb); - II(b,c,d,a,m[9], 21,0xeb86d391); - - ctx->state[0] += a; - ctx->state[1] += b; - ctx->state[2] += c; - ctx->state[3] += d; -} - -void md5_init(MD5_CTX *ctx) -{ - ctx->datalen = 0; - ctx->bitlen = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -void md5_update(MD5_CTX *ctx, const BYTE data[], size_t len) -{ - size_t i; - - for (i = 0; i < len; ++i) { - ctx->data[ctx->datalen] = data[i]; - ctx->datalen++; - if (ctx->datalen == 64) { - md5_transform(ctx, ctx->data); - ctx->bitlen += 512; - ctx->datalen = 0; - } - } -} - -void md5_final(MD5_CTX *ctx, BYTE hash[]) -{ - size_t i; - - i = ctx->datalen; - - // Pad whatever data is left in the buffer. - if (ctx->datalen < 56) { - ctx->data[i++] = 0x80; - while (i < 56) - ctx->data[i++] = 0x00; - } - else if (ctx->datalen >= 56) { - ctx->data[i++] = 0x80; - while (i < 64) - ctx->data[i++] = 0x00; - md5_transform(ctx, ctx->data); - memset(ctx->data, 0, 56); - } - - // Append to the padding the total message's length in bits and transform. - ctx->bitlen += ctx->datalen * 8; - ctx->data[56] = ctx->bitlen; - ctx->data[57] = ctx->bitlen >> 8; - ctx->data[58] = ctx->bitlen >> 16; - ctx->data[59] = ctx->bitlen >> 24; - ctx->data[60] = ctx->bitlen >> 32; - ctx->data[61] = ctx->bitlen >> 40; - ctx->data[62] = ctx->bitlen >> 48; - ctx->data[63] = ctx->bitlen >> 56; - md5_transform(ctx, ctx->data); - - // Since this implementation uses little endian byte ordering and MD uses big endian, - // reverse all the bytes when copying the final state to the output hash. - for (i = 0; i < 4; ++i) { - hash[i] = (ctx->state[0] >> (i * 8)) & 0x000000ff; - hash[i + 4] = (ctx->state[1] >> (i * 8)) & 0x000000ff; - hash[i + 8] = (ctx->state[2] >> (i * 8)) & 0x000000ff; - hash[i + 12] = (ctx->state[3] >> (i * 8)) & 0x000000ff; - } -} diff --git a/dep/libchdr/src/md5.h b/dep/libchdr/src/md5.h deleted file mode 100644 index 1370387ce..000000000 --- a/dep/libchdr/src/md5.h +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************************************* -* Filename: md5.h -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Defines the API for the corresponding MD5 implementation. -*********************************************************************/ - -#ifndef MD5_H -#define MD5_H - -/*************************** HEADER FILES ***************************/ -#include - -/****************************** MACROS ******************************/ -#define MD5_BLOCK_SIZE 16 // MD5 outputs a 16 byte digest - -/**************************** DATA TYPES ****************************/ -typedef unsigned char BYTE; // 8-bit byte -typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines - -typedef struct { - BYTE data[64]; - WORD datalen; - unsigned long long bitlen; - WORD state[4]; -} MD5_CTX; - -/*********************** FUNCTION DECLARATIONS **********************/ -void md5_init(MD5_CTX *ctx); -void md5_update(MD5_CTX *ctx, const BYTE data[], size_t len); -void md5_final(MD5_CTX *ctx, BYTE hash[]); - -#endif // MD5_H diff --git a/dep/libchdr/src/sha1.c b/dep/libchdr/src/sha1.c deleted file mode 100644 index 2f9622d43..000000000 --- a/dep/libchdr/src/sha1.c +++ /dev/null @@ -1,149 +0,0 @@ -/********************************************************************* -* Filename: sha1.c -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Implementation of the SHA1 hashing algorithm. - Algorithm specification can be found here: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf - This implementation uses little endian byte order. -*********************************************************************/ - -/*************************** HEADER FILES ***************************/ -#include -#include -#include "sha1.h" - -/****************************** MACROS ******************************/ -#define ROTLEFT(a, b) ((a << b) | (a >> (32 - b))) - -/*********************** FUNCTION DEFINITIONS ***********************/ -void sha1_transform(SHA1_CTX *ctx, const BYTE data[]) -{ - WORD a, b, c, d, e, i, j, t, m[80]; - - for (i = 0, j = 0; i < 16; ++i, j += 4) - m[i] = (data[j] << 24) + (data[j + 1] << 16) + (data[j + 2] << 8) + (data[j + 3]); - for ( ; i < 80; ++i) { - m[i] = (m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]); - m[i] = (m[i] << 1) | (m[i] >> 31); - } - - a = ctx->state[0]; - b = ctx->state[1]; - c = ctx->state[2]; - d = ctx->state[3]; - e = ctx->state[4]; - - for (i = 0; i < 20; ++i) { - t = ROTLEFT(a, 5) + ((b & c) ^ (~b & d)) + e + ctx->k[0] + m[i]; - e = d; - d = c; - c = ROTLEFT(b, 30); - b = a; - a = t; - } - for ( ; i < 40; ++i) { - t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[1] + m[i]; - e = d; - d = c; - c = ROTLEFT(b, 30); - b = a; - a = t; - } - for ( ; i < 60; ++i) { - t = ROTLEFT(a, 5) + ((b & c) ^ (b & d) ^ (c & d)) + e + ctx->k[2] + m[i]; - e = d; - d = c; - c = ROTLEFT(b, 30); - b = a; - a = t; - } - for ( ; i < 80; ++i) { - t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[3] + m[i]; - e = d; - d = c; - c = ROTLEFT(b, 30); - b = a; - a = t; - } - - ctx->state[0] += a; - ctx->state[1] += b; - ctx->state[2] += c; - ctx->state[3] += d; - ctx->state[4] += e; -} - -void sha1_init(SHA1_CTX *ctx) -{ - ctx->datalen = 0; - ctx->bitlen = 0; - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xc3d2e1f0; - ctx->k[0] = 0x5a827999; - ctx->k[1] = 0x6ed9eba1; - ctx->k[2] = 0x8f1bbcdc; - ctx->k[3] = 0xca62c1d6; -} - -void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len) -{ - size_t i; - - for (i = 0; i < len; ++i) { - ctx->data[ctx->datalen] = data[i]; - ctx->datalen++; - if (ctx->datalen == 64) { - sha1_transform(ctx, ctx->data); - ctx->bitlen += 512; - ctx->datalen = 0; - } - } -} - -void sha1_final(SHA1_CTX *ctx, BYTE hash[]) -{ - WORD i; - - i = ctx->datalen; - - // Pad whatever data is left in the buffer. - if (ctx->datalen < 56) { - ctx->data[i++] = 0x80; - while (i < 56) - ctx->data[i++] = 0x00; - } - else { - ctx->data[i++] = 0x80; - while (i < 64) - ctx->data[i++] = 0x00; - sha1_transform(ctx, ctx->data); - memset(ctx->data, 0, 56); - } - - // Append to the padding the total message's length in bits and transform. - ctx->bitlen += ctx->datalen * 8; - ctx->data[63] = ctx->bitlen; - ctx->data[62] = ctx->bitlen >> 8; - ctx->data[61] = ctx->bitlen >> 16; - ctx->data[60] = ctx->bitlen >> 24; - ctx->data[59] = ctx->bitlen >> 32; - ctx->data[58] = ctx->bitlen >> 40; - ctx->data[57] = ctx->bitlen >> 48; - ctx->data[56] = ctx->bitlen >> 56; - sha1_transform(ctx, ctx->data); - - // Since this implementation uses little endian byte ordering and MD uses big endian, - // reverse all the bytes when copying the final state to the output hash. - for (i = 0; i < 4; ++i) { - hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; - hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; - hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; - hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; - hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; - } -} diff --git a/dep/libchdr/src/sha1.h b/dep/libchdr/src/sha1.h deleted file mode 100644 index f32bb7c04..000000000 --- a/dep/libchdr/src/sha1.h +++ /dev/null @@ -1,35 +0,0 @@ -/********************************************************************* -* Filename: sha1.h -* Author: Brad Conte (brad AT bradconte.com) -* Copyright: -* Disclaimer: This code is presented "as is" without any guarantees. -* Details: Defines the API for the corresponding SHA1 implementation. -*********************************************************************/ - -#ifndef SHA1_H -#define SHA1_H - -/*************************** HEADER FILES ***************************/ -#include - -/****************************** MACROS ******************************/ -#define SHA1_BLOCK_SIZE 20 // SHA1 outputs a 20 byte digest - -/**************************** DATA TYPES ****************************/ -typedef unsigned char BYTE; // 8-bit byte -typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines - -typedef struct { - BYTE data[64]; - WORD datalen; - unsigned long long bitlen; - WORD state[5]; - WORD k[4]; -} SHA1_CTX; - -/*********************** FUNCTION DECLARATIONS **********************/ -void sha1_init(SHA1_CTX *ctx); -void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len); -void sha1_final(SHA1_CTX *ctx, BYTE hash[]); - -#endif // SHA1_H