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 ***************************************************************************/
40 typedef unsigned char Byte;
60 #include "../deps/crypto/md5.h"
65 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
66 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
68 #define SHA1_DIGEST_SIZE 20
70 #define CHD_MAKE_TAG(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
72 /***************************************************************************
74 ***************************************************************************/
76 #define PRINTF_MAX_HUNK (0)
80 /***************************************************************************
82 ***************************************************************************/
84 #define MAP_STACK_ENTRIES 512 /* max number of entries to use on the stack */
85 #define MAP_ENTRY_SIZE 16 /* V3 and later */
86 #define OLD_MAP_ENTRY_SIZE 8 /* V1-V2 */
87 #define METADATA_HEADER_SIZE 16 /* metadata header size */
88 #define CRCMAP_HASH_SIZE 4095 /* number of CRC hashtable entries */
90 #define MAP_ENTRY_FLAG_TYPE_MASK 0x0f /* what type of hunk */
91 #define MAP_ENTRY_FLAG_NO_CRC 0x10 /* no CRC is present */
93 #define CHD_V1_SECTOR_SIZE 512 /* size of a "sector" in the V1 header */
95 #define COOKIE_VALUE 0xbaadf00d
96 #define MAX_ZLIB_ALLOCS 64
98 #define END_OF_LIST_COOKIE "EndOfListCookie"
100 #define NO_MATCH (~0)
102 static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
107 V34_MAP_ENTRY_TYPE_INVALID = 0, // invalid type
108 V34_MAP_ENTRY_TYPE_COMPRESSED = 1, // standard compression
109 V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2, // uncompressed data
110 V34_MAP_ENTRY_TYPE_MINI = 3, // mini: use offset as raw data
111 V34_MAP_ENTRY_TYPE_SELF_HUNK = 4, // same as another hunk in this file
112 V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5, // same as a hunk in the parent file
113 V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6 // compressed with secondary algorithm (usually FLAC CDDA)
116 // V5 compression types
120 // these types are live when running
121 COMPRESSION_TYPE_0 = 0,
123 COMPRESSION_TYPE_1 = 1,
125 COMPRESSION_TYPE_2 = 2,
127 COMPRESSION_TYPE_3 = 3,
128 ///< no compression; implicit length = hunkbytes
129 COMPRESSION_NONE = 4,
130 ///< same as another block in this chd
131 COMPRESSION_SELF = 5,
132 ///< same as a hunk's worth of units in the parent chd
133 COMPRESSION_PARENT = 6,
135 ///< start of small RLE run (4-bit length)
136 // these additional pseudo-types are used for compressed encodings:
137 COMPRESSION_RLE_SMALL,
138 ///< start of large RLE run (8-bit length)
139 COMPRESSION_RLE_LARGE,
140 ///< same as the last COMPRESSION_SELF block
142 ///< same as the last COMPRESSION_SELF block + 1
144 ///< same block in the parent
145 COMPRESSION_PARENT_SELF,
146 ///< same as the last COMPRESSION_PARENT block
147 COMPRESSION_PARENT_0,
148 ///< same as the last COMPRESSION_PARENT block + 1
153 /***************************************************************************
155 ***************************************************************************/
157 #define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0)
161 /***************************************************************************
163 ***************************************************************************/
165 /* interface to a codec */
166 typedef struct _codec_interface codec_interface;
167 struct _codec_interface
169 UINT32 compression; /* type of compression */
170 const char *compname; /* name of the algorithm */
171 UINT8 lossy; /* is this a lossy algorithm? */
172 chd_error (*init)(void *codec, UINT32 hunkbytes); /* codec initialize */
173 void (*free)(void *codec); /* codec free */
174 chd_error (*decompress)(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); /* decompress data */
175 chd_error (*config)(void *codec, int param, void *config); /* configure */
179 /* a single map entry */
180 typedef struct _map_entry map_entry;
183 UINT64 offset; /* offset within the file of the data */
184 UINT32 crc; /* 32-bit CRC of the data */
185 UINT32 length; /* length of the data */
186 UINT8 flags; /* misc flags */
190 /* simple linked-list of hunks used for our CRC map */
191 typedef struct _crcmap_entry crcmap_entry;
194 UINT32 hunknum; /* hunk number */
195 crcmap_entry * next; /* next entry in list */
199 /* a single metadata entry */
200 typedef struct _metadata_entry metadata_entry;
201 struct _metadata_entry
203 UINT64 offset; /* offset within the file of the header */
204 UINT64 next; /* offset within the file of the next header */
205 UINT64 prev; /* offset within the file of the previous header */
206 UINT32 length; /* length of the metadata */
207 UINT32 metatag; /* metadata tag */
208 UINT8 flags; /* flag bits */
211 /* codec-private data for the ZLIB codec */
213 typedef struct _zlib_allocator zlib_allocator;
214 struct _zlib_allocator
216 UINT32 * allocptr[MAX_ZLIB_ALLOCS];
219 typedef struct _zlib_codec_data zlib_codec_data;
220 struct _zlib_codec_data
223 zlib_allocator allocator;
226 /* codec-private data for the LZMA codec */
227 #define MAX_LZMA_ALLOCS 64
229 typedef struct _lzma_allocator lzma_allocator;
230 struct _lzma_allocator
232 void *(*Alloc)(void *p, size_t size);
233 void (*Free)(void *p, void *address); /* address can be 0 */
234 void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
235 uint32_t* allocptr[MAX_LZMA_ALLOCS];
238 typedef struct _lzma_codec_data lzma_codec_data;
239 struct _lzma_codec_data
242 lzma_allocator allocator;
245 /* codec-private data for the CDZL codec */
246 typedef struct _cdzl_codec_data cdzl_codec_data;
247 struct _cdzl_codec_data {
249 zlib_codec_data base_decompressor;
250 zlib_codec_data subcode_decompressor;
254 /* codec-private data for the CDLZ codec */
255 typedef struct _cdlz_codec_data cdlz_codec_data;
256 struct _cdlz_codec_data {
258 lzma_codec_data base_decompressor;
259 zlib_codec_data subcode_decompressor;
263 /* codec-private data for the CDFL codec */
264 typedef struct _cdfl_codec_data cdfl_codec_data;
265 struct _cdfl_codec_data {
268 flac_decoder decoder;
270 zlib_allocator allocator;
274 /* internal representation of an open CHD file */
277 UINT32 cookie; /* cookie, should equal COOKIE_VALUE */
279 core_file * file; /* handle to the open core file */
280 UINT8 owns_file; /* flag indicating if this file should be closed on chd_close() */
281 chd_header header; /* header, extracted from file */
283 chd_file * parent; /* pointer to parent file, or NULL */
285 map_entry * map; /* array of map entries */
287 UINT8 * cache; /* hunk cache pointer */
288 UINT32 cachehunk; /* index of currently cached hunk */
290 UINT8 * compare; /* hunk compare pointer */
291 UINT32 comparehunk; /* index of current compare data */
293 UINT8 * compressed; /* pointer to buffer for compressed data */
294 const codec_interface * codecintf[4]; /* interface to the codec */
296 zlib_codec_data zlib_codec_data; /* zlib codec data */
297 cdzl_codec_data cdzl_codec_data; /* cdzl codec data */
298 cdlz_codec_data cdlz_codec_data; /* cdlz codec data */
299 cdfl_codec_data cdfl_codec_data; /* cdfl codec data */
301 crcmap_entry * crcmap; /* CRC map entries */
302 crcmap_entry * crcfree; /* free list CRC entries */
303 crcmap_entry ** crctable; /* table of CRC entries */
305 UINT32 maxhunk; /* maximum hunk accessed */
307 UINT8 compressing; /* are we compressing? */
308 MD5_CTX compmd5; /* running MD5 during compression */
309 SHA1_CTX compsha1; /* running SHA1 during compression */
310 UINT32 comphunk; /* next hunk we will compress */
312 UINT8 verifying; /* are we verifying? */
313 MD5_CTX vermd5; /* running MD5 during verification */
314 SHA1_CTX versha1; /* running SHA1 during verification */
315 UINT32 verhunk; /* next hunk we will verify */
317 UINT32 async_hunknum; /* hunk index for asynchronous operations */
318 void * async_buffer; /* buffer pointer for asynchronous operations */
320 UINT8 * file_cache; /* cache of underlying file */
324 /* a single metadata hash entry */
325 typedef struct _metadata_hash metadata_hash;
326 struct _metadata_hash
328 UINT8 tag[4]; /* tag of the metadata in big-endian */
329 UINT8 sha1[CHD_SHA1_BYTES]; /* hash */
334 /***************************************************************************
336 ***************************************************************************/
338 static const UINT8 nullmd5[CHD_MD5_BYTES] = { 0 };
339 static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };
343 /***************************************************************************
345 ***************************************************************************/
347 /* internal header operations */
348 static chd_error header_validate(const chd_header *header);
349 static chd_error header_read(core_file *file, chd_header *header);
352 /* internal hunk read/write */
353 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum);
354 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest);
356 /* internal map access */
357 static chd_error map_read(chd_file *chd);
359 /* metadata management */
360 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry);
363 /* zlib compression codec */
364 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes);
365 static void zlib_codec_free(void *codec);
366 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
367 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size);
368 static void zlib_fast_free(voidpf opaque, voidpf address);
370 /* lzma compression codec */
371 static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes);
372 static void lzma_codec_free(void *codec);
373 static chd_error lzma_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
375 /* cdzl compression codec */
376 static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
377 static void cdzl_codec_free(void* codec);
378 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
380 /* cdlz compression codec */
381 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes);
382 static void cdlz_codec_free(void* codec);
383 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
385 /* cdfl compression codec */
386 static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
387 static void cdfl_codec_free(void* codec);
388 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
390 //**************************************************************************
391 // LZMA ALLOCATOR HELPER
392 //**************************************************************************
394 void *lzma_fast_alloc(void *p, size_t size);
395 void lzma_fast_free(void *p, void *address);
397 //-------------------------------------------------
398 // lzma_allocator_init
399 //-------------------------------------------------
401 void lzma_allocator_init(void* p)
403 lzma_allocator *codec = (lzma_allocator *)(p);
405 // reset pointer list
406 memset(codec->allocptr, 0, sizeof(codec->allocptr));
407 codec->Alloc = lzma_fast_alloc;
408 codec->Free = lzma_fast_free;
411 //-------------------------------------------------
412 // lzma_allocator_free
413 //-------------------------------------------------
415 void lzma_allocator_free(void* p )
418 lzma_allocator *codec = (lzma_allocator *)(p);
421 for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++)
423 if (codec->allocptr[i] != NULL)
424 free(codec->allocptr[i]);
428 //-------------------------------------------------
429 // lzma_fast_alloc - fast malloc for lzma, which
430 // allocates and frees memory frequently
431 //-------------------------------------------------
433 void *lzma_fast_alloc(void *p, size_t size)
436 uint32_t *addr = NULL;
437 lzma_allocator *codec = (lzma_allocator *)(p);
439 // compute the size, rounding to the nearest 1k
440 size = (size + 0x3ff) & ~0x3ff;
442 // reuse a hunk if we can
443 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
445 uint32_t *ptr = codec->allocptr[scan];
446 if (ptr != NULL && size == *ptr)
448 // set the low bit of the size so we don't match next time
454 // alloc a new one and put it into the list
455 addr = (uint32_t *)malloc(sizeof(uint8_t) * (size + sizeof(uint32_t)));
458 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
460 if (codec->allocptr[scan] == NULL)
462 codec->allocptr[scan] = addr;
467 // set the low bit of the size so we don't match next time
473 //-------------------------------------------------
474 // lzma_fast_free - fast free for lzma, which
475 // allocates and frees memory frequently
476 //-------------------------------------------------
478 void lzma_fast_free(void *p, void *address)
482 lzma_allocator *codec;
486 codec = (lzma_allocator *)(p);
489 ptr = (uint32_t *)(address) - 1;
490 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
492 if (ptr == codec->allocptr[scan])
494 // clear the low bit of the size to allow matches
501 //**************************************************************************
503 //**************************************************************************
506 //-------------------------------------------------
507 // lzma_codec_init - constructor
508 //-------------------------------------------------
510 chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
513 CLzmaEncProps encoder_props;
514 Byte decoder_props[LZMA_PROPS_SIZE];
516 lzma_allocator* alloc;
517 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
519 // construct the decoder
520 LzmaDec_Construct(&lzma_codec->decoder);
522 // FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK
523 // This code assumes that the current version of the encoder imposes the same requirements on the
524 // decoder as the encoder used to produce the file. This is not necessarily true. The format
525 // needs to be changed so the encoder properties are written to the file.
527 // configure the properties like the compressor did
528 LzmaEncProps_Init(&encoder_props);
529 encoder_props.level = 9;
530 encoder_props.reduceSize = hunkbytes;
531 LzmaEncProps_Normalize(&encoder_props);
533 // convert to decoder properties
534 alloc = &lzma_codec->allocator;
535 lzma_allocator_init(alloc);
536 enc = LzmaEnc_Create((ISzAlloc*)alloc);
538 return CHDERR_DECOMPRESSION_ERROR;
539 if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
541 LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc);
542 return CHDERR_DECOMPRESSION_ERROR;
544 props_size = sizeof(decoder_props);
545 if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
547 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
548 return CHDERR_DECOMPRESSION_ERROR;
550 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
552 // do memory allocations
553 if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK)
554 return CHDERR_DECOMPRESSION_ERROR;
561 //-------------------------------------------------
563 //-------------------------------------------------
565 void lzma_codec_free(void* codec)
567 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
570 LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator);
574 //-------------------------------------------------
575 // decompress - decompress data using the LZMA
577 //-------------------------------------------------
579 chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
583 SizeT consumedlen, decodedlen;
585 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
586 LzmaDec_Init(&lzma_codec->decoder);
589 consumedlen = complen;
590 decodedlen = destlen;
591 res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status);
592 if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen)
593 return CHDERR_DECOMPRESSION_ERROR;
598 chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes)
600 cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
603 cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
605 // make sure the CHD's hunk size is an even multiple of the frame size
606 lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
607 zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
609 if (hunkbytes % CD_FRAME_SIZE != 0)
610 return CHDERR_CODEC_ERROR;
615 void cdlz_codec_free(void* codec)
620 chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
623 cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
625 // determine header bytes
626 uint32_t frames = destlen / CD_FRAME_SIZE;
627 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
628 uint32_t ecc_bytes = (frames + 7) / 8;
629 uint32_t header_bytes = ecc_bytes + complen_bytes;
631 // extract compressed length of base
632 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
633 if (complen_bytes > 2)
634 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
637 lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA);
638 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);
640 // reassemble the data
641 for (framenum = 0; framenum < frames; framenum++)
645 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
646 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);
648 // reconstitute the ECC data and sync header
649 sector = &dest[framenum * CD_FRAME_SIZE];
650 if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
652 memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
653 ecc_generate(sector);
662 chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes)
664 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
666 // make sure the CHD's hunk size is an even multiple of the frame size
667 zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
668 zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
670 cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
671 if (hunkbytes % CD_FRAME_SIZE != 0)
672 return CHDERR_CODEC_ERROR;
677 void cdzl_codec_free(void *codec)
682 chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
685 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
687 // determine header bytes
688 uint32_t frames = destlen / CD_FRAME_SIZE;
689 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
690 uint32_t ecc_bytes = (frames + 7) / 8;
691 uint32_t header_bytes = ecc_bytes + complen_bytes;
693 // extract compressed length of base
694 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
695 if (complen_bytes > 2)
696 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
699 zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA);
700 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);
702 // reassemble the data
703 for (framenum = 0; framenum < frames; framenum++)
706 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
707 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);
709 // reconstitute the ECC data and sync header
710 sector = &dest[framenum * CD_FRAME_SIZE];
711 if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
713 memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
714 ecc_generate(sector);
720 //**************************************************************************
721 // CD FLAC DECOMPRESSOR
722 //**************************************************************************
726 //------------------------------------------------------
727 // cdfl_codec_blocksize - return the optimal block size
728 //------------------------------------------------------
730 static uint32_t cdfl_codec_blocksize(uint32_t bytes)
732 // determine FLAC block size, which must be 16-65535
733 // clamp to 2k since that's supposed to be the sweet spot
734 uint32_t hunkbytes = bytes / 4;
735 while (hunkbytes > 2048)
740 chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes)
743 uint16_t native_endian = 0;
744 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
746 cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
748 // make sure the CHD's hunk size is an even multiple of the frame size
749 if (hunkbytes % CD_FRAME_SIZE != 0)
750 return CHDERR_CODEC_ERROR;
752 // determine whether we want native or swapped samples
753 *(uint8_t *)(&native_endian) = 1;
754 cdfl->swap_endian = (native_endian & 1);
757 cdfl->inflater.next_in = (Bytef *)cdfl; // bogus, but that's ok
758 cdfl->inflater.avail_in = 0;
759 //cdfl->allocator.install(cdfl->inflater);
760 cdfl->inflater.zalloc = zlib_fast_alloc;
761 cdfl->inflater.zfree = zlib_fast_free;
762 cdfl->inflater.opaque = &cdfl->allocator;
763 zerr = inflateInit2(&cdfl->inflater, -MAX_WBITS);
766 if (zerr == Z_MEM_ERROR)
767 return CHDERR_OUT_OF_MEMORY;
768 else if (zerr != Z_OK)
769 return CHDERR_CODEC_ERROR;
772 flac_decoder_init(&cdfl->decoder);
777 void cdfl_codec_free(void *codec)
779 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
780 inflateEnd(&cdfl->inflater);
783 chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
787 uint32_t framenum, offset;
788 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
791 uint32_t frames = destlen / CD_FRAME_SIZE;
792 if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
793 return CHDERR_DECOMPRESSION_ERROR;
794 buffer = &cdfl->buffer[0];
795 if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian))
796 return CHDERR_DECOMPRESSION_ERROR;
798 // inflate the subcode data
799 offset = flac_decoder_finish(&cdfl->decoder);
800 cdfl->inflater.next_in = (Bytef *)(src + offset);
801 cdfl->inflater.avail_in = complen - offset;
802 cdfl->inflater.total_in = 0;
803 cdfl->inflater.next_out = &cdfl->buffer[frames * CD_MAX_SECTOR_DATA];
804 cdfl->inflater.avail_out = frames * CD_MAX_SUBCODE_DATA;
805 cdfl->inflater.total_out = 0;
806 zerr = inflateReset(&cdfl->inflater);
808 return CHDERR_DECOMPRESSION_ERROR;
811 zerr = inflate(&cdfl->inflater, Z_FINISH);
812 if (zerr != Z_STREAM_END)
813 return CHDERR_DECOMPRESSION_ERROR;
814 if (cdfl->inflater.total_out != frames * CD_MAX_SUBCODE_DATA)
815 return CHDERR_DECOMPRESSION_ERROR;
817 // reassemble the data
818 for (framenum = 0; framenum < frames; framenum++)
820 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
821 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);
826 /***************************************************************************
828 ***************************************************************************/
830 #define CHD_MAKE_TAG(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
832 // general codecs with CD frontend
833 #define CHD_CODEC_CD_ZLIB CHD_MAKE_TAG('c','d','z','l')
834 #define CHD_CODEC_CD_LZMA CHD_MAKE_TAG('c','d','l','z')
835 #define CHD_CODEC_CD_FLAC CHD_MAKE_TAG('c','d','f','l')
837 static const codec_interface codec_interfaces[] =
839 /* "none" or no compression */
850 /* standard zlib compression */
857 zlib_codec_decompress,
861 /* zlib+ compression */
863 CHDCOMPRESSION_ZLIB_PLUS,
868 zlib_codec_decompress,
872 /* V5 CD zlib compression */
879 cdzl_codec_decompress,
883 /* V5 CD lzma compression */
890 cdlz_codec_decompress,
894 /* V5 CD flac compression */
901 cdfl_codec_decompress,
906 /***************************************************************************
908 ***************************************************************************/
910 /*-------------------------------------------------
911 get_bigendian_uint64 - fetch a UINT64 from
912 the data stream in bigendian order
913 -------------------------------------------------*/
915 static inline UINT64 get_bigendian_uint64(const UINT8 *base)
917 return ((UINT64)base[0] << 56) | ((UINT64)base[1] << 48) | ((UINT64)base[2] << 40) | ((UINT64)base[3] << 32) |
918 ((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
922 /*-------------------------------------------------
923 put_bigendian_uint64 - write a UINT64 to
924 the data stream in bigendian order
925 -------------------------------------------------*/
927 static inline void put_bigendian_uint64(UINT8 *base, UINT64 value)
929 base[0] = value >> 56;
930 base[1] = value >> 48;
931 base[2] = value >> 40;
932 base[3] = value >> 32;
933 base[4] = value >> 24;
934 base[5] = value >> 16;
935 base[6] = value >> 8;
939 /*-------------------------------------------------
940 get_bigendian_uint48 - fetch a UINT48 from
941 the data stream in bigendian order
942 -------------------------------------------------*/
944 static inline UINT64 get_bigendian_uint48(const UINT8 *base)
946 return ((UINT64)base[0] << 40) | ((UINT64)base[1] << 32) |
947 ((UINT64)base[2] << 24) | ((UINT64)base[3] << 16) | ((UINT64)base[4] << 8) | (UINT64)base[5];
950 /*-------------------------------------------------
951 put_bigendian_uint48 - write a UINT48 to
952 the data stream in bigendian order
953 -------------------------------------------------*/
955 static inline void put_bigendian_uint48(UINT8 *base, UINT64 value)
957 value &= 0xffffffffffff;
958 base[0] = value >> 40;
959 base[1] = value >> 32;
960 base[2] = value >> 24;
961 base[3] = value >> 16;
962 base[4] = value >> 8;
965 /*-------------------------------------------------
966 get_bigendian_uint32 - fetch a UINT32 from
967 the data stream in bigendian order
968 -------------------------------------------------*/
970 static inline UINT32 get_bigendian_uint32(const UINT8 *base)
972 return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
976 /*-------------------------------------------------
977 put_bigendian_uint32 - write a UINT32 to
978 the data stream in bigendian order
979 -------------------------------------------------*/
981 static inline void put_bigendian_uint24(UINT8 *base, UINT32 value)
984 base[0] = value >> 16;
985 base[1] = value >> 8;
990 /*-------------------------------------------------
991 put_bigendian_uint24 - write a UINT24 to
992 the data stream in bigendian order
993 -------------------------------------------------*/
995 static inline void put_bigendian_uint32(UINT8 *base, UINT32 value)
998 base[0] = value >> 16;
999 base[1] = value >> 8;
1003 /*-------------------------------------------------
1004 get_bigendian_uint24 - fetch a UINT24 from
1005 the data stream in bigendian order
1006 -------------------------------------------------*/
1008 static inline UINT32 get_bigendian_uint24(const UINT8 *base)
1010 return (base[0] << 16) | (base[1] << 8) | base[2];
1013 /*-------------------------------------------------
1014 get_bigendian_uint16 - fetch a UINT16 from
1015 the data stream in bigendian order
1016 -------------------------------------------------*/
1018 static inline UINT16 get_bigendian_uint16(const UINT8 *base)
1020 return (base[0] << 8) | base[1];
1024 /*-------------------------------------------------
1025 put_bigendian_uint16 - write a UINT16 to
1026 the data stream in bigendian order
1027 -------------------------------------------------*/
1029 static inline void put_bigendian_uint16(UINT8 *base, UINT16 value)
1031 base[0] = value >> 8;
1036 /*-------------------------------------------------
1037 map_extract - extract a single map
1038 entry from the datastream
1039 -------------------------------------------------*/
1041 static inline void map_extract(const UINT8 *base, map_entry *entry)
1043 entry->offset = get_bigendian_uint64(&base[0]);
1044 entry->crc = get_bigendian_uint32(&base[8]);
1045 entry->length = get_bigendian_uint16(&base[12]) | (base[14] << 16);
1046 entry->flags = base[15];
1050 /*-------------------------------------------------
1051 map_assemble - write a single map
1052 entry to the datastream
1053 -------------------------------------------------*/
1055 static inline void map_assemble(UINT8 *base, map_entry *entry)
1057 put_bigendian_uint64(&base[0], entry->offset);
1058 put_bigendian_uint32(&base[8], entry->crc);
1059 put_bigendian_uint16(&base[12], entry->length);
1060 base[14] = entry->length >> 16;
1061 base[15] = entry->flags;
1064 /*-------------------------------------------------
1065 map_size_v5 - calculate CHDv5 map size
1066 -------------------------------------------------*/
1067 static inline int map_size_v5(chd_header* header)
1069 return header->hunkcount * header->mapentrybytes;
1073 /*-------------------------------------------------
1074 crc16 - calculate CRC16 (from hashing.cpp)
1075 -------------------------------------------------*/
1076 uint16_t crc16(const void *data, uint32_t length)
1078 uint16_t crc = 0xffff;
1080 static const uint16_t s_table[256] =
1082 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1083 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1084 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1085 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1086 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1087 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1088 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1089 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1090 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1091 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1092 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1093 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1094 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1095 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1096 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1097 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1098 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1099 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1100 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1101 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1102 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1103 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1104 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1105 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1106 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1107 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1108 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1109 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1110 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1111 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1112 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1113 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1116 const uint8_t *src = (uint8_t*)data;
1118 // fetch the current value into a local and rip through the source data
1119 while (length-- != 0)
1120 crc = (crc << 8) ^ s_table[(crc >> 8) ^ *src++];
1124 /*-------------------------------------------------
1125 decompress_v5_map - decompress the v5 map
1126 -------------------------------------------------*/
1128 static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
1131 uint8_t lastcomp = 0;
1133 uint32_t last_self = 0;
1134 uint64_t last_parent = 0;
1135 struct bitstream* bitbuf;
1142 uint8_t *compressed;
1144 struct huffman_decoder* decoder;
1145 enum huffman_error err;
1148 if (header->mapoffset == 0)
1150 //memset(header->rawmap, 0xff,map_size_v5(header));
1151 return CHDERR_READ_ERROR;
1155 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1156 core_fread(chd->file, rawbuf, sizeof(rawbuf));
1157 mapbytes = get_bigendian_uint32(&rawbuf[0]);
1158 firstoffs = get_bigendian_uint48(&rawbuf[4]);
1159 mapcrc = get_bigendian_uint16(&rawbuf[10]);
1160 lengthbits = rawbuf[12];
1161 selfbits = rawbuf[13];
1162 parentbits = rawbuf[14];
1165 compressed = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes);
1166 core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
1167 core_fread(chd->file, compressed, mapbytes);
1168 bitbuf = create_bitstream(compressed, sizeof(uint8_t) * mapbytes);
1169 header->rawmap = (uint8_t*)malloc(sizeof(uint8_t) * map_size_v5(header));
1171 // first decode the compression types
1172 decoder = create_huffman_decoder(16, 8);
1173 err = huffman_import_tree_rle(decoder, bitbuf);
1174 if (err != HUFFERR_NONE)
1175 return CHDERR_DECOMPRESSION_ERROR;
1176 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1178 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1180 rawmap[0] = lastcomp, repcount--;
1183 uint8_t val = huffman_decode_one(decoder, bitbuf);
1184 if (val == COMPRESSION_RLE_SMALL)
1185 rawmap[0] = lastcomp, repcount = 2 + huffman_decode_one(decoder, bitbuf);
1186 else if (val == COMPRESSION_RLE_LARGE)
1187 rawmap[0] = lastcomp, repcount = 2 + 16 + (huffman_decode_one(decoder, bitbuf) << 4), repcount += huffman_decode_one(decoder, bitbuf);
1189 rawmap[0] = lastcomp = val;
1193 // then iterate through the hunks and extract the needed data
1194 curoffset = firstoffs;
1195 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1197 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1198 uint64_t offset = curoffset;
1199 uint32_t length = 0;
1204 case COMPRESSION_TYPE_0:
1205 case COMPRESSION_TYPE_1:
1206 case COMPRESSION_TYPE_2:
1207 case COMPRESSION_TYPE_3:
1208 curoffset += length = bitstream_read(bitbuf, lengthbits);
1209 crc = bitstream_read(bitbuf, 16);
1212 case COMPRESSION_NONE:
1213 curoffset += length = header->hunkbytes;
1214 crc = bitstream_read(bitbuf, 16);
1217 case COMPRESSION_SELF:
1218 last_self = offset = bitstream_read(bitbuf, selfbits);
1221 case COMPRESSION_PARENT:
1222 offset = bitstream_read(bitbuf, parentbits);
1223 last_parent = offset;
1226 // pseudo-types; convert into base types
1227 case COMPRESSION_SELF_1:
1229 case COMPRESSION_SELF_0:
1230 rawmap[0] = COMPRESSION_SELF;
1234 case COMPRESSION_PARENT_SELF:
1235 rawmap[0] = COMPRESSION_PARENT;
1236 last_parent = offset = ( ((uint64_t)hunknum) * ((uint64_t)header->hunkbytes) ) / header->unitbytes;
1239 case COMPRESSION_PARENT_1:
1240 last_parent += header->hunkbytes / header->unitbytes;
1241 case COMPRESSION_PARENT_0:
1242 rawmap[0] = COMPRESSION_PARENT;
1243 offset = last_parent;
1247 put_bigendian_uint24(&rawmap[1], length);
1250 put_bigendian_uint48(&rawmap[4], offset);
1253 put_bigendian_uint16(&rawmap[10], crc);
1256 // verify the final CRC
1257 if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc)
1258 return CHDERR_DECOMPRESSION_ERROR;
1263 /*-------------------------------------------------
1264 map_extract_old - extract a single map
1265 entry in old format from the datastream
1266 -------------------------------------------------*/
1268 static inline void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 hunkbytes)
1270 entry->offset = get_bigendian_uint64(&base[0]);
1272 entry->length = entry->offset >> 44;
1273 entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
1275 entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
1277 entry->offset = (entry->offset << 20) >> 20;
1282 /***************************************************************************
1284 ***************************************************************************/
1287 /*-------------------------------------------------
1288 chd_open_file - open a CHD file for access
1289 -------------------------------------------------*/
1291 chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd)
1293 chd_file *newchd = NULL;
1297 /* verify parameters */
1299 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1301 /* punt if invalid parent */
1302 if (parent != NULL && parent->cookie != COOKIE_VALUE)
1303 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1305 /* allocate memory for the final result */
1306 newchd = (chd_file *)malloc(sizeof(chd_file));
1308 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1309 memset(newchd, 0, sizeof(chd_file));
1310 newchd->cookie = COOKIE_VALUE;
1311 newchd->parent = parent;
1312 newchd->file = file;
1314 /* now attempt to read the header */
1315 err = header_read(newchd->file, &newchd->header);
1316 if (err != CHDERR_NONE)
1319 /* validate the header */
1320 err = header_validate(&newchd->header);
1321 if (err != CHDERR_NONE)
1324 /* make sure we don't open a read-only file writeable */
1325 if (mode == CHD_OPEN_READWRITE && !(newchd->header.flags & CHDFLAGS_IS_WRITEABLE))
1326 EARLY_EXIT(err = CHDERR_FILE_NOT_WRITEABLE);
1328 /* also, never open an older version writeable */
1329 if (mode == CHD_OPEN_READWRITE && newchd->header.version < CHD_HEADER_VERSION)
1330 EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
1332 /* if we need a parent, make sure we have one */
1333 if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
1334 EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1336 /* make sure we have a valid parent */
1339 /* check MD5 if it isn't empty */
1340 if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1341 memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1342 memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1343 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1345 /* check SHA1 if it isn't empty */
1346 if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1347 memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1348 memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1349 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1352 /* now read the hunk map */
1353 if (newchd->header.version < 5)
1355 err = map_read(newchd);
1356 if (err != CHDERR_NONE)
1361 err = decompress_v5_map(newchd, &(newchd->header));
1364 /* allocate and init the hunk cache */
1365 newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1366 newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1367 if (newchd->cache == NULL || newchd->compare == NULL)
1368 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1369 newchd->cachehunk = ~0;
1370 newchd->comparehunk = ~0;
1372 /* allocate the temporary compressed buffer */
1373 newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1374 if (newchd->compressed == NULL)
1375 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1377 /* find the codec interface */
1378 if (newchd->header.version < 5)
1380 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1381 if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1383 newchd->codecintf[0] = &codec_interfaces[intfnum];
1386 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1387 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1389 /* initialize the codec */
1390 if (newchd->codecintf[0]->init != NULL)
1391 err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1397 // verify the compression types and initialize the codecs
1398 for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1401 for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1403 if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1405 newchd->codecintf[decompnum] = &codec_interfaces[i];
1406 if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1407 err = CHDERR_UNSUPPORTED_FORMAT;
1409 /* initialize the codec */
1410 if (newchd->codecintf[decompnum]->init != NULL)
1413 switch (newchd->header.compression[decompnum])
1415 case CHD_CODEC_CD_ZLIB:
1416 codec = &newchd->cdzl_codec_data;
1419 case CHD_CODEC_CD_LZMA:
1420 codec = &newchd->cdlz_codec_data;
1423 case CHD_CODEC_CD_FLAC:
1424 codec = &newchd->cdfl_codec_data;
1429 err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1438 //if (err != CHDERR_NONE)
1451 /*-------------------------------------------------
1452 chd_open - open a CHD file by
1454 -------------------------------------------------*/
1456 chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1459 core_file *file = NULL;
1462 /* choose the proper mode */
1469 err = CHDERR_INVALID_PARAMETER;
1474 file = core_fopen(filename);
1477 err = CHDERR_FILE_NOT_FOUND;
1481 /* now open the CHD */
1482 err = chd_open_file(file, mode, parent, chd);
1483 if (err != CHDERR_NONE)
1486 /* we now own this file */
1487 (*chd)->owns_file = TRUE;
1490 if ((err != CHDERR_NONE) && (file != NULL))
1495 chd_error chd_precache(chd_file *chd)
1497 ssize_t size, count;
1499 if (chd->file_cache == NULL)
1501 core_fseek(chd->file, 0, SEEK_END);
1502 size = core_ftell(chd->file);
1504 return CHDERR_INVALID_DATA;
1505 chd->file_cache = malloc(size);
1506 if (chd->file_cache == NULL)
1507 return CHDERR_OUT_OF_MEMORY;
1508 core_fseek(chd->file, 0, SEEK_SET);
1509 count = core_fread(chd->file, chd->file_cache, size);
1512 free(chd->file_cache);
1513 chd->file_cache = NULL;
1514 return CHDERR_READ_ERROR;
1521 /*-------------------------------------------------
1522 chd_close - close a CHD file for access
1523 -------------------------------------------------*/
1525 void chd_close(chd_file *chd)
1527 /* punt if NULL or invalid */
1528 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1531 /* deinit the codec */
1532 if (chd->header.version < 5)
1534 if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1535 (*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1541 for (i = 0 ; i < 4 ; i++)
1544 switch (chd->codecintf[i]->compression)
1546 case CHD_CODEC_CD_LZMA:
1547 codec = &chd->cdlz_codec_data;
1550 case CHD_CODEC_CD_ZLIB:
1551 codec = &chd->cdzl_codec_data;
1554 case CHD_CODEC_CD_FLAC:
1555 codec = &chd->cdfl_codec_data;
1560 (*chd->codecintf[i]->free)(codec);
1565 if (chd->header.rawmap != NULL)
1566 free(chd->header.rawmap);
1569 /* free the compressed data buffer */
1570 if (chd->compressed != NULL)
1571 free(chd->compressed);
1573 /* free the hunk cache and compare data */
1574 if (chd->compare != NULL)
1576 if (chd->cache != NULL)
1579 /* free the hunk map */
1580 if (chd->map != NULL)
1583 /* free the CRC table */
1584 if (chd->crctable != NULL)
1585 free(chd->crctable);
1587 /* free the CRC map */
1588 if (chd->crcmap != NULL)
1591 /* close the file */
1592 if (chd->owns_file && chd->file != NULL)
1593 core_fclose(chd->file);
1595 if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1597 if (chd->file_cache)
1598 free(chd->file_cache);
1600 /* free our memory */
1605 /*-------------------------------------------------
1606 chd_core_file - return the associated
1608 -------------------------------------------------*/
1610 core_file *chd_core_file(chd_file *chd)
1616 /*-------------------------------------------------
1617 chd_error_string - return an error string for
1619 -------------------------------------------------*/
1621 const char *chd_error_string(chd_error err)
1625 case CHDERR_NONE: return "no error";
1626 case CHDERR_NO_INTERFACE: return "no drive interface";
1627 case CHDERR_OUT_OF_MEMORY: return "out of memory";
1628 case CHDERR_INVALID_FILE: return "invalid file";
1629 case CHDERR_INVALID_PARAMETER: return "invalid parameter";
1630 case CHDERR_INVALID_DATA: return "invalid data";
1631 case CHDERR_FILE_NOT_FOUND: return "file not found";
1632 case CHDERR_REQUIRES_PARENT: return "requires parent";
1633 case CHDERR_FILE_NOT_WRITEABLE: return "file not writeable";
1634 case CHDERR_READ_ERROR: return "read error";
1635 case CHDERR_WRITE_ERROR: return "write error";
1636 case CHDERR_CODEC_ERROR: return "codec error";
1637 case CHDERR_INVALID_PARENT: return "invalid parent";
1638 case CHDERR_HUNK_OUT_OF_RANGE: return "hunk out of range";
1639 case CHDERR_DECOMPRESSION_ERROR: return "decompression error";
1640 case CHDERR_COMPRESSION_ERROR: return "compression error";
1641 case CHDERR_CANT_CREATE_FILE: return "can't create file";
1642 case CHDERR_CANT_VERIFY: return "can't verify file";
1643 case CHDERR_NOT_SUPPORTED: return "operation not supported";
1644 case CHDERR_METADATA_NOT_FOUND: return "can't find metadata";
1645 case CHDERR_INVALID_METADATA_SIZE: return "invalid metadata size";
1646 case CHDERR_UNSUPPORTED_VERSION: return "unsupported CHD version";
1647 case CHDERR_VERIFY_INCOMPLETE: return "incomplete verify";
1648 case CHDERR_INVALID_METADATA: return "invalid metadata";
1649 case CHDERR_INVALID_STATE: return "invalid state";
1650 case CHDERR_OPERATION_PENDING: return "operation pending";
1651 case CHDERR_NO_ASYNC_OPERATION: return "no async operation in progress";
1652 case CHDERR_UNSUPPORTED_FORMAT: return "unsupported format";
1653 default: return "undocumented error";
1659 /***************************************************************************
1660 CHD HEADER MANAGEMENT
1661 ***************************************************************************/
1663 /*-------------------------------------------------
1664 chd_get_header - return a pointer to the
1665 extracted header data
1666 -------------------------------------------------*/
1668 const chd_header *chd_get_header(chd_file *chd)
1670 /* punt if NULL or invalid */
1671 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1674 return &chd->header;
1679 /***************************************************************************
1680 CORE DATA READ/WRITE
1681 ***************************************************************************/
1683 /*-------------------------------------------------
1684 chd_read - read a single hunk from the CHD
1686 -------------------------------------------------*/
1688 chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1690 /* punt if NULL or invalid */
1691 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1692 return CHDERR_INVALID_PARAMETER;
1694 /* if we're past the end, fail */
1695 if (hunknum >= chd->header.totalhunks)
1696 return CHDERR_HUNK_OUT_OF_RANGE;
1698 /* perform the read */
1699 return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1706 /***************************************************************************
1708 ***************************************************************************/
1710 /*-------------------------------------------------
1711 chd_get_metadata - get the indexed metadata
1713 -------------------------------------------------*/
1715 chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1717 metadata_entry metaentry;
1721 /* if we didn't find it, just return */
1722 err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1723 if (err != CHDERR_NONE)
1725 /* unless we're an old version and they are requesting hard disk metadata */
1726 if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1728 char faux_metadata[256];
1731 /* fill in the faux metadata */
1732 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);
1733 faux_length = (UINT32)strlen(faux_metadata) + 1;
1735 /* copy the metadata itself */
1736 memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1738 /* return the length of the data and the tag */
1739 if (resultlen != NULL)
1740 *resultlen = faux_length;
1741 if (resulttag != NULL)
1742 *resulttag = HARD_DISK_METADATA_TAG;
1748 /* read the metadata */
1749 outputlen = MIN(outputlen, metaentry.length);
1750 core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1751 count = core_fread(chd->file, output, outputlen);
1752 if (count != outputlen)
1753 return CHDERR_READ_ERROR;
1755 /* return the length of the data and the tag */
1756 if (resultlen != NULL)
1757 *resultlen = metaentry.length;
1758 if (resulttag != NULL)
1759 *resulttag = metaentry.metatag;
1760 if (resultflags != NULL)
1761 *resultflags = metaentry.flags;
1767 /***************************************************************************
1769 ***************************************************************************/
1771 /*-------------------------------------------------
1772 chd_codec_config - set internal codec
1774 -------------------------------------------------*/
1776 chd_error chd_codec_config(chd_file *chd, int param, void *config)
1779 return CHDERR_INVALID_PARAMETER;
1783 /*-------------------------------------------------
1784 chd_get_codec_name - get the name of a
1786 -------------------------------------------------*/
1788 const char *chd_get_codec_name(UINT32 codec)
1794 /***************************************************************************
1795 INTERNAL HEADER OPERATIONS
1796 ***************************************************************************/
1798 /*-------------------------------------------------
1799 header_validate - check the validity of a
1801 -------------------------------------------------*/
1803 static chd_error header_validate(const chd_header *header)
1807 /* require a valid version */
1808 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1809 return CHDERR_UNSUPPORTED_VERSION;
1811 /* require a valid length */
1812 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1813 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1814 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1815 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1816 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1817 return CHDERR_INVALID_PARAMETER;
1819 /* Do not validate v5 header */
1820 if (header->version <= 4)
1822 /* require valid flags */
1823 if (header->flags & CHDFLAGS_UNDEFINED)
1824 return CHDERR_INVALID_PARAMETER;
1826 /* require a supported compression mechanism */
1827 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1828 if (codec_interfaces[intfnum].compression == header->compression[0])
1831 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1832 return CHDERR_INVALID_PARAMETER;
1834 /* require a valid hunksize */
1835 if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1836 return CHDERR_INVALID_PARAMETER;
1838 /* require a valid hunk count */
1839 if (header->totalhunks == 0)
1840 return CHDERR_INVALID_PARAMETER;
1842 /* require a valid MD5 and/or SHA1 if we're using a parent */
1843 if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1844 return CHDERR_INVALID_PARAMETER;
1846 /* if we're V3 or later, the obsolete fields must be 0 */
1847 if (header->version >= 3 &&
1848 (header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1849 header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1850 return CHDERR_INVALID_PARAMETER;
1852 /* if we're pre-V3, the obsolete fields must NOT be 0 */
1853 if (header->version < 3 &&
1854 (header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1855 header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1856 return CHDERR_INVALID_PARAMETER;
1863 /*-------------------------------------------------
1864 header_read - read a CHD header into the
1865 internal data structure
1866 -------------------------------------------------*/
1868 static chd_error header_read(core_file *file, chd_header *header)
1870 UINT8 rawheader[CHD_MAX_HEADER_SIZE];
1875 return CHDERR_INVALID_PARAMETER;
1877 /* punt if invalid file */
1879 return CHDERR_INVALID_FILE;
1882 core_fseek(file, 0, SEEK_SET);
1883 count = core_fread(file, rawheader, sizeof(rawheader));
1884 if (count != sizeof(rawheader))
1885 return CHDERR_READ_ERROR;
1887 /* verify the tag */
1888 if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
1889 return CHDERR_INVALID_DATA;
1891 /* extract the direct data */
1892 memset(header, 0, sizeof(*header));
1893 header->length = get_bigendian_uint32(&rawheader[8]);
1894 header->version = get_bigendian_uint32(&rawheader[12]);
1896 /* make sure it's a version we understand */
1897 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1898 return CHDERR_UNSUPPORTED_VERSION;
1900 /* make sure the length is expected */
1901 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1902 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1903 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1904 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1905 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1907 return CHDERR_INVALID_DATA;
1909 /* extract the common data */
1910 header->flags = get_bigendian_uint32(&rawheader[16]);
1911 header->compression[0] = get_bigendian_uint32(&rawheader[20]);
1913 /* extract the V1/V2-specific data */
1914 if (header->version < 3)
1916 int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
1917 header->obsolete_hunksize = get_bigendian_uint32(&rawheader[24]);
1918 header->totalhunks = get_bigendian_uint32(&rawheader[28]);
1919 header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
1920 header->obsolete_heads = get_bigendian_uint32(&rawheader[36]);
1921 header->obsolete_sectors = get_bigendian_uint32(&rawheader[40]);
1922 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
1923 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
1924 header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
1925 header->hunkbytes = seclen * header->obsolete_hunksize;
1926 header->metaoffset = 0;
1929 /* extract the V3-specific data */
1930 else if (header->version == 3)
1932 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
1933 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
1934 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
1935 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
1936 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
1937 header->hunkbytes = get_bigendian_uint32(&rawheader[76]);
1938 memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
1939 memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
1942 /* extract the V4-specific data */
1943 else if (header->version == 4)
1945 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
1946 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
1947 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
1948 header->hunkbytes = get_bigendian_uint32(&rawheader[44]);
1949 memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
1950 memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
1951 memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
1954 /* extract the V5-specific data */
1955 else if (header->version == 5)
1958 header->compression[0] = get_bigendian_uint32(&rawheader[16]);
1959 header->compression[1] = get_bigendian_uint32(&rawheader[20]);
1960 header->compression[2] = get_bigendian_uint32(&rawheader[24]);
1961 header->compression[3] = get_bigendian_uint32(&rawheader[28]);
1962 header->logicalbytes = get_bigendian_uint64(&rawheader[32]);
1963 header->mapoffset = get_bigendian_uint64(&rawheader[40]);
1964 header->metaoffset = get_bigendian_uint64(&rawheader[48]);
1965 header->hunkbytes = get_bigendian_uint32(&rawheader[56]);
1966 header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
1967 header->unitbytes = get_bigendian_uint32(&rawheader[60]);
1968 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
1969 memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
1970 memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
1971 memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
1973 // determine properties of map entries
1974 header->mapentrybytes = 12; //TODO compressed() ? 12 : 4;
1977 header->totalhunks = header->hunkcount;
1980 /* Unknown version */
1986 /* guess it worked */
1991 /***************************************************************************
1992 INTERNAL HUNK READ/WRITE
1993 ***************************************************************************/
1995 /*-------------------------------------------------
1996 hunk_read_into_cache - read a hunk into
1997 the CHD's hunk cache
1998 -------------------------------------------------*/
2000 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2005 if (hunknum > chd->maxhunk)
2006 chd->maxhunk = hunknum;
2008 /* if we're already in the cache, we're done */
2009 if (chd->cachehunk == hunknum)
2011 chd->cachehunk = ~0;
2013 /* otherwise, read the data */
2014 err = hunk_read_into_memory(chd, hunknum, chd->cache);
2015 if (err != CHDERR_NONE)
2018 /* mark the hunk successfully cached in */
2019 chd->cachehunk = hunknum;
2024 static UINT8* read_compressed(chd_file *chd, UINT64 offset, size_t size)
2027 if (chd->file_cache != NULL)
2029 return chd->file_cache + offset;
2033 core_fseek(chd->file, offset, SEEK_SET);
2034 bytes = core_fread(chd->file, chd->compressed, size);
2037 return chd->compressed;
2041 static chd_error read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2044 if (chd->file_cache != NULL)
2046 memcpy(dest, chd->file_cache + offset, size);
2050 core_fseek(chd->file, offset, SEEK_SET);
2051 bytes = core_fread(chd->file, dest, size);
2053 return CHDERR_READ_ERROR;
2058 /*-------------------------------------------------
2059 hunk_read_into_memory - read a hunk into
2060 memory at the given location
2061 -------------------------------------------------*/
2063 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2068 if (chd->file == NULL)
2069 return CHDERR_INVALID_FILE;
2071 /* return an error if out of range */
2072 if (hunknum >= chd->header.totalhunks)
2073 return CHDERR_HUNK_OUT_OF_RANGE;
2075 if (chd->header.version < 5)
2077 map_entry *entry = &chd->map[hunknum];
2080 /* switch off the entry type */
2081 switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2083 /* compressed data */
2084 case V34_MAP_ENTRY_TYPE_COMPRESSED:
2087 UINT8 *bytes = read_compressed(chd, entry->offset, entry->length);
2089 return CHDERR_READ_ERROR;
2091 /* now decompress using the codec */
2093 codec = &chd->zlib_codec_data;
2094 if (chd->codecintf[0]->decompress != NULL)
2095 err = (*chd->codecintf[0]->decompress)(codec, bytes, entry->length, dest, chd->header.hunkbytes);
2096 if (err != CHDERR_NONE)
2101 /* uncompressed data */
2102 case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2103 err = read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2104 if (err != CHDERR_NONE)
2108 /* mini-compressed data */
2109 case V34_MAP_ENTRY_TYPE_MINI:
2110 put_bigendian_uint64(&dest[0], entry->offset);
2111 for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2112 dest[bytes] = dest[bytes - 8];
2115 /* self-referenced data */
2116 case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2117 if (chd->cachehunk == entry->offset && dest == chd->cache)
2119 return hunk_read_into_memory(chd, entry->offset, dest);
2121 /* parent-referenced data */
2122 case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2123 err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2124 if (err != CHDERR_NONE)
2133 // get a pointer to the map entry
2138 uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2141 // uncompressed case
2145 blockoffs = uint64_t(be_read(rawmap, 4)) * uint64_t(m_hunkbytes);
2147 file_read(blockoffs, dest, m_hunkbytes);
2148 else if (m_parent_missing)
2149 throw CHDERR_REQUIRES_PARENT;
2150 else if (m_parent != nullptr)
2151 m_parent->read_hunk(hunknum, dest);
2153 memset(dest, 0, m_hunkbytes);
2158 blocklen = get_bigendian_uint24(&rawmap[1]);
2159 blockoffs = get_bigendian_uint48(&rawmap[4]);
2160 blockcrc = get_bigendian_uint16(&rawmap[10]);
2163 case COMPRESSION_TYPE_0:
2164 case COMPRESSION_TYPE_1:
2165 case COMPRESSION_TYPE_2:
2166 case COMPRESSION_TYPE_3:
2167 bytes = read_compressed(chd, blockoffs, blocklen);
2169 return CHDERR_READ_ERROR;
2170 switch (chd->codecintf[rawmap[0]]->compression)
2172 case CHD_CODEC_CD_LZMA:
2173 codec = &chd->cdlz_codec_data;
2176 case CHD_CODEC_CD_ZLIB:
2177 codec = &chd->cdzl_codec_data;
2180 case CHD_CODEC_CD_FLAC:
2181 codec = &chd->cdfl_codec_data;
2185 return CHDERR_DECOMPRESSION_ERROR;
2186 chd->codecintf[rawmap[0]]->decompress(codec, bytes, blocklen, dest, chd->header.hunkbytes);
2187 if (dest != NULL && crc16(dest, chd->header.hunkbytes) != blockcrc)
2188 return CHDERR_DECOMPRESSION_ERROR;
2191 case COMPRESSION_NONE:
2192 err = read_uncompressed(chd, blockoffs, blocklen, dest);
2193 if (err != CHDERR_NONE)
2195 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2196 return CHDERR_DECOMPRESSION_ERROR;
2199 case COMPRESSION_SELF:
2200 return hunk_read_into_memory(chd, blockoffs, dest);
2202 case COMPRESSION_PARENT:
2204 //if (m_parent_missing)
2205 // return CHDERR_REQUIRES_PARENT;
2206 //return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
2207 return CHDERR_DECOMPRESSION_ERROR;
2212 // We should not reach this code
2213 return CHDERR_DECOMPRESSION_ERROR;
2217 /***************************************************************************
2219 ***************************************************************************/
2221 /*-------------------------------------------------
2222 map_read - read the initial sector map
2223 -------------------------------------------------*/
2225 static chd_error map_read(chd_file *chd)
2227 UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2228 UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2229 UINT64 fileoffset, maxoffset = 0;
2230 UINT8 cookie[MAP_ENTRY_SIZE];
2235 /* first allocate memory */
2236 chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2238 return CHDERR_OUT_OF_MEMORY;
2240 /* read the map entries in in chunks and extract to the map list */
2241 fileoffset = chd->header.length;
2242 for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2244 /* compute how many entries this time */
2245 int entries = chd->header.totalhunks - i, j;
2246 if (entries > MAP_STACK_ENTRIES)
2247 entries = MAP_STACK_ENTRIES;
2249 /* read that many */
2250 core_fseek(chd->file, fileoffset, SEEK_SET);
2251 count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2252 if (count != entries * entrysize)
2254 err = CHDERR_READ_ERROR;
2257 fileoffset += entries * entrysize;
2259 /* process that many */
2260 if (entrysize == MAP_ENTRY_SIZE)
2262 for (j = 0; j < entries; j++)
2263 map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2267 for (j = 0; j < entries; j++)
2268 map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2271 /* track the maximum offset */
2272 for (j = 0; j < entries; j++)
2273 if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2274 (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2275 maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2278 /* verify the cookie */
2279 core_fseek(chd->file, fileoffset, SEEK_SET);
2280 count = core_fread(chd->file, &cookie, entrysize);
2281 if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2283 err = CHDERR_INVALID_FILE;
2287 /* verify the length */
2288 if (maxoffset > core_fsize(chd->file))
2290 err = CHDERR_INVALID_FILE;
2305 /***************************************************************************
2306 INTERNAL METADATA ACCESS
2307 ***************************************************************************/
2309 /*-------------------------------------------------
2310 metadata_find_entry - find a metadata entry
2311 -------------------------------------------------*/
2313 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2315 /* start at the beginning */
2316 metaentry->offset = chd->header.metaoffset;
2317 metaentry->prev = 0;
2319 /* loop until we run out of options */
2320 while (metaentry->offset != 0)
2322 UINT8 raw_meta_header[METADATA_HEADER_SIZE];
2325 /* read the raw header */
2326 core_fseek(chd->file, metaentry->offset, SEEK_SET);
2327 count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2328 if (count != sizeof(raw_meta_header))
2331 /* extract the data */
2332 metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2333 metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2334 metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2336 /* flags are encoded in the high byte of length */
2337 metaentry->flags = metaentry->length >> 24;
2338 metaentry->length &= 0x00ffffff;
2340 /* if we got a match, proceed */
2341 if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2342 if (metaindex-- == 0)
2345 /* no match, fetch the next link */
2346 metaentry->prev = metaentry->offset;
2347 metaentry->offset = metaentry->next;
2350 /* if we get here, we didn't find it */
2351 return CHDERR_METADATA_NOT_FOUND;
2356 /***************************************************************************
2357 ZLIB COMPRESSION CODEC
2358 ***************************************************************************/
2360 /*-------------------------------------------------
2361 zlib_codec_init - initialize the ZLIB codec
2362 -------------------------------------------------*/
2364 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2366 zlib_codec_data *data = (zlib_codec_data*)codec;
2370 /* clear the buffers */
2371 memset(data, 0, sizeof(zlib_codec_data));
2373 /* init the inflater first */
2374 data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */
2375 data->inflater.avail_in = 0;
2376 data->inflater.zalloc = zlib_fast_alloc;
2377 data->inflater.zfree = zlib_fast_free;
2378 data->inflater.opaque = &data->allocator;
2379 zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2381 /* convert errors */
2382 if (zerr == Z_MEM_ERROR)
2383 err = CHDERR_OUT_OF_MEMORY;
2384 else if (zerr != Z_OK)
2385 err = CHDERR_CODEC_ERROR;
2389 /* handle an error */
2390 if (err != CHDERR_NONE)
2397 /*-------------------------------------------------
2398 zlib_codec_free - free data for the ZLIB
2400 -------------------------------------------------*/
2402 static void zlib_codec_free(void *codec)
2404 zlib_codec_data *data = (zlib_codec_data *)codec;
2406 /* deinit the streams */
2410 zlib_allocator alloc;
2412 inflateEnd(&data->inflater);
2414 /* free our fast memory */
2415 alloc = data->allocator;
2416 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2417 if (alloc.allocptr[i])
2418 free(alloc.allocptr[i]);
2423 /*-------------------------------------------------
2424 zlib_codec_decompress - decomrpess data using
2426 -------------------------------------------------*/
2428 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2430 zlib_codec_data *data = (zlib_codec_data *)codec;
2433 /* reset the decompressor */
2434 data->inflater.next_in = (Bytef *)src;
2435 data->inflater.avail_in = complen;
2436 data->inflater.total_in = 0;
2437 data->inflater.next_out = (Bytef *)dest;
2438 data->inflater.avail_out = destlen;
2439 data->inflater.total_out = 0;
2440 zerr = inflateReset(&data->inflater);
2442 return CHDERR_DECOMPRESSION_ERROR;
2445 zerr = inflate(&data->inflater, Z_FINISH);
2446 if (data->inflater.total_out != destlen)
2447 return CHDERR_DECOMPRESSION_ERROR;
2453 /*-------------------------------------------------
2454 zlib_fast_alloc - fast malloc for ZLIB, which
2455 allocates and frees memory frequently
2456 -------------------------------------------------*/
2458 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2460 zlib_allocator *alloc = (zlib_allocator *)opaque;
2464 /* compute the size, rounding to the nearest 1k */
2465 size = (size * items + 0x3ff) & ~0x3ff;
2467 /* reuse a hunk if we can */
2468 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2470 ptr = alloc->allocptr[i];
2471 if (ptr && size == *ptr)
2473 /* set the low bit of the size so we don't match next time */
2479 /* alloc a new one */
2480 ptr = (UINT32 *)malloc(size + sizeof(UINT32));
2484 /* put it into the list */
2485 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2486 if (!alloc->allocptr[i])
2488 alloc->allocptr[i] = ptr;
2492 /* set the low bit of the size so we don't match next time */
2498 /*-------------------------------------------------
2499 zlib_fast_free - fast free for ZLIB, which
2500 allocates and frees memory frequently
2501 -------------------------------------------------*/
2503 static void zlib_fast_free(voidpf opaque, voidpf address)
2505 zlib_allocator *alloc = (zlib_allocator *)opaque;
2506 UINT32 *ptr = (UINT32 *)address - 1;
2510 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2511 if (ptr == alloc->allocptr[i])
2513 /* clear the low bit of the size to allow matches */