From dcd8e4fd48205ae70f8d9a353d9d3a70c0537df2 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Fri, 23 Oct 2020 08:00:38 +0800 Subject: [PATCH] Update libchdr from latest upstream changes Based on commit https://github.com/rtissera/libchdr/tree/16759edf50f39ecea7bfe8564d689fa01e0fae0c but without directory stucture and filename changes. --- deps/libchdr/chd.c | 216 ++++++++++++++++++++++++++------------- deps/libchdr/coretypes.h | 7 +- deps/libchdr/huffman.c | 64 +++++++----- 3 files changed, 189 insertions(+), 98 deletions(-) diff --git a/deps/libchdr/chd.c b/deps/libchdr/chd.c index 096ba9ec..a77a5237 100644 --- a/deps/libchdr/chd.c +++ b/deps/libchdr/chd.c @@ -197,6 +197,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 +217,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; @@ -342,6 +344,7 @@ static void zlib_codec_free(void *codec); static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size); static void zlib_fast_free(voidpf opaque, voidpf address); +static void zlib_allocator_free(voidpf opaque); /* lzma compression codec */ static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes); @@ -382,6 +385,7 @@ void lzma_allocator_init(void* 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; } @@ -393,10 +397,11 @@ void lzma_allocator_init(void* p) 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]); @@ -409,27 +414,33 @@ void lzma_allocator_free(void* p ) *------------------------------------------------- */ +#define LZMA_MIN_ALIGNMENT_BITS 512 +#define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8) 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 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++) @@ -437,13 +448,16 @@ void *lzma_fast_alloc(void *p, size_t size) if (codec->allocptr[scan] == NULL) { codec->allocptr[scan] = addr; + 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 (void*)vaddr; } /*------------------------------------------------- @@ -454,19 +468,23 @@ void *lzma_fast_alloc(void *p, size_t size) 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; } } @@ -484,6 +502,11 @@ void lzma_fast_free(void *p, void *address) 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 */ @@ -495,16 +518,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) @@ -512,8 +534,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); @@ -551,15 +572,17 @@ 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) { + 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; @@ -593,7 +616,7 @@ void cdlz_codec_free(void* codec) 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 */ @@ -612,8 +635,10 @@ chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t comple 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); /* reassemble the data */ - for (uint32_t framenum = 0; framenum < frames; framenum++) + for (framenum = 0; framenum < frames; framenum++) { + uint8_t *sector; + 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); @@ -655,7 +680,7 @@ void cdzl_codec_free(void *codec) 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 */ @@ -674,8 +699,10 @@ chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple 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); /* reassemble the data */ - for (uint32_t framenum = 0; framenum < frames; framenum++) + for (framenum = 0; framenum < frames; framenum++) { + uint8_t *sector; + 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); @@ -712,6 +739,8 @@ static uint32_t cdfl_codec_blocksize(uint32_t bytes) chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) { + int zerr; + uint16_t native_endian = 0; cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes); @@ -721,7 +750,6 @@ chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) return CHDERR_CODEC_ERROR; /* determine whether we want native or swapped samples */ - uint16_t native_endian = 0; *(uint8_t *)(&native_endian) = 1; cdfl->swap_endian = (native_endian & 1); @@ -734,7 +762,7 @@ chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes) cdfl->inflater.zalloc = zlib_fast_alloc; cdfl->inflater.zfree = zlib_fast_free; cdfl->inflater.opaque = &cdfl->allocator; - int zerr = inflateInit2(&cdfl->inflater, -MAX_WBITS); + zerr = inflateInit2(&cdfl->inflater, -MAX_WBITS); /* convert errors */ if (zerr == Z_MEM_ERROR) @@ -753,10 +781,16 @@ void cdfl_codec_free(void *codec) free(cdfl->buffer); inflateEnd(&cdfl->inflater); flac_decoder_free(&cdfl->decoder); + + /* free our fast memory */ + zlib_allocator_free(&cdfl->allocator); } chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen) { + int zerr; + uint8_t *buffer; + uint32_t framenum, offset; cdfl_codec_data *cdfl = (cdfl_codec_data*)codec; /* reset and decode */ @@ -764,19 +798,19 @@ 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; /* inflate the subcode data */ - uint32_t offset = flac_decoder_finish(&cdfl->decoder); + 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); + zerr = inflateReset(&cdfl->inflater); if (zerr != Z_OK) return CHDERR_DECOMPRESSION_ERROR; @@ -788,7 +822,7 @@ chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t comple return CHDERR_DECOMPRESSION_ERROR; /* 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); 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); @@ -1095,7 +1129,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; } @@ -1105,42 +1139,58 @@ 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); + int result; 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); + err = huffman_import_tree_rle(decoder, bitbuf); if (err != HUFFERR_NONE) 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) @@ -1158,10 +1208,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; @@ -1222,7 +1270,7 @@ static chd_error decompress_v5_map(chd_file* chd, chd_header* header) put_bigendian_uint16(&rawmap[10], crc); } - free(compressed); + free(compressed_ptr); free(bitbuf); free(decoder->lookup); free(decoder->huffnode); @@ -1373,10 +1421,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]) { @@ -1524,8 +1574,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; @@ -1986,7 +2037,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; @@ -2106,6 +2157,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); @@ -2114,12 +2167,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: @@ -2156,16 +2210,18 @@ static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *des uint64_t blockoffs; uint32_t blocklen; uint16_t blockcrc; + void* codec = NULL; 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) { + int result; core_fseek(chd->file, blockoffs, SEEK_SET); - core_fread(chd->file, dest, chd->header.hunkbytes); + result = core_fread(chd->file, dest, chd->header.hunkbytes); /* TODO else if (m_parent_missing) throw CHDERR_REQUIRES_PARENT; */ @@ -2176,13 +2232,14 @@ 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]); blockcrc = get_bigendian_uint16(&rawmap[10]); - void* codec = NULL; + codec = NULL; switch (rawmap[0]) { case COMPRESSION_TYPE_0: @@ -2435,15 +2492,12 @@ static void zlib_codec_free(void *codec) inflateEnd(&data->inflater); /* free our fast memory */ - zlib_allocator alloc = data->allocator; - for (i = 0; i < MAX_ZLIB_ALLOCS; i++) - if (alloc.allocptr[i]) - free(alloc.allocptr[i]); + zlib_allocator_free(&data->allocator); } } /*------------------------------------------------- - zlib_codec_decompress - decomrpess data using + zlib_codec_decompress - decompress data using the ZLIB codec -------------------------------------------------*/ @@ -2475,10 +2529,13 @@ static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t zlib_fast_alloc - fast malloc for ZLIB, which allocates and frees memory frequently -------------------------------------------------*/ +#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; @@ -2493,12 +2550,12 @@ 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 (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; @@ -2507,12 +2564,14 @@ 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 (voidpf)paddr; } /*------------------------------------------------- @@ -2523,15 +2582,28 @@ 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; } } + +/*------------------------------------------------- + zlib_allocator_free +-------------------------------------------------*/ +static void zlib_allocator_free(voidpf opaque) +{ + zlib_allocator *alloc = (zlib_allocator *)opaque; + int i; + + for (i = 0; i < MAX_ZLIB_ALLOCS; i++) + if (alloc->allocptr[i]) + free(alloc->allocptr[i]); +} diff --git a/deps/libchdr/coretypes.h b/deps/libchdr/coretypes.h index 5aecc14d..fbe2d7d6 100644 --- a/deps/libchdr/coretypes.h +++ b/deps/libchdr/coretypes.h @@ -4,6 +4,10 @@ #include #include +#ifdef __LIBRETRO__ +#include +#endif + #define ARRAY_LENGTH(x) (sizeof(x)/sizeof(x[0])) typedef uint64_t UINT64; @@ -24,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/deps/libchdr/huffman.c b/deps/libchdr/huffman.c index f48210ea..a58b6be8 100644 --- a/deps/libchdr/huffman.c +++ b/deps/libchdr/huffman.c @@ -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)); @@ -167,8 +169,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 +181,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 +211,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 +231,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 +255,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 +305,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 +369,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,7 +408,7 @@ 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) { /* remove lowest two items */ @@ -421,8 +434,7 @@ 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* node = &decoder->huffnode[curcode]; node->numbits = 0; @@ -453,9 +465,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 +479,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 +489,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,8 +506,9 @@ 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]; -- 2.39.5