1 /***************************************************************************
5 MAME Compressed Hunks of Data file format
7 ****************************************************************************
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are
16 * Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18 * Redistributions in binary form must reproduce the above copyright
19 notice, this list of conditions and the following disclaimer in
20 the documentation and/or other materials provided with the
22 * Neither the name 'MAME' nor the names of its contributors may be
23 used to endorse or promote products derived from this software
24 without specific prior written permission.
26 THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
27 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
30 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
35 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 POSSIBILITY OF SUCH DAMAGE.
38 ***************************************************************************/
46 #include <libchdr/chd.h>
47 #include <libchdr/cdrom.h>
48 #include <libchdr/flac.h>
49 #include <libchdr/huffman.h>
62 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
63 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
65 #define SHA1_DIGEST_SIZE 20
67 /***************************************************************************
69 ***************************************************************************/
71 #define PRINTF_MAX_HUNK (0)
73 /***************************************************************************
75 ***************************************************************************/
77 #define MAP_STACK_ENTRIES 512 /* max number of entries to use on the stack */
78 #define MAP_ENTRY_SIZE 16 /* V3 and later */
79 #define OLD_MAP_ENTRY_SIZE 8 /* V1-V2 */
80 #define METADATA_HEADER_SIZE 16 /* metadata header size */
82 #define MAP_ENTRY_FLAG_TYPE_MASK 0x0f /* what type of hunk */
83 #define MAP_ENTRY_FLAG_NO_CRC 0x10 /* no CRC is present */
85 #define CHD_V1_SECTOR_SIZE 512 /* size of a "sector" in the V1 header */
87 #define COOKIE_VALUE 0xbaadf00d
88 #define MAX_ZLIB_ALLOCS 64
90 #define END_OF_LIST_COOKIE "EndOfListCookie"
94 #ifdef WANT_RAW_DATA_SECTOR
95 static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
98 /* V3-V4 entry types */
101 V34_MAP_ENTRY_TYPE_INVALID = 0, /* invalid type */
102 V34_MAP_ENTRY_TYPE_COMPRESSED = 1, /* standard compression */
103 V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2, /* uncompressed data */
104 V34_MAP_ENTRY_TYPE_MINI = 3, /* mini: use offset as raw data */
105 V34_MAP_ENTRY_TYPE_SELF_HUNK = 4, /* same as another hunk in this file */
106 V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5, /* same as a hunk in the parent file */
107 V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6 /* compressed with secondary algorithm (usually FLAC CDDA) */
110 /* V5 compression types */
114 * these types are live when running */
115 COMPRESSION_TYPE_0 = 0,
117 COMPRESSION_TYPE_1 = 1,
119 COMPRESSION_TYPE_2 = 2,
121 COMPRESSION_TYPE_3 = 3,
122 /* no compression; implicit length = hunkbytes */
123 COMPRESSION_NONE = 4,
124 /* same as another block in this chd */
125 COMPRESSION_SELF = 5,
126 /* same as a hunk's worth of units in the parent chd */
127 COMPRESSION_PARENT = 6,
129 /* start of small RLE run (4-bit length)
130 * these additional pseudo-types are used for compressed encodings: */
131 COMPRESSION_RLE_SMALL,
132 /* start of large RLE run (8-bit length) */
133 COMPRESSION_RLE_LARGE,
134 /* same as the last COMPRESSION_SELF block */
136 /* same as the last COMPRESSION_SELF block + 1 */
138 /* same block in the parent */
139 COMPRESSION_PARENT_SELF,
140 /* same as the last COMPRESSION_PARENT block */
141 COMPRESSION_PARENT_0,
142 /* same as the last COMPRESSION_PARENT block + 1 */
146 /***************************************************************************
148 ***************************************************************************/
150 #define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0)
152 /***************************************************************************
154 ***************************************************************************/
156 /* interface to a codec */
157 typedef struct _codec_interface codec_interface;
158 struct _codec_interface
160 UINT32 compression; /* type of compression */
161 const char *compname; /* name of the algorithm */
162 UINT8 lossy; /* is this a lossy algorithm? */
163 chd_error (*init)(void *codec, UINT32 hunkbytes); /* codec initialize */
164 void (*free)(void *codec); /* codec free */
165 chd_error (*decompress)(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); /* decompress data */
166 chd_error (*config)(void *codec, int param, void *config); /* configure */
169 /* a single map entry */
170 typedef struct _map_entry map_entry;
173 UINT64 offset; /* offset within the file of the data */
174 UINT32 crc; /* 32-bit CRC of the data */
175 UINT32 length; /* length of the data */
176 UINT8 flags; /* misc flags */
179 /* a single metadata entry */
180 typedef struct _metadata_entry metadata_entry;
181 struct _metadata_entry
183 UINT64 offset; /* offset within the file of the header */
184 UINT64 next; /* offset within the file of the next header */
185 UINT64 prev; /* offset within the file of the previous header */
186 UINT32 length; /* length of the metadata */
187 UINT32 metatag; /* metadata tag */
188 UINT8 flags; /* flag bits */
191 /* codec-private data for the ZLIB codec */
193 typedef struct _zlib_allocator zlib_allocator;
194 struct _zlib_allocator
196 UINT32 * allocptr[MAX_ZLIB_ALLOCS];
197 UINT32 * allocptr2[MAX_ZLIB_ALLOCS];
200 typedef struct _zlib_codec_data zlib_codec_data;
201 struct _zlib_codec_data
204 zlib_allocator allocator;
207 /* codec-private data for the LZMA codec */
208 #define MAX_LZMA_ALLOCS 64
210 typedef struct _lzma_allocator lzma_allocator;
211 struct _lzma_allocator
213 void *(*Alloc)(void *p, size_t size);
214 void (*Free)(void *p, void *address); /* address can be 0 */
215 void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
216 uint32_t* allocptr[MAX_LZMA_ALLOCS];
217 uint32_t* allocptr2[MAX_LZMA_ALLOCS];
220 typedef struct _lzma_codec_data lzma_codec_data;
221 struct _lzma_codec_data
224 lzma_allocator allocator;
227 /* codec-private data for the CDZL codec */
228 typedef struct _cdzl_codec_data cdzl_codec_data;
229 struct _cdzl_codec_data {
231 zlib_codec_data base_decompressor;
233 zlib_codec_data subcode_decompressor;
238 /* codec-private data for the CDLZ codec */
239 typedef struct _cdlz_codec_data cdlz_codec_data;
240 struct _cdlz_codec_data {
242 lzma_codec_data base_decompressor;
244 zlib_codec_data subcode_decompressor;
249 /* codec-private data for the CDFL codec */
250 typedef struct _cdfl_codec_data cdfl_codec_data;
251 struct _cdfl_codec_data {
254 flac_decoder decoder;
256 zlib_codec_data subcode_decompressor;
261 /* internal representation of an open CHD file */
264 UINT32 cookie; /* cookie, should equal COOKIE_VALUE */
266 core_file * file; /* handle to the open core file */
267 UINT8 owns_file; /* flag indicating if this file should be closed on chd_close() */
268 chd_header header; /* header, extracted from file */
270 chd_file * parent; /* pointer to parent file, or NULL */
272 map_entry * map; /* array of map entries */
274 #ifdef NEED_CACHE_HUNK
275 UINT8 * cache; /* hunk cache pointer */
276 UINT32 cachehunk; /* index of currently cached hunk */
278 UINT8 * compare; /* hunk compare pointer */
279 UINT32 comparehunk; /* index of current compare data */
282 UINT8 * compressed; /* pointer to buffer for compressed data */
283 const codec_interface * codecintf[4]; /* interface to the codec */
285 zlib_codec_data zlib_codec_data; /* zlib codec data */
286 cdzl_codec_data cdzl_codec_data; /* cdzl codec data */
287 cdlz_codec_data cdlz_codec_data; /* cdlz codec data */
288 cdfl_codec_data cdfl_codec_data; /* cdfl codec data */
290 #ifdef NEED_CACHE_HUNK
291 UINT32 maxhunk; /* maximum hunk accessed */
294 UINT8 * file_cache; /* cache of underlying file */
298 /***************************************************************************
300 ***************************************************************************/
302 static const UINT8 nullmd5[CHD_MD5_BYTES] = { 0 };
303 static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };
305 /***************************************************************************
307 ***************************************************************************/
309 /* internal header operations */
310 static chd_error header_validate(const chd_header *header);
311 static chd_error header_read(chd_file *chd, chd_header *header);
313 /* internal hunk read/write */
314 #ifdef NEED_CACHE_HUNK
315 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum);
317 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest);
319 /* internal map access */
320 static chd_error map_read(chd_file *chd);
322 /* metadata management */
323 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry);
325 /* zlib compression codec */
326 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes);
327 static void zlib_codec_free(void *codec);
328 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
329 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size);
330 static void zlib_fast_free(voidpf opaque, voidpf address);
331 static void zlib_allocator_free(voidpf opaque);
333 /* lzma compression codec */
334 static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes);
335 static void lzma_codec_free(void *codec);
336 static chd_error lzma_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
338 /* cdzl compression codec */
339 static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
340 static void cdzl_codec_free(void* codec);
341 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
343 /* cdlz compression codec */
344 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes);
345 static void cdlz_codec_free(void* codec);
346 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
348 /* cdfl compression codec */
349 static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
350 static void cdfl_codec_free(void* codec);
351 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
353 /***************************************************************************
354 * LZMA ALLOCATOR HELPER
355 ***************************************************************************
358 static void *lzma_fast_alloc(void *p, size_t size);
359 static void lzma_fast_free(void *p, void *address);
361 /*-------------------------------------------------
362 * lzma_allocator_init
363 *-------------------------------------------------
366 static void lzma_allocator_init(void* p)
368 lzma_allocator *codec = (lzma_allocator *)(p);
370 /* reset pointer list */
371 memset(codec->allocptr, 0, sizeof(codec->allocptr));
372 memset(codec->allocptr2, 0, sizeof(codec->allocptr2));
373 codec->Alloc = lzma_fast_alloc;
374 codec->Free = lzma_fast_free;
377 /*-------------------------------------------------
378 * lzma_allocator_free
379 *-------------------------------------------------
382 static void lzma_allocator_free(void* p )
385 lzma_allocator *codec = (lzma_allocator *)(p);
387 /* free our memory */
388 for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++)
390 if (codec->allocptr[i] != NULL)
391 free(codec->allocptr[i]);
395 /*-------------------------------------------------
396 * lzma_fast_alloc - fast malloc for lzma, which
397 * allocates and frees memory frequently
398 *-------------------------------------------------
401 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
402 #define LZMA_MIN_ALIGNMENT_BITS 512
403 #define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
405 static void *lzma_fast_alloc(void *p, size_t size)
408 uint32_t *addr = NULL;
409 lzma_allocator *codec = (lzma_allocator *)(p);
412 /* compute the size, rounding to the nearest 1k */
413 size = (size + 0x3ff) & ~0x3ff;
415 /* reuse a hunk if we can */
416 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
418 uint32_t *ptr = codec->allocptr[scan];
419 if (ptr != NULL && size == *ptr)
421 /* set the low bit of the size so we don't match next time */
424 /* return aligned address of the block */
425 return codec->allocptr2[scan];
429 /* alloc a new one and put it into the list */
430 addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
433 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
435 if (codec->allocptr[scan] == NULL)
437 /* store block address */
438 codec->allocptr[scan] = addr;
440 /* compute aligned address, store it */
441 vaddr = (uintptr_t)addr;
442 vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1));
443 codec->allocptr2[scan] = (uint32_t*)vaddr;
448 /* set the low bit of the size so we don't match next time */
451 /* return aligned address */
455 /*-------------------------------------------------
456 * lzma_fast_free - fast free for lzma, which
457 * allocates and frees memory frequently
458 *-------------------------------------------------
461 static void lzma_fast_free(void *p, void *address)
464 uint32_t *ptr = NULL;
465 lzma_allocator *codec = NULL;
470 codec = (lzma_allocator *)(p);
473 ptr = (uint32_t *)address;
474 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
476 if (ptr == codec->allocptr2[scan])
478 /* clear the low bit of the size to allow matches */
479 *codec->allocptr[scan] &= ~1;
485 /***************************************************************************
487 ***************************************************************************
490 /*-------------------------------------------------
491 * lzma_codec_init - constructor
492 *-------------------------------------------------
495 static chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
498 CLzmaEncProps encoder_props;
499 Byte decoder_props[LZMA_PROPS_SIZE];
501 lzma_allocator* alloc;
502 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
504 /* construct the decoder */
505 LzmaDec_Construct(&lzma_codec->decoder);
507 /* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK
508 * This code assumes that the current version of the encoder imposes the same requirements on the
509 * decoder as the encoder used to produce the file. This is not necessarily true. The format
510 * needs to be changed so the encoder properties are written to the file.
512 * configure the properties like the compressor did */
513 LzmaEncProps_Init(&encoder_props);
514 encoder_props.level = 9;
515 encoder_props.reduceSize = hunkbytes;
516 LzmaEncProps_Normalize(&encoder_props);
518 /* convert to decoder properties */
519 alloc = &lzma_codec->allocator;
520 lzma_allocator_init(alloc);
521 enc = LzmaEnc_Create((ISzAlloc*)alloc);
523 return CHDERR_DECOMPRESSION_ERROR;
524 if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
526 LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc);
527 return CHDERR_DECOMPRESSION_ERROR;
529 props_size = sizeof(decoder_props);
530 if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
532 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
533 return CHDERR_DECOMPRESSION_ERROR;
535 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
537 /* do memory allocations */
538 if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK)
539 return CHDERR_DECOMPRESSION_ERROR;
545 /*-------------------------------------------------
547 *-------------------------------------------------
550 static void lzma_codec_free(void* codec)
552 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
555 LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator);
556 lzma_allocator_free(&lzma_codec->allocator);
559 /*-------------------------------------------------
560 * decompress - decompress data using the LZMA
562 *-------------------------------------------------
565 static chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
569 SizeT consumedlen, decodedlen;
571 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
572 LzmaDec_Init(&lzma_codec->decoder);
575 consumedlen = complen;
576 decodedlen = destlen;
577 res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status);
578 if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen)
579 return CHDERR_DECOMPRESSION_ERROR;
584 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes)
587 cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
589 /* allocate buffer */
590 cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
591 if (cdlz->buffer == NULL)
592 return CHDERR_OUT_OF_MEMORY;
594 /* make sure the CHD's hunk size is an even multiple of the frame size */
595 ret = lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
596 if (ret != CHDERR_NONE)
600 ret = zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
601 if (ret != CHDERR_NONE)
605 if (hunkbytes % CD_FRAME_SIZE != 0)
606 return CHDERR_CODEC_ERROR;
611 static void cdlz_codec_free(void* codec)
613 cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
615 lzma_codec_free(&cdlz->base_decompressor);
617 zlib_codec_free(&cdlz->subcode_decompressor);
621 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
624 cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
626 /* determine header bytes */
627 uint32_t frames = destlen / CD_FRAME_SIZE;
628 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
629 uint32_t ecc_bytes = (frames + 7) / 8;
630 uint32_t header_bytes = ecc_bytes + complen_bytes;
632 /* extract compressed length of base */
633 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
634 if (complen_bytes > 2)
635 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
637 /* reset and decode */
638 lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA);
640 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);
643 /* reassemble the data */
644 for (framenum = 0; framenum < frames; framenum++)
648 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
650 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);
653 #ifdef WANT_RAW_DATA_SECTOR
654 /* reconstitute the ECC data and sync header */
655 sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
656 if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
658 memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
659 ecc_generate(sector);
668 static chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes)
671 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
673 /* make sure the CHD's hunk size is an even multiple of the frame size */
674 if (hunkbytes % CD_FRAME_SIZE != 0)
675 return CHDERR_CODEC_ERROR;
677 cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
678 if (cdzl->buffer == NULL)
679 return CHDERR_OUT_OF_MEMORY;
681 ret = zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
682 if (ret != CHDERR_NONE)
686 ret = zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
687 if (ret != CHDERR_NONE)
694 static void cdzl_codec_free(void *codec)
696 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
697 zlib_codec_free(&cdzl->base_decompressor);
699 zlib_codec_free(&cdzl->subcode_decompressor);
704 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
707 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
709 /* determine header bytes */
710 uint32_t frames = destlen / CD_FRAME_SIZE;
711 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
712 uint32_t ecc_bytes = (frames + 7) / 8;
713 uint32_t header_bytes = ecc_bytes + complen_bytes;
715 /* extract compressed length of base */
716 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
717 if (complen_bytes > 2)
718 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
720 /* reset and decode */
721 zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA);
723 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);
726 /* reassemble the data */
727 for (framenum = 0; framenum < frames; framenum++)
731 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
733 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);
736 #ifdef WANT_RAW_DATA_SECTOR
737 /* reconstitute the ECC data and sync header */
738 sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
739 if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
741 memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
742 ecc_generate(sector);
749 /***************************************************************************
750 * CD FLAC DECOMPRESSOR
751 ***************************************************************************
754 /*------------------------------------------------------
755 * cdfl_codec_blocksize - return the optimal block size
756 *------------------------------------------------------
759 static uint32_t cdfl_codec_blocksize(uint32_t bytes)
761 /* determine FLAC block size, which must be 16-65535
762 * clamp to 2k since that's supposed to be the sweet spot */
763 uint32_t hunkbytes = bytes / 4;
764 while (hunkbytes > 2048)
769 static chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes)
774 uint16_t native_endian = 0;
775 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
777 /* make sure the CHD's hunk size is an even multiple of the frame size */
778 if (hunkbytes % CD_FRAME_SIZE != 0)
779 return CHDERR_CODEC_ERROR;
781 cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
782 if (cdfl->buffer == NULL)
783 return CHDERR_OUT_OF_MEMORY;
785 /* determine whether we want native or swapped samples */
786 *(uint8_t *)(&native_endian) = 1;
787 cdfl->swap_endian = (native_endian & 1);
790 /* init zlib inflater */
791 ret = zlib_codec_init(&cdfl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
792 if (ret != CHDERR_NONE)
796 /* flac decoder init */
797 if (flac_decoder_init(&cdfl->decoder))
798 return CHDERR_OUT_OF_MEMORY;
803 static void cdfl_codec_free(void *codec)
805 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
806 flac_decoder_free(&cdfl->decoder);
808 zlib_codec_free(&cdfl->subcode_decompressor);
814 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
822 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
824 /* reset and decode */
825 uint32_t frames = destlen / CD_FRAME_SIZE;
827 if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
828 return CHDERR_DECOMPRESSION_ERROR;
829 buffer = &cdfl->buffer[0];
830 if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian))
831 return CHDERR_DECOMPRESSION_ERROR;
834 /* inflate the subcode data */
835 offset = flac_decoder_finish(&cdfl->decoder);
836 ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
837 if (ret != CHDERR_NONE)
840 flac_decoder_finish(&cdfl->decoder);
843 /* reassemble the data */
844 for (framenum = 0; framenum < frames; framenum++)
846 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
848 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);
854 /***************************************************************************
856 ***************************************************************************/
858 static const codec_interface codec_interfaces[] =
860 /* "none" or no compression */
871 /* standard zlib compression */
878 zlib_codec_decompress,
882 /* zlib+ compression */
884 CHDCOMPRESSION_ZLIB_PLUS,
889 zlib_codec_decompress,
893 /* V5 zlib compression */
900 zlib_codec_decompress,
904 /* V5 CD zlib compression */
911 cdzl_codec_decompress,
915 /* V5 CD lzma compression */
922 cdlz_codec_decompress,
926 /* V5 CD flac compression */
933 cdfl_codec_decompress,
938 /***************************************************************************
940 ***************************************************************************/
942 /*-------------------------------------------------
943 get_bigendian_uint64 - fetch a UINT64 from
944 the data stream in bigendian order
945 -------------------------------------------------*/
947 static inline UINT64 get_bigendian_uint64(const UINT8 *base)
949 return ((UINT64)base[0] << 56) | ((UINT64)base[1] << 48) | ((UINT64)base[2] << 40) | ((UINT64)base[3] << 32) |
950 ((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
953 /*-------------------------------------------------
954 put_bigendian_uint64 - write a UINT64 to
955 the data stream in bigendian order
956 -------------------------------------------------*/
958 static inline void put_bigendian_uint64(UINT8 *base, UINT64 value)
960 base[0] = value >> 56;
961 base[1] = value >> 48;
962 base[2] = value >> 40;
963 base[3] = value >> 32;
964 base[4] = value >> 24;
965 base[5] = value >> 16;
966 base[6] = value >> 8;
970 /*-------------------------------------------------
971 get_bigendian_uint48 - fetch a UINT48 from
972 the data stream in bigendian order
973 -------------------------------------------------*/
975 static inline UINT64 get_bigendian_uint48(const UINT8 *base)
977 return ((UINT64)base[0] << 40) | ((UINT64)base[1] << 32) |
978 ((UINT64)base[2] << 24) | ((UINT64)base[3] << 16) | ((UINT64)base[4] << 8) | (UINT64)base[5];
981 /*-------------------------------------------------
982 put_bigendian_uint48 - write a UINT48 to
983 the data stream in bigendian order
984 -------------------------------------------------*/
986 static inline void put_bigendian_uint48(UINT8 *base, UINT64 value)
988 value &= 0xffffffffffff;
989 base[0] = value >> 40;
990 base[1] = value >> 32;
991 base[2] = value >> 24;
992 base[3] = value >> 16;
993 base[4] = value >> 8;
996 /*-------------------------------------------------
997 get_bigendian_uint32 - fetch a UINT32 from
998 the data stream in bigendian order
999 -------------------------------------------------*/
1001 static inline UINT32 get_bigendian_uint32(const UINT8 *base)
1003 return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
1006 /*-------------------------------------------------
1007 put_bigendian_uint32 - write a UINT32 to
1008 the data stream in bigendian order
1009 -------------------------------------------------*/
1011 static inline void put_bigendian_uint32(UINT8 *base, UINT32 value)
1013 base[0] = value >> 24;
1014 base[1] = value >> 16;
1015 base[2] = value >> 8;
1019 /*-------------------------------------------------
1020 put_bigendian_uint24 - write a UINT24 to
1021 the data stream in bigendian order
1022 -------------------------------------------------*/
1024 static inline void put_bigendian_uint24(UINT8 *base, UINT32 value)
1027 base[0] = value >> 16;
1028 base[1] = value >> 8;
1032 /*-------------------------------------------------
1033 get_bigendian_uint24 - fetch a UINT24 from
1034 the data stream in bigendian order
1035 -------------------------------------------------*/
1037 static inline UINT32 get_bigendian_uint24(const UINT8 *base)
1039 return (base[0] << 16) | (base[1] << 8) | base[2];
1042 /*-------------------------------------------------
1043 get_bigendian_uint16 - fetch a UINT16 from
1044 the data stream in bigendian order
1045 -------------------------------------------------*/
1047 static inline UINT16 get_bigendian_uint16(const UINT8 *base)
1049 return (base[0] << 8) | base[1];
1052 /*-------------------------------------------------
1053 put_bigendian_uint16 - write a UINT16 to
1054 the data stream in bigendian order
1055 -------------------------------------------------*/
1057 static inline void put_bigendian_uint16(UINT8 *base, UINT16 value)
1059 base[0] = value >> 8;
1063 /*-------------------------------------------------
1064 map_extract - extract a single map
1065 entry from the datastream
1066 -------------------------------------------------*/
1068 static inline void map_extract(const UINT8 *base, map_entry *entry)
1070 entry->offset = get_bigendian_uint64(&base[0]);
1071 entry->crc = get_bigendian_uint32(&base[8]);
1072 entry->length = get_bigendian_uint16(&base[12]) | (base[14] << 16);
1073 entry->flags = base[15];
1076 /*-------------------------------------------------
1077 map_assemble - write a single map
1078 entry to the datastream
1079 -------------------------------------------------*/
1081 static inline void map_assemble(UINT8 *base, map_entry *entry)
1083 put_bigendian_uint64(&base[0], entry->offset);
1084 put_bigendian_uint32(&base[8], entry->crc);
1085 put_bigendian_uint16(&base[12], entry->length);
1086 base[14] = entry->length >> 16;
1087 base[15] = entry->flags;
1090 /*-------------------------------------------------
1091 map_size_v5 - calculate CHDv5 map size
1092 -------------------------------------------------*/
1093 static inline int map_size_v5(chd_header* header)
1095 return header->hunkcount * header->mapentrybytes;
1098 /*-------------------------------------------------
1099 crc16 - calculate CRC16 (from hashing.cpp)
1100 -------------------------------------------------*/
1101 uint16_t crc16(const void *data, uint32_t length)
1103 uint16_t crc = 0xffff;
1105 static const uint16_t s_table[256] =
1107 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1108 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1109 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1110 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1111 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1112 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1113 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1114 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1115 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1116 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1117 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1118 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1119 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1120 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1121 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1122 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1123 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1124 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1125 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1126 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1127 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1128 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1129 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1130 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1131 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1132 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1133 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1134 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1135 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1136 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1137 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1138 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1141 const uint8_t *src = (uint8_t*)data;
1143 /* fetch the current value into a local and rip through the source data */
1144 while (length-- != 0)
1145 crc = (crc << 8) ^ s_table[(crc >> 8) ^ *src++];
1149 /*-------------------------------------------------
1150 compressed - test if CHD file is compressed
1151 +-------------------------------------------------*/
1152 static inline int chd_compressed(chd_header* header) {
1153 return header->compression[0] != CHD_CODEC_NONE;
1156 /*-------------------------------------------------
1157 decompress_v5_map - decompress the v5 map
1158 -------------------------------------------------*/
1160 static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
1165 uint8_t lastcomp = 0;
1166 uint32_t last_self = 0;
1167 uint64_t last_parent = 0;
1168 struct bitstream* bitbuf;
1175 uint8_t *compressed_ptr;
1177 struct huffman_decoder* decoder;
1178 enum huffman_error err;
1180 int rawmapsize = map_size_v5(header);
1182 if (!chd_compressed(header))
1184 header->rawmap = (uint8_t*)malloc(rawmapsize);
1185 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1186 result = core_fread(chd->file, header->rawmap, rawmapsize);
1190 /* read the reader */
1191 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1192 result = core_fread(chd->file, rawbuf, sizeof(rawbuf));
1193 mapbytes = get_bigendian_uint32(&rawbuf[0]);
1194 firstoffs = get_bigendian_uint48(&rawbuf[4]);
1195 mapcrc = get_bigendian_uint16(&rawbuf[10]);
1196 lengthbits = rawbuf[12];
1197 selfbits = rawbuf[13];
1198 parentbits = rawbuf[14];
1200 /* now read the map */
1201 compressed_ptr = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes);
1202 core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
1203 result = core_fread(chd->file, compressed_ptr, mapbytes);
1204 bitbuf = create_bitstream(compressed_ptr, sizeof(uint8_t) * mapbytes);
1205 header->rawmap = (uint8_t*)malloc(rawmapsize);
1207 /* first decode the compression types */
1208 decoder = create_huffman_decoder(16, 8);
1209 if (decoder == NULL)
1211 free(compressed_ptr);
1213 return CHDERR_OUT_OF_MEMORY;
1216 err = huffman_import_tree_rle(decoder, bitbuf);
1217 if (err != HUFFERR_NONE)
1219 free(compressed_ptr);
1221 delete_huffman_decoder(decoder);
1222 return CHDERR_DECOMPRESSION_ERROR;
1225 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1227 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1229 rawmap[0] = lastcomp, repcount--;
1232 uint8_t val = huffman_decode_one(decoder, bitbuf);
1233 if (val == COMPRESSION_RLE_SMALL)
1234 rawmap[0] = lastcomp, repcount = 2 + huffman_decode_one(decoder, bitbuf);
1235 else if (val == COMPRESSION_RLE_LARGE)
1236 rawmap[0] = lastcomp, repcount = 2 + 16 + (huffman_decode_one(decoder, bitbuf) << 4), repcount += huffman_decode_one(decoder, bitbuf);
1238 rawmap[0] = lastcomp = val;
1242 /* then iterate through the hunks and extract the needed data */
1243 curoffset = firstoffs;
1244 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1246 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1247 uint64_t offset = curoffset;
1248 uint32_t length = 0;
1253 case COMPRESSION_TYPE_0:
1254 case COMPRESSION_TYPE_1:
1255 case COMPRESSION_TYPE_2:
1256 case COMPRESSION_TYPE_3:
1257 curoffset += length = bitstream_read(bitbuf, lengthbits);
1258 crc = bitstream_read(bitbuf, 16);
1261 case COMPRESSION_NONE:
1262 curoffset += length = header->hunkbytes;
1263 crc = bitstream_read(bitbuf, 16);
1266 case COMPRESSION_SELF:
1267 last_self = offset = bitstream_read(bitbuf, selfbits);
1270 case COMPRESSION_PARENT:
1271 offset = bitstream_read(bitbuf, parentbits);
1272 last_parent = offset;
1275 /* pseudo-types; convert into base types */
1276 case COMPRESSION_SELF_1:
1278 case COMPRESSION_SELF_0:
1279 rawmap[0] = COMPRESSION_SELF;
1283 case COMPRESSION_PARENT_SELF:
1284 rawmap[0] = COMPRESSION_PARENT;
1285 last_parent = offset = ( ((uint64_t)hunknum) * ((uint64_t)header->hunkbytes) ) / header->unitbytes;
1288 case COMPRESSION_PARENT_1:
1289 last_parent += header->hunkbytes / header->unitbytes;
1290 case COMPRESSION_PARENT_0:
1291 rawmap[0] = COMPRESSION_PARENT;
1292 offset = last_parent;
1296 put_bigendian_uint24(&rawmap[1], length);
1299 put_bigendian_uint48(&rawmap[4], offset);
1302 put_bigendian_uint16(&rawmap[10], crc);
1306 free(compressed_ptr);
1308 delete_huffman_decoder(decoder);
1310 /* verify the final CRC */
1311 if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc)
1312 return CHDERR_DECOMPRESSION_ERROR;
1317 /*-------------------------------------------------
1318 map_extract_old - extract a single map
1319 entry in old format from the datastream
1320 -------------------------------------------------*/
1322 static inline void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 hunkbytes)
1324 entry->offset = get_bigendian_uint64(&base[0]);
1326 entry->length = entry->offset >> 44;
1327 entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
1329 entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
1331 entry->offset = (entry->offset << 20) >> 20;
1335 /***************************************************************************
1337 ***************************************************************************/
1339 /*-------------------------------------------------
1340 chd_open_file - open a CHD file for access
1341 -------------------------------------------------*/
1343 CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd)
1345 chd_file *newchd = NULL;
1349 /* verify parameters */
1351 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1353 /* punt if invalid parent */
1354 if (parent != NULL && parent->cookie != COOKIE_VALUE)
1355 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1357 /* allocate memory for the final result */
1358 newchd = (chd_file *)malloc(sizeof(**chd));
1360 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1361 memset(newchd, 0, sizeof(*newchd));
1362 newchd->cookie = COOKIE_VALUE;
1363 newchd->parent = parent;
1364 newchd->file = file;
1366 /* now attempt to read the header */
1367 err = header_read(newchd, &newchd->header);
1368 if (err != CHDERR_NONE)
1371 /* validate the header */
1372 err = header_validate(&newchd->header);
1373 if (err != CHDERR_NONE)
1376 /* make sure we don't open a read-only file writeable */
1377 if (mode == CHD_OPEN_READWRITE && !(newchd->header.flags & CHDFLAGS_IS_WRITEABLE))
1378 EARLY_EXIT(err = CHDERR_FILE_NOT_WRITEABLE);
1380 /* also, never open an older version writeable */
1381 if (mode == CHD_OPEN_READWRITE && newchd->header.version < CHD_HEADER_VERSION)
1382 EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
1384 /* if we need a parent, make sure we have one */
1385 if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
1386 EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1388 /* make sure we have a valid parent */
1391 /* check MD5 if it isn't empty */
1392 if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1393 memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1394 memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1395 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1397 /* check SHA1 if it isn't empty */
1398 if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1399 memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1400 memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1401 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1404 /* now read the hunk map */
1405 if (newchd->header.version < 5)
1407 err = map_read(newchd);
1408 if (err != CHDERR_NONE)
1413 err = decompress_v5_map(newchd, &(newchd->header));
1415 if (err != CHDERR_NONE)
1418 #ifdef NEED_CACHE_HUNK
1419 /* allocate and init the hunk cache */
1420 newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1421 newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1422 if (newchd->cache == NULL || newchd->compare == NULL)
1423 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1424 newchd->cachehunk = ~0;
1425 newchd->comparehunk = ~0;
1428 /* allocate the temporary compressed buffer */
1429 newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1430 if (newchd->compressed == NULL)
1431 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1433 /* find the codec interface */
1434 if (newchd->header.version < 5)
1436 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1438 if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1440 newchd->codecintf[0] = &codec_interfaces[intfnum];
1445 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1446 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1448 /* initialize the codec */
1449 if (newchd->codecintf[0]->init != NULL)
1451 err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1452 if (err != CHDERR_NONE)
1459 /* verify the compression types and initialize the codecs */
1460 for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1463 for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1465 if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1467 newchd->codecintf[decompnum] = &codec_interfaces[i];
1472 if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1473 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1475 /* initialize the codec */
1476 if (newchd->codecintf[decompnum]->init != NULL)
1479 switch (newchd->header.compression[decompnum])
1481 case CHD_CODEC_ZLIB:
1482 codec = &newchd->zlib_codec_data;
1485 case CHD_CODEC_CD_ZLIB:
1486 codec = &newchd->cdzl_codec_data;
1489 case CHD_CODEC_CD_LZMA:
1490 codec = &newchd->cdlz_codec_data;
1493 case CHD_CODEC_CD_FLAC:
1494 codec = &newchd->cdfl_codec_data;
1499 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1501 err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1502 if (err != CHDERR_NONE)
1518 /*-------------------------------------------------
1519 chd_precache - precache underlying file in
1521 -------------------------------------------------*/
1523 CHD_EXPORT chd_error chd_precache(chd_file *chd)
1528 ssize_t size, count;
1531 if (chd->file_cache == NULL)
1533 core_fseek(chd->file, 0, SEEK_END);
1534 size = core_ftell(chd->file);
1536 return CHDERR_INVALID_DATA;
1537 chd->file_cache = malloc(size);
1538 if (chd->file_cache == NULL)
1539 return CHDERR_OUT_OF_MEMORY;
1540 core_fseek(chd->file, 0, SEEK_SET);
1541 count = core_fread(chd->file, chd->file_cache, size);
1544 free(chd->file_cache);
1545 chd->file_cache = NULL;
1546 return CHDERR_READ_ERROR;
1553 /*-------------------------------------------------
1554 chd_open - open a CHD file by
1556 -------------------------------------------------*/
1558 CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1561 core_file *file = NULL;
1563 /* choose the proper mode */
1570 err = CHDERR_INVALID_PARAMETER;
1575 file = core_fopen(filename);
1578 err = CHDERR_FILE_NOT_FOUND;
1582 /* now open the CHD */
1583 err = chd_open_file(file, mode, parent, chd);
1584 if (err != CHDERR_NONE)
1587 /* we now own this file */
1588 (*chd)->owns_file = TRUE;
1591 if ((err != CHDERR_NONE) && (file != NULL))
1596 /*-------------------------------------------------
1597 chd_close - close a CHD file for access
1598 -------------------------------------------------*/
1600 CHD_EXPORT void chd_close(chd_file *chd)
1602 /* punt if NULL or invalid */
1603 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1606 /* deinit the codec */
1607 if (chd->header.version < 5)
1609 if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1610 (*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1615 /* Free the codecs */
1616 for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
1620 if (chd->codecintf[i] == NULL)
1623 switch (chd->codecintf[i]->compression)
1625 case CHD_CODEC_CD_LZMA:
1626 codec = &chd->cdlz_codec_data;
1629 case CHD_CODEC_ZLIB:
1630 codec = &chd->zlib_codec_data;
1633 case CHD_CODEC_CD_ZLIB:
1634 codec = &chd->cdzl_codec_data;
1637 case CHD_CODEC_CD_FLAC:
1638 codec = &chd->cdfl_codec_data;
1644 (*chd->codecintf[i]->free)(codec);
1648 /* Free the raw map */
1649 if (chd->header.rawmap != NULL)
1650 free(chd->header.rawmap);
1653 /* free the compressed data buffer */
1654 if (chd->compressed != NULL)
1655 free(chd->compressed);
1657 #ifdef NEED_CACHE_HUNK
1658 /* free the hunk cache and compare data */
1659 if (chd->compare != NULL)
1661 if (chd->cache != NULL)
1665 /* free the hunk map */
1666 if (chd->map != NULL)
1669 /* close the file */
1670 if (chd->owns_file && chd->file != NULL)
1671 core_fclose(chd->file);
1673 #ifdef NEED_CACHE_HUNK
1674 if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1676 if (chd->file_cache)
1677 free(chd->file_cache);
1679 /* free our memory */
1683 /*-------------------------------------------------
1684 chd_core_file - return the associated
1686 -------------------------------------------------*/
1688 CHD_EXPORT core_file *chd_core_file(chd_file *chd)
1693 /*-------------------------------------------------
1694 chd_error_string - return an error string for
1696 -------------------------------------------------*/
1698 CHD_EXPORT const char *chd_error_string(chd_error err)
1702 case CHDERR_NONE: return "no error";
1703 case CHDERR_NO_INTERFACE: return "no drive interface";
1704 case CHDERR_OUT_OF_MEMORY: return "out of memory";
1705 case CHDERR_INVALID_FILE: return "invalid file";
1706 case CHDERR_INVALID_PARAMETER: return "invalid parameter";
1707 case CHDERR_INVALID_DATA: return "invalid data";
1708 case CHDERR_FILE_NOT_FOUND: return "file not found";
1709 case CHDERR_REQUIRES_PARENT: return "requires parent";
1710 case CHDERR_FILE_NOT_WRITEABLE: return "file not writeable";
1711 case CHDERR_READ_ERROR: return "read error";
1712 case CHDERR_WRITE_ERROR: return "write error";
1713 case CHDERR_CODEC_ERROR: return "codec error";
1714 case CHDERR_INVALID_PARENT: return "invalid parent";
1715 case CHDERR_HUNK_OUT_OF_RANGE: return "hunk out of range";
1716 case CHDERR_DECOMPRESSION_ERROR: return "decompression error";
1717 case CHDERR_COMPRESSION_ERROR: return "compression error";
1718 case CHDERR_CANT_CREATE_FILE: return "can't create file";
1719 case CHDERR_CANT_VERIFY: return "can't verify file";
1720 case CHDERR_NOT_SUPPORTED: return "operation not supported";
1721 case CHDERR_METADATA_NOT_FOUND: return "can't find metadata";
1722 case CHDERR_INVALID_METADATA_SIZE: return "invalid metadata size";
1723 case CHDERR_UNSUPPORTED_VERSION: return "unsupported CHD version";
1724 case CHDERR_VERIFY_INCOMPLETE: return "incomplete verify";
1725 case CHDERR_INVALID_METADATA: return "invalid metadata";
1726 case CHDERR_INVALID_STATE: return "invalid state";
1727 case CHDERR_OPERATION_PENDING: return "operation pending";
1728 case CHDERR_NO_ASYNC_OPERATION: return "no async operation in progress";
1729 case CHDERR_UNSUPPORTED_FORMAT: return "unsupported format";
1730 default: return "undocumented error";
1734 /***************************************************************************
1735 CHD HEADER MANAGEMENT
1736 ***************************************************************************/
1738 /*-------------------------------------------------
1739 chd_get_header - return a pointer to the
1740 extracted header data
1741 -------------------------------------------------*/
1743 CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
1745 /* punt if NULL or invalid */
1746 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1749 return &chd->header;
1752 /***************************************************************************
1753 CORE DATA READ/WRITE
1754 ***************************************************************************/
1756 /*-------------------------------------------------
1757 chd_read - read a single hunk from the CHD
1759 -------------------------------------------------*/
1761 CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1763 /* punt if NULL or invalid */
1764 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1765 return CHDERR_INVALID_PARAMETER;
1767 /* if we're past the end, fail */
1768 if (hunknum >= chd->header.totalhunks)
1769 return CHDERR_HUNK_OUT_OF_RANGE;
1771 /* perform the read */
1772 return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1775 /***************************************************************************
1777 ***************************************************************************/
1779 /*-------------------------------------------------
1780 chd_get_metadata - get the indexed metadata
1782 -------------------------------------------------*/
1784 CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1786 metadata_entry metaentry;
1790 /* if we didn't find it, just return */
1791 err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1792 if (err != CHDERR_NONE)
1794 /* unless we're an old version and they are requesting hard disk metadata */
1795 if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1797 char faux_metadata[256];
1800 /* fill in the faux metadata */
1801 sprintf(faux_metadata, HARD_DISK_METADATA_FORMAT, chd->header.obsolete_cylinders, chd->header.obsolete_heads, chd->header.obsolete_sectors, chd->header.hunkbytes / chd->header.obsolete_hunksize);
1802 faux_length = (UINT32)strlen(faux_metadata) + 1;
1804 /* copy the metadata itself */
1805 memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1807 /* return the length of the data and the tag */
1808 if (resultlen != NULL)
1809 *resultlen = faux_length;
1810 if (resulttag != NULL)
1811 *resulttag = HARD_DISK_METADATA_TAG;
1817 /* read the metadata */
1818 outputlen = MIN(outputlen, metaentry.length);
1819 core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1820 count = core_fread(chd->file, output, outputlen);
1821 if (count != outputlen)
1822 return CHDERR_READ_ERROR;
1824 /* return the length of the data and the tag */
1825 if (resultlen != NULL)
1826 *resultlen = metaentry.length;
1827 if (resulttag != NULL)
1828 *resulttag = metaentry.metatag;
1829 if (resultflags != NULL)
1830 *resultflags = metaentry.flags;
1834 /***************************************************************************
1836 ***************************************************************************/
1838 /*-------------------------------------------------
1839 chd_codec_config - set internal codec
1841 -------------------------------------------------*/
1843 CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config)
1845 return CHDERR_INVALID_PARAMETER;
1848 /*-------------------------------------------------
1849 chd_get_codec_name - get the name of a
1851 -------------------------------------------------*/
1853 CHD_EXPORT const char *chd_get_codec_name(UINT32 codec)
1858 /***************************************************************************
1859 INTERNAL HEADER OPERATIONS
1860 ***************************************************************************/
1862 /*-------------------------------------------------
1863 header_validate - check the validity of a
1865 -------------------------------------------------*/
1867 static chd_error header_validate(const chd_header *header)
1871 /* require a valid version */
1872 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1873 return CHDERR_UNSUPPORTED_VERSION;
1875 /* require a valid length */
1876 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1877 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1878 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1879 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1880 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1881 return CHDERR_INVALID_PARAMETER;
1883 /* Do not validate v5 header */
1884 if (header->version <= 4)
1886 /* require valid flags */
1887 if (header->flags & CHDFLAGS_UNDEFINED)
1888 return CHDERR_INVALID_PARAMETER;
1890 /* require a supported compression mechanism */
1891 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1892 if (codec_interfaces[intfnum].compression == header->compression[0])
1895 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1896 return CHDERR_INVALID_PARAMETER;
1898 /* require a valid hunksize */
1899 if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1900 return CHDERR_INVALID_PARAMETER;
1902 /* require a valid hunk count */
1903 if (header->totalhunks == 0)
1904 return CHDERR_INVALID_PARAMETER;
1906 /* require a valid MD5 and/or SHA1 if we're using a parent */
1907 if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1908 return CHDERR_INVALID_PARAMETER;
1910 /* if we're V3 or later, the obsolete fields must be 0 */
1911 if (header->version >= 3 &&
1912 (header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1913 header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1914 return CHDERR_INVALID_PARAMETER;
1916 /* if we're pre-V3, the obsolete fields must NOT be 0 */
1917 if (header->version < 3 &&
1918 (header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1919 header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1920 return CHDERR_INVALID_PARAMETER;
1926 /*-------------------------------------------------
1927 header_guess_unitbytes - for older CHD formats,
1928 guess at the bytes/unit based on metadata
1929 -------------------------------------------------*/
1931 static UINT32 header_guess_unitbytes(chd_file *chd)
1933 /* look for hard disk metadata; if found, then the unit size == sector size */
1936 if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
1937 sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
1940 /* look for CD-ROM metadata; if found, then the unit size == CD frame size */
1941 if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1942 chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1943 chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1944 chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1945 chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
1946 return CD_FRAME_SIZE;
1948 /* otherwise, just map 1:1 with the hunk size */
1949 return chd->header.hunkbytes;
1952 /*-------------------------------------------------
1953 header_read - read a CHD header into the
1954 internal data structure
1955 -------------------------------------------------*/
1957 static chd_error header_read(chd_file *chd, chd_header *header)
1959 UINT8 rawheader[CHD_MAX_HEADER_SIZE];
1964 return CHDERR_INVALID_PARAMETER;
1966 /* punt if invalid file */
1967 if (chd->file == NULL)
1968 return CHDERR_INVALID_FILE;
1971 core_fseek(chd->file, 0, SEEK_SET);
1972 count = core_fread(chd->file, rawheader, sizeof(rawheader));
1973 if (count != sizeof(rawheader))
1974 return CHDERR_READ_ERROR;
1976 /* verify the tag */
1977 if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
1978 return CHDERR_INVALID_DATA;
1980 /* extract the direct data */
1981 memset(header, 0, sizeof(*header));
1982 header->length = get_bigendian_uint32(&rawheader[8]);
1983 header->version = get_bigendian_uint32(&rawheader[12]);
1985 /* make sure it's a version we understand */
1986 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1987 return CHDERR_UNSUPPORTED_VERSION;
1989 /* make sure the length is expected */
1990 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1991 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1992 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1993 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1994 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1996 return CHDERR_INVALID_DATA;
1998 /* extract the common data */
1999 header->flags = get_bigendian_uint32(&rawheader[16]);
2000 header->compression[0] = get_bigendian_uint32(&rawheader[20]);
2001 header->compression[1] = CHD_CODEC_NONE;
2002 header->compression[2] = CHD_CODEC_NONE;
2003 header->compression[3] = CHD_CODEC_NONE;
2005 /* extract the V1/V2-specific data */
2006 if (header->version < 3)
2008 int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
2009 header->obsolete_hunksize = get_bigendian_uint32(&rawheader[24]);
2010 header->totalhunks = get_bigendian_uint32(&rawheader[28]);
2011 header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
2012 header->obsolete_heads = get_bigendian_uint32(&rawheader[36]);
2013 header->obsolete_sectors = get_bigendian_uint32(&rawheader[40]);
2014 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2015 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2016 header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
2017 header->hunkbytes = seclen * header->obsolete_hunksize;
2018 header->unitbytes = header_guess_unitbytes(chd);
2019 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2020 header->metaoffset = 0;
2023 /* extract the V3-specific data */
2024 else if (header->version == 3)
2026 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
2027 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2028 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
2029 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2030 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2031 header->hunkbytes = get_bigendian_uint32(&rawheader[76]);
2032 header->unitbytes = header_guess_unitbytes(chd);
2033 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2034 memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
2035 memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
2038 /* extract the V4-specific data */
2039 else if (header->version == 4)
2041 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
2042 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2043 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
2044 header->hunkbytes = get_bigendian_uint32(&rawheader[44]);
2045 header->unitbytes = header_guess_unitbytes(chd);
2046 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2047 memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
2048 memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
2049 memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
2052 /* extract the V5-specific data */
2053 else if (header->version == 5)
2056 header->compression[0] = get_bigendian_uint32(&rawheader[16]);
2057 header->compression[1] = get_bigendian_uint32(&rawheader[20]);
2058 header->compression[2] = get_bigendian_uint32(&rawheader[24]);
2059 header->compression[3] = get_bigendian_uint32(&rawheader[28]);
2060 header->logicalbytes = get_bigendian_uint64(&rawheader[32]);
2061 header->mapoffset = get_bigendian_uint64(&rawheader[40]);
2062 header->metaoffset = get_bigendian_uint64(&rawheader[48]);
2063 header->hunkbytes = get_bigendian_uint32(&rawheader[56]);
2064 header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
2065 header->unitbytes = get_bigendian_uint32(&rawheader[60]);
2066 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2067 memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
2068 memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
2069 memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
2071 /* determine properties of map entries */
2072 header->mapentrybytes = chd_compressed(header) ? 12 : 4;
2075 header->totalhunks = header->hunkcount;
2078 /* Unknown version */
2084 /* guess it worked */
2088 /***************************************************************************
2089 INTERNAL HUNK READ/WRITE
2090 ***************************************************************************/
2092 /*-------------------------------------------------
2093 hunk_read_compressed - read a compressed
2095 -------------------------------------------------*/
2097 static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
2104 if (chd->file_cache != NULL)
2106 return chd->file_cache + offset;
2110 core_fseek(chd->file, offset, SEEK_SET);
2111 bytes = core_fread(chd->file, chd->compressed, size);
2114 return chd->compressed;
2118 /*-------------------------------------------------
2119 hunk_read_uncompressed - read an uncompressed
2121 -------------------------------------------------*/
2123 static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2130 if (chd->file_cache != NULL)
2132 memcpy(dest, chd->file_cache + offset, size);
2136 core_fseek(chd->file, offset, SEEK_SET);
2137 bytes = core_fread(chd->file, dest, size);
2139 return CHDERR_READ_ERROR;
2144 #ifdef NEED_CACHE_HUNK
2145 /*-------------------------------------------------
2146 hunk_read_into_cache - read a hunk into
2147 the CHD's hunk cache
2148 -------------------------------------------------*/
2150 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2155 if (hunknum > chd->maxhunk)
2156 chd->maxhunk = hunknum;
2158 /* if we're already in the cache, we're done */
2159 if (chd->cachehunk == hunknum)
2161 chd->cachehunk = ~0;
2163 /* otherwise, read the data */
2164 err = hunk_read_into_memory(chd, hunknum, chd->cache);
2165 if (err != CHDERR_NONE)
2168 /* mark the hunk successfully cached in */
2169 chd->cachehunk = hunknum;
2174 /*-------------------------------------------------
2175 hunk_read_into_memory - read a hunk into
2176 memory at the given location
2177 -------------------------------------------------*/
2179 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2183 /* punt if no file */
2184 if (chd->file == NULL)
2185 return CHDERR_INVALID_FILE;
2187 /* return an error if out of range */
2188 if (hunknum >= chd->header.totalhunks)
2189 return CHDERR_HUNK_OUT_OF_RANGE;
2192 return CHDERR_INVALID_PARAMETER;
2194 if (chd->header.version < 5)
2196 map_entry *entry = &chd->map[hunknum];
2198 UINT8* compressed_bytes;
2200 /* switch off the entry type */
2201 switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2203 /* compressed data */
2204 case V34_MAP_ENTRY_TYPE_COMPRESSED:
2208 /* read it into the decompression buffer */
2209 compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
2210 if (compressed_bytes == NULL)
2211 return CHDERR_READ_ERROR;
2213 /* now decompress using the codec */
2215 codec = &chd->zlib_codec_data;
2216 if (chd->codecintf[0]->decompress != NULL)
2217 err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
2218 if (err != CHDERR_NONE)
2223 /* uncompressed data */
2224 case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2225 err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2226 if (err != CHDERR_NONE)
2230 /* mini-compressed data */
2231 case V34_MAP_ENTRY_TYPE_MINI:
2232 put_bigendian_uint64(&dest[0], entry->offset);
2233 for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2234 dest[bytes] = dest[bytes - 8];
2237 /* self-referenced data */
2238 case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2239 #ifdef NEED_CACHE_HUNK
2240 if (chd->cachehunk == entry->offset && dest == chd->cache)
2243 return hunk_read_into_memory(chd, entry->offset, dest);
2245 /* parent-referenced data */
2246 case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2247 err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2248 if (err != CHDERR_NONE)
2257 /* get a pointer to the map entry */
2260 #ifdef VERIFY_BLOCK_CRC
2263 uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2264 UINT8* compressed_bytes;
2266 /* uncompressed case */
2267 if (!chd_compressed(&chd->header))
2269 blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
2270 if (blockoffs != 0) {
2271 core_fseek(chd->file, blockoffs, SEEK_SET);
2272 int result = core_fread(chd->file, dest, chd->header.hunkbytes);
2274 else if (m_parent_missing)
2275 throw CHDERR_REQUIRES_PARENT; */
2276 } else if (chd->parent) {
2277 err = hunk_read_into_memory(chd->parent, hunknum, dest);
2278 if (err != CHDERR_NONE)
2281 memset(dest, 0, chd->header.hunkbytes);
2287 /* compressed case */
2288 blocklen = get_bigendian_uint24(&rawmap[1]);
2289 blockoffs = get_bigendian_uint48(&rawmap[4]);
2290 #ifdef VERIFY_BLOCK_CRC
2291 blockcrc = get_bigendian_uint16(&rawmap[10]);
2296 case COMPRESSION_TYPE_0:
2297 case COMPRESSION_TYPE_1:
2298 case COMPRESSION_TYPE_2:
2299 case COMPRESSION_TYPE_3:
2300 compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
2301 if (compressed_bytes == NULL)
2302 return CHDERR_READ_ERROR;
2303 switch (chd->codecintf[rawmap[0]]->compression)
2305 case CHD_CODEC_CD_LZMA:
2306 codec = &chd->cdlz_codec_data;
2309 case CHD_CODEC_ZLIB:
2310 codec = &chd->zlib_codec_data;
2313 case CHD_CODEC_CD_ZLIB:
2314 codec = &chd->cdzl_codec_data;
2317 case CHD_CODEC_CD_FLAC:
2318 codec = &chd->cdfl_codec_data;
2322 return CHDERR_CODEC_ERROR;
2323 err = chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
2324 if (err != CHDERR_NONE)
2326 #ifdef VERIFY_BLOCK_CRC
2327 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2328 return CHDERR_DECOMPRESSION_ERROR;
2332 case COMPRESSION_NONE:
2333 err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest);
2334 if (err != CHDERR_NONE)
2336 #ifdef VERIFY_BLOCK_CRC
2337 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2338 return CHDERR_DECOMPRESSION_ERROR;
2342 case COMPRESSION_SELF:
2343 return hunk_read_into_memory(chd, blockoffs, dest);
2345 case COMPRESSION_PARENT:
2348 if (m_parent_missing)
2349 return CHDERR_REQUIRES_PARENT;
2350 return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
2352 return CHDERR_DECOMPRESSION_ERROR;
2357 /* We should not reach this code */
2358 return CHDERR_DECOMPRESSION_ERROR;
2361 /***************************************************************************
2363 ***************************************************************************/
2365 /*-------------------------------------------------
2366 map_read - read the initial sector map
2367 -------------------------------------------------*/
2369 static chd_error map_read(chd_file *chd)
2371 UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2372 UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2373 UINT64 fileoffset, maxoffset = 0;
2374 UINT8 cookie[MAP_ENTRY_SIZE];
2379 /* first allocate memory */
2380 chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2382 return CHDERR_OUT_OF_MEMORY;
2384 /* read the map entries in in chunks and extract to the map list */
2385 fileoffset = chd->header.length;
2386 for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2388 /* compute how many entries this time */
2389 int entries = chd->header.totalhunks - i, j;
2390 if (entries > MAP_STACK_ENTRIES)
2391 entries = MAP_STACK_ENTRIES;
2393 /* read that many */
2394 core_fseek(chd->file, fileoffset, SEEK_SET);
2395 count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2396 if (count != entries * entrysize)
2398 err = CHDERR_READ_ERROR;
2401 fileoffset += entries * entrysize;
2403 /* process that many */
2404 if (entrysize == MAP_ENTRY_SIZE)
2406 for (j = 0; j < entries; j++)
2407 map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2411 for (j = 0; j < entries; j++)
2412 map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2415 /* track the maximum offset */
2416 for (j = 0; j < entries; j++)
2417 if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2418 (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2419 maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2422 /* verify the cookie */
2423 core_fseek(chd->file, fileoffset, SEEK_SET);
2424 count = core_fread(chd->file, &cookie, entrysize);
2425 if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2427 err = CHDERR_INVALID_FILE;
2431 /* verify the length */
2432 if (maxoffset > core_fsize(chd->file))
2434 err = CHDERR_INVALID_FILE;
2446 /***************************************************************************
2447 INTERNAL METADATA ACCESS
2448 ***************************************************************************/
2450 /*-------------------------------------------------
2451 metadata_find_entry - find a metadata entry
2452 -------------------------------------------------*/
2454 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2456 /* start at the beginning */
2457 metaentry->offset = chd->header.metaoffset;
2458 metaentry->prev = 0;
2460 /* loop until we run out of options */
2461 while (metaentry->offset != 0)
2463 UINT8 raw_meta_header[METADATA_HEADER_SIZE];
2466 /* read the raw header */
2467 core_fseek(chd->file, metaentry->offset, SEEK_SET);
2468 count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2469 if (count != sizeof(raw_meta_header))
2472 /* extract the data */
2473 metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2474 metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2475 metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2477 /* flags are encoded in the high byte of length */
2478 metaentry->flags = metaentry->length >> 24;
2479 metaentry->length &= 0x00ffffff;
2481 /* if we got a match, proceed */
2482 if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2483 if (metaindex-- == 0)
2486 /* no match, fetch the next link */
2487 metaentry->prev = metaentry->offset;
2488 metaentry->offset = metaentry->next;
2491 /* if we get here, we didn't find it */
2492 return CHDERR_METADATA_NOT_FOUND;
2495 /***************************************************************************
2496 ZLIB COMPRESSION CODEC
2497 ***************************************************************************/
2499 /*-------------------------------------------------
2500 zlib_codec_init - initialize the ZLIB codec
2501 -------------------------------------------------*/
2503 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2507 zlib_codec_data *data = (zlib_codec_data*)codec;
2509 /* clear the buffers */
2510 memset(data, 0, sizeof(zlib_codec_data));
2512 /* init the inflater first */
2513 data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */
2514 data->inflater.avail_in = 0;
2515 data->inflater.zalloc = zlib_fast_alloc;
2516 data->inflater.zfree = zlib_fast_free;
2517 data->inflater.opaque = &data->allocator;
2518 zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2520 /* convert errors */
2521 if (zerr == Z_MEM_ERROR)
2522 err = CHDERR_OUT_OF_MEMORY;
2523 else if (zerr != Z_OK)
2524 err = CHDERR_CODEC_ERROR;
2528 /* handle an error */
2529 if (err != CHDERR_NONE)
2535 /*-------------------------------------------------
2536 zlib_codec_free - free data for the ZLIB
2538 -------------------------------------------------*/
2540 static void zlib_codec_free(void *codec)
2542 zlib_codec_data *data = (zlib_codec_data *)codec;
2544 /* deinit the streams */
2549 inflateEnd(&data->inflater);
2551 /* free our fast memory */
2552 zlib_allocator_free(&data->allocator);
2556 /*-------------------------------------------------
2557 zlib_codec_decompress - decompress data using
2559 -------------------------------------------------*/
2561 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2563 zlib_codec_data *data = (zlib_codec_data *)codec;
2566 /* reset the decompressor */
2567 data->inflater.next_in = (Bytef *)src;
2568 data->inflater.avail_in = complen;
2569 data->inflater.total_in = 0;
2570 data->inflater.next_out = (Bytef *)dest;
2571 data->inflater.avail_out = destlen;
2572 data->inflater.total_out = 0;
2573 zerr = inflateReset(&data->inflater);
2575 return CHDERR_DECOMPRESSION_ERROR;
2578 zerr = inflate(&data->inflater, Z_FINISH);
2579 if (data->inflater.total_out != destlen)
2580 return CHDERR_DECOMPRESSION_ERROR;
2585 /*-------------------------------------------------
2586 zlib_fast_alloc - fast malloc for ZLIB, which
2587 allocates and frees memory frequently
2588 -------------------------------------------------*/
2590 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
2591 #define ZLIB_MIN_ALIGNMENT_BITS 512
2592 #define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
2594 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2596 zlib_allocator *alloc = (zlib_allocator *)opaque;
2597 uintptr_t paddr = 0;
2601 /* compute the size, rounding to the nearest 1k */
2602 size = (size * items + 0x3ff) & ~0x3ff;
2604 /* reuse a hunk if we can */
2605 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2607 ptr = alloc->allocptr[i];
2608 if (ptr && size == *ptr)
2610 /* set the low bit of the size so we don't match next time */
2613 /* return aligned block address */
2614 return (voidpf)(alloc->allocptr2[i]);
2618 /* alloc a new one */
2619 ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
2623 /* put it into the list */
2624 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2625 if (!alloc->allocptr[i])
2627 alloc->allocptr[i] = ptr;
2628 paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
2629 alloc->allocptr2[i] = (uint32_t*)paddr;
2633 /* set the low bit of the size so we don't match next time */
2636 /* return aligned block address */
2637 return (voidpf)paddr;
2640 /*-------------------------------------------------
2641 zlib_fast_free - fast free for ZLIB, which
2642 allocates and frees memory frequently
2643 -------------------------------------------------*/
2645 static void zlib_fast_free(voidpf opaque, voidpf address)
2647 zlib_allocator *alloc = (zlib_allocator *)opaque;
2648 UINT32 *ptr = (UINT32 *)address;
2652 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2653 if (ptr == alloc->allocptr2[i])
2655 /* clear the low bit of the size to allow matches */
2656 *(alloc->allocptr[i]) &= ~1;
2661 /*-------------------------------------------------
2663 -------------------------------------------------*/
2664 static void zlib_allocator_free(voidpf opaque)
2666 zlib_allocator *alloc = (zlib_allocator *)opaque;
2669 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2670 if (alloc->allocptr[i])
2671 free(alloc->allocptr[i]);