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 ***************************************************************************/
58 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
59 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
61 #define SHA1_DIGEST_SIZE 20
63 /***************************************************************************
65 ***************************************************************************/
67 #define PRINTF_MAX_HUNK (0)
69 /***************************************************************************
71 ***************************************************************************/
73 #define MAP_STACK_ENTRIES 512 /* max number of entries to use on the stack */
74 #define MAP_ENTRY_SIZE 16 /* V3 and later */
75 #define OLD_MAP_ENTRY_SIZE 8 /* V1-V2 */
76 #define METADATA_HEADER_SIZE 16 /* metadata header size */
77 #define CRCMAP_HASH_SIZE 4095 /* number of CRC hashtable entries */
79 #define MAP_ENTRY_FLAG_TYPE_MASK 0x0f /* what type of hunk */
80 #define MAP_ENTRY_FLAG_NO_CRC 0x10 /* no CRC is present */
82 #define CHD_V1_SECTOR_SIZE 512 /* size of a "sector" in the V1 header */
84 #define COOKIE_VALUE 0xbaadf00d
85 #define MAX_ZLIB_ALLOCS 64
87 #define END_OF_LIST_COOKIE "EndOfListCookie"
91 static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
93 /* V3-V4 entry types */
96 V34_MAP_ENTRY_TYPE_INVALID = 0, /* invalid type */
97 V34_MAP_ENTRY_TYPE_COMPRESSED = 1, /* standard compression */
98 V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2, /* uncompressed data */
99 V34_MAP_ENTRY_TYPE_MINI = 3, /* mini: use offset as raw data */
100 V34_MAP_ENTRY_TYPE_SELF_HUNK = 4, /* same as another hunk in this file */
101 V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5, /* same as a hunk in the parent file */
102 V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6 /* compressed with secondary algorithm (usually FLAC CDDA) */
105 /* V5 compression types */
109 * these types are live when running */
110 COMPRESSION_TYPE_0 = 0,
112 COMPRESSION_TYPE_1 = 1,
114 COMPRESSION_TYPE_2 = 2,
116 COMPRESSION_TYPE_3 = 3,
117 /* no compression; implicit length = hunkbytes */
118 COMPRESSION_NONE = 4,
119 /* same as another block in this chd */
120 COMPRESSION_SELF = 5,
121 /* same as a hunk's worth of units in the parent chd */
122 COMPRESSION_PARENT = 6,
124 /* start of small RLE run (4-bit length)
125 * these additional pseudo-types are used for compressed encodings: */
126 COMPRESSION_RLE_SMALL,
127 /* start of large RLE run (8-bit length) */
128 COMPRESSION_RLE_LARGE,
129 /* same as the last COMPRESSION_SELF block */
131 /* same as the last COMPRESSION_SELF block + 1 */
133 /* same block in the parent */
134 COMPRESSION_PARENT_SELF,
135 /* same as the last COMPRESSION_PARENT block */
136 COMPRESSION_PARENT_0,
137 /* same as the last COMPRESSION_PARENT block + 1 */
141 /***************************************************************************
143 ***************************************************************************/
145 #define EARLY_EXIT(x) do { (void)(x); goto cleanup; } while (0)
147 /***************************************************************************
149 ***************************************************************************/
151 /* interface to a codec */
152 typedef struct _codec_interface codec_interface;
153 struct _codec_interface
155 UINT32 compression; /* type of compression */
156 const char *compname; /* name of the algorithm */
157 UINT8 lossy; /* is this a lossy algorithm? */
158 chd_error (*init)(void *codec, UINT32 hunkbytes); /* codec initialize */
159 void (*free)(void *codec); /* codec free */
160 chd_error (*decompress)(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); /* decompress data */
161 chd_error (*config)(void *codec, int param, void *config); /* configure */
164 /* a single map entry */
165 typedef struct _map_entry map_entry;
168 UINT64 offset; /* offset within the file of the data */
169 UINT32 crc; /* 32-bit CRC of the data */
170 UINT32 length; /* length of the data */
171 UINT8 flags; /* misc flags */
174 /* simple linked-list of hunks used for our CRC map */
175 typedef struct _crcmap_entry crcmap_entry;
178 UINT32 hunknum; /* hunk number */
179 crcmap_entry * next; /* next entry in list */
182 /* a single metadata entry */
183 typedef struct _metadata_entry metadata_entry;
184 struct _metadata_entry
186 UINT64 offset; /* offset within the file of the header */
187 UINT64 next; /* offset within the file of the next header */
188 UINT64 prev; /* offset within the file of the previous header */
189 UINT32 length; /* length of the metadata */
190 UINT32 metatag; /* metadata tag */
191 UINT8 flags; /* flag bits */
194 /* codec-private data for the ZLIB codec */
196 typedef struct _zlib_allocator zlib_allocator;
197 struct _zlib_allocator
199 UINT32 * allocptr[MAX_ZLIB_ALLOCS];
200 UINT32 * allocptr2[MAX_ZLIB_ALLOCS];
203 typedef struct _zlib_codec_data zlib_codec_data;
204 struct _zlib_codec_data
207 zlib_allocator allocator;
210 /* codec-private data for the LZMA codec */
211 #define MAX_LZMA_ALLOCS 64
213 typedef struct _lzma_allocator lzma_allocator;
214 struct _lzma_allocator
216 void *(*Alloc)(void *p, size_t size);
217 void (*Free)(void *p, void *address); /* address can be 0 */
218 void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
219 uint32_t* allocptr[MAX_LZMA_ALLOCS];
220 uint32_t* allocptr2[MAX_LZMA_ALLOCS];
223 typedef struct _lzma_codec_data lzma_codec_data;
224 struct _lzma_codec_data
227 lzma_allocator allocator;
230 /* codec-private data for the CDZL codec */
231 typedef struct _cdzl_codec_data cdzl_codec_data;
232 struct _cdzl_codec_data {
234 zlib_codec_data base_decompressor;
235 zlib_codec_data subcode_decompressor;
239 /* codec-private data for the CDLZ codec */
240 typedef struct _cdlz_codec_data cdlz_codec_data;
241 struct _cdlz_codec_data {
243 lzma_codec_data base_decompressor;
244 zlib_codec_data subcode_decompressor;
248 /* codec-private data for the CDFL codec */
249 typedef struct _cdfl_codec_data cdfl_codec_data;
250 struct _cdfl_codec_data {
253 flac_decoder decoder;
255 zlib_allocator allocator;
259 /* internal representation of an open CHD file */
262 UINT32 cookie; /* cookie, should equal COOKIE_VALUE */
264 core_file * file; /* handle to the open core file */
265 UINT8 owns_file; /* flag indicating if this file should be closed on chd_close() */
266 chd_header header; /* header, extracted from file */
268 chd_file * parent; /* pointer to parent file, or NULL */
270 map_entry * map; /* array of map entries */
272 UINT8 * cache; /* hunk cache pointer */
273 UINT32 cachehunk; /* index of currently cached hunk */
275 UINT8 * compare; /* hunk compare pointer */
276 UINT32 comparehunk; /* index of current compare data */
278 UINT8 * compressed; /* pointer to buffer for compressed data */
279 const codec_interface * codecintf[4]; /* interface to the codec */
281 zlib_codec_data zlib_codec_data; /* zlib codec data */
282 cdzl_codec_data cdzl_codec_data; /* cdzl codec data */
283 cdlz_codec_data cdlz_codec_data; /* cdlz codec data */
284 cdfl_codec_data cdfl_codec_data; /* cdfl codec data */
286 crcmap_entry * crcmap; /* CRC map entries */
287 crcmap_entry * crcfree; /* free list CRC entries */
288 crcmap_entry ** crctable; /* table of CRC entries */
290 UINT32 maxhunk; /* maximum hunk accessed */
292 UINT8 compressing; /* are we compressing? */
293 MD5_CTX compmd5; /* running MD5 during compression */
294 SHA1_CTX compsha1; /* running SHA1 during compression */
295 UINT32 comphunk; /* next hunk we will compress */
297 UINT8 verifying; /* are we verifying? */
298 MD5_CTX vermd5; /* running MD5 during verification */
299 SHA1_CTX versha1; /* running SHA1 during verification */
300 UINT32 verhunk; /* next hunk we will verify */
302 UINT32 async_hunknum; /* hunk index for asynchronous operations */
303 void * async_buffer; /* buffer pointer for asynchronous operations */
305 UINT8 * file_cache; /* cache of underlying file */
308 /* a single metadata hash entry */
309 typedef struct _metadata_hash metadata_hash;
310 struct _metadata_hash
312 UINT8 tag[4]; /* tag of the metadata in big-endian */
313 UINT8 sha1[CHD_SHA1_BYTES]; /* hash */
316 /***************************************************************************
318 ***************************************************************************/
320 static const UINT8 nullmd5[CHD_MD5_BYTES] = { 0 };
321 static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };
323 /***************************************************************************
325 ***************************************************************************/
327 /* internal header operations */
328 static chd_error header_validate(const chd_header *header);
329 static chd_error header_read(chd_file *chd, chd_header *header);
331 /* internal hunk read/write */
332 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum);
333 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest);
335 /* internal map access */
336 static chd_error map_read(chd_file *chd);
338 /* metadata management */
339 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry);
341 /* zlib compression codec */
342 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes);
343 static void zlib_codec_free(void *codec);
344 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
345 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size);
346 static void zlib_fast_free(voidpf opaque, voidpf address);
347 static void zlib_allocator_free(voidpf opaque);
349 /* lzma compression codec */
350 static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes);
351 static void lzma_codec_free(void *codec);
352 static chd_error lzma_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
354 /* cdzl compression codec */
355 static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
356 static void cdzl_codec_free(void* codec);
357 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
359 /* cdlz compression codec */
360 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes);
361 static void cdlz_codec_free(void* codec);
362 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
364 /* cdfl compression codec */
365 static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
366 static void cdfl_codec_free(void* codec);
367 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
369 /***************************************************************************
370 * LZMA ALLOCATOR HELPER
371 ***************************************************************************
374 void *lzma_fast_alloc(void *p, size_t size);
375 void lzma_fast_free(void *p, void *address);
377 /*-------------------------------------------------
378 * lzma_allocator_init
379 *-------------------------------------------------
382 void lzma_allocator_init(void* p)
384 lzma_allocator *codec = (lzma_allocator *)(p);
386 /* reset pointer list */
387 memset(codec->allocptr, 0, sizeof(codec->allocptr));
388 memset(codec->allocptr2, 0, sizeof(codec->allocptr2));
389 codec->Alloc = lzma_fast_alloc;
390 codec->Free = lzma_fast_free;
393 /*-------------------------------------------------
394 * lzma_allocator_free
395 *-------------------------------------------------
398 void lzma_allocator_free(void* p )
401 lzma_allocator *codec = (lzma_allocator *)(p);
403 /* free our memory */
404 for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++)
406 if (codec->allocptr[i] != NULL)
407 free(codec->allocptr[i]);
411 /*-------------------------------------------------
412 * lzma_fast_alloc - fast malloc for lzma, which
413 * allocates and frees memory frequently
414 *-------------------------------------------------
417 #define LZMA_MIN_ALIGNMENT_BITS 512
418 #define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
419 void *lzma_fast_alloc(void *p, size_t size)
422 uint32_t *addr = NULL;
423 lzma_allocator *codec = (lzma_allocator *)(p);
427 /* compute the size, rounding to the nearest 1k */
428 size = (size + 0x3ff) & ~0x3ff;
430 /* reuse a hunk if we can */
431 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
433 uint32_t *ptr = codec->allocptr[scan];
434 if (ptr != NULL && size == *ptr)
436 /* set the low bit of the size so we don't match next time */
438 return codec->allocptr2[scan];
442 /* alloc a new one and put it into the list */
443 addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
446 for (int scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
448 if (codec->allocptr[scan] == NULL)
450 codec->allocptr[scan] = addr;
451 vaddr = (uintptr_t)addr;
452 vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1));
453 codec->allocptr2[scan] = (uint32_t*)vaddr;
458 /* set the low bit of the size so we don't match next time */
463 /*-------------------------------------------------
464 * lzma_fast_free - fast free for lzma, which
465 * allocates and frees memory frequently
466 *-------------------------------------------------
469 void lzma_fast_free(void *p, void *address)
472 uint32_t *ptr = NULL;
473 lzma_allocator *codec = NULL;
478 codec = (lzma_allocator *)(p);
481 ptr = (uint32_t *)address;
482 for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
484 if (ptr == codec->allocptr2[scan])
486 /* clear the low bit of the size to allow matches */
487 *codec->allocptr[scan] &= ~1;
493 /***************************************************************************
495 ***************************************************************************
498 /*-------------------------------------------------
499 * lzma_codec_init - constructor
500 *-------------------------------------------------
503 chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
506 CLzmaEncProps encoder_props;
507 Byte decoder_props[LZMA_PROPS_SIZE];
509 lzma_allocator* alloc;
510 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
512 /* construct the decoder */
513 LzmaDec_Construct(&lzma_codec->decoder);
515 /* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK
516 * This code assumes that the current version of the encoder imposes the same requirements on the
517 * decoder as the encoder used to produce the file. This is not necessarily true. The format
518 * needs to be changed so the encoder properties are written to the file.
520 * configure the properties like the compressor did */
521 LzmaEncProps_Init(&encoder_props);
522 encoder_props.level = 9;
523 encoder_props.reduceSize = hunkbytes;
524 LzmaEncProps_Normalize(&encoder_props);
526 /* convert to decoder properties */
527 alloc = &lzma_codec->allocator;
528 lzma_allocator_init(alloc);
529 enc = LzmaEnc_Create((ISzAlloc*)alloc);
531 return CHDERR_DECOMPRESSION_ERROR;
532 if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
534 LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc);
535 return CHDERR_DECOMPRESSION_ERROR;
537 props_size = sizeof(decoder_props);
538 if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
540 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
541 return CHDERR_DECOMPRESSION_ERROR;
543 LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
545 /* do memory allocations */
546 if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK)
547 return CHDERR_DECOMPRESSION_ERROR;
553 /*-------------------------------------------------
555 *-------------------------------------------------
558 void lzma_codec_free(void* codec)
560 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
563 LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator);
564 lzma_allocator_free(&lzma_codec->allocator);
567 /*-------------------------------------------------
568 * decompress - decompress data using the LZMA
570 *-------------------------------------------------
573 chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
577 SizeT consumedlen, decodedlen;
579 lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
580 LzmaDec_Init(&lzma_codec->decoder);
583 consumedlen = complen;
584 decodedlen = destlen;
585 res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status);
586 if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen)
587 return CHDERR_DECOMPRESSION_ERROR;
592 chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes)
594 cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
596 /* allocate buffer */
597 cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
599 /* make sure the CHD's hunk size is an even multiple of the frame size */
600 lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
601 zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
603 if (hunkbytes % CD_FRAME_SIZE != 0)
604 return CHDERR_CODEC_ERROR;
609 void cdlz_codec_free(void* codec)
611 cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
613 lzma_codec_free(&cdlz->base_decompressor);
614 zlib_codec_free(&cdlz->subcode_decompressor);
617 chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
620 cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
622 /* determine header bytes */
623 uint32_t frames = destlen / CD_FRAME_SIZE;
624 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
625 uint32_t ecc_bytes = (frames + 7) / 8;
626 uint32_t header_bytes = ecc_bytes + complen_bytes;
628 /* extract compressed length of base */
629 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
630 if (complen_bytes > 2)
631 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
633 /* reset and decode */
634 lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA);
635 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);
637 /* reassemble the data */
638 for (framenum = 0; framenum < frames; framenum++)
642 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
643 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);
645 /* reconstitute the ECC data and sync header */
646 sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
647 if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
649 memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
650 ecc_generate(sector);
658 chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes)
660 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
662 /* make sure the CHD's hunk size is an even multiple of the frame size */
663 zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
664 zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
666 cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
667 if (hunkbytes % CD_FRAME_SIZE != 0)
668 return CHDERR_CODEC_ERROR;
673 void cdzl_codec_free(void *codec)
675 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
676 zlib_codec_free(&cdzl->base_decompressor);
677 zlib_codec_free(&cdzl->subcode_decompressor);
681 chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
684 cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
686 /* determine header bytes */
687 uint32_t frames = destlen / CD_FRAME_SIZE;
688 uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
689 uint32_t ecc_bytes = (frames + 7) / 8;
690 uint32_t header_bytes = ecc_bytes + complen_bytes;
692 /* extract compressed length of base */
693 uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
694 if (complen_bytes > 2)
695 complen_base = (complen_base << 8) | src[ecc_bytes + 2];
697 /* reset and decode */
698 zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA);
699 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);
701 /* reassemble the data */
702 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 = (uint8_t *)&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 ***************************************************************************
725 /*------------------------------------------------------
726 * cdfl_codec_blocksize - return the optimal block size
727 *------------------------------------------------------
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);
756 /* init the inflater */
757 cdfl->inflater.next_in = (Bytef *)cdfl; /* bogus, but that's ok */
758 cdfl->inflater.avail_in = 0;
760 cdfl->allocator.install(cdfl->inflater);
762 cdfl->inflater.zalloc = zlib_fast_alloc;
763 cdfl->inflater.zfree = zlib_fast_free;
764 cdfl->inflater.opaque = &cdfl->allocator;
765 zerr = inflateInit2(&cdfl->inflater, -MAX_WBITS);
768 if (zerr == Z_MEM_ERROR)
769 return CHDERR_OUT_OF_MEMORY;
770 else if (zerr != Z_OK)
771 return CHDERR_CODEC_ERROR;
773 /* flac decoder init */
774 flac_decoder_init(&cdfl->decoder);
778 void cdfl_codec_free(void *codec)
780 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
782 inflateEnd(&cdfl->inflater);
783 flac_decoder_free(&cdfl->decoder);
785 /* free our fast memory */
786 zlib_allocator_free(&cdfl->allocator);
789 chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
793 uint32_t framenum, offset;
794 cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
796 /* reset and decode */
797 uint32_t frames = destlen / CD_FRAME_SIZE;
799 if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
800 return CHDERR_DECOMPRESSION_ERROR;
801 buffer = &cdfl->buffer[0];
802 if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian))
803 return CHDERR_DECOMPRESSION_ERROR;
805 /* inflate the subcode data */
806 offset = flac_decoder_finish(&cdfl->decoder);
807 cdfl->inflater.next_in = (Bytef *)(src + offset);
808 cdfl->inflater.avail_in = complen - offset;
809 cdfl->inflater.total_in = 0;
810 cdfl->inflater.next_out = &cdfl->buffer[frames * CD_MAX_SECTOR_DATA];
811 cdfl->inflater.avail_out = frames * CD_MAX_SUBCODE_DATA;
812 cdfl->inflater.total_out = 0;
813 zerr = inflateReset(&cdfl->inflater);
815 return CHDERR_DECOMPRESSION_ERROR;
818 zerr = inflate(&cdfl->inflater, Z_FINISH);
819 if (zerr != Z_STREAM_END)
820 return CHDERR_DECOMPRESSION_ERROR;
821 if (cdfl->inflater.total_out != frames * CD_MAX_SUBCODE_DATA)
822 return CHDERR_DECOMPRESSION_ERROR;
824 /* reassemble the data */
825 for (framenum = 0; framenum < frames; framenum++)
827 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
828 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);
833 /***************************************************************************
835 ***************************************************************************/
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 zlib compression */
879 zlib_codec_decompress,
883 /* V5 CD zlib compression */
890 cdzl_codec_decompress,
894 /* V5 CD lzma compression */
901 cdlz_codec_decompress,
905 /* V5 CD flac compression */
912 cdfl_codec_decompress,
917 /***************************************************************************
919 ***************************************************************************/
921 /*-------------------------------------------------
922 get_bigendian_uint64 - fetch a UINT64 from
923 the data stream in bigendian order
924 -------------------------------------------------*/
926 static inline UINT64 get_bigendian_uint64(const UINT8 *base)
928 return ((UINT64)base[0] << 56) | ((UINT64)base[1] << 48) | ((UINT64)base[2] << 40) | ((UINT64)base[3] << 32) |
929 ((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
932 /*-------------------------------------------------
933 put_bigendian_uint64 - write a UINT64 to
934 the data stream in bigendian order
935 -------------------------------------------------*/
937 static inline void put_bigendian_uint64(UINT8 *base, UINT64 value)
939 base[0] = value >> 56;
940 base[1] = value >> 48;
941 base[2] = value >> 40;
942 base[3] = value >> 32;
943 base[4] = value >> 24;
944 base[5] = value >> 16;
945 base[6] = value >> 8;
949 /*-------------------------------------------------
950 get_bigendian_uint48 - fetch a UINT48 from
951 the data stream in bigendian order
952 -------------------------------------------------*/
954 static inline UINT64 get_bigendian_uint48(const UINT8 *base)
956 return ((UINT64)base[0] << 40) | ((UINT64)base[1] << 32) |
957 ((UINT64)base[2] << 24) | ((UINT64)base[3] << 16) | ((UINT64)base[4] << 8) | (UINT64)base[5];
960 /*-------------------------------------------------
961 put_bigendian_uint48 - write a UINT48 to
962 the data stream in bigendian order
963 -------------------------------------------------*/
965 static inline void put_bigendian_uint48(UINT8 *base, UINT64 value)
967 value &= 0xffffffffffff;
968 base[0] = value >> 40;
969 base[1] = value >> 32;
970 base[2] = value >> 24;
971 base[3] = value >> 16;
972 base[4] = value >> 8;
975 /*-------------------------------------------------
976 get_bigendian_uint32 - fetch a UINT32 from
977 the data stream in bigendian order
978 -------------------------------------------------*/
980 static inline UINT32 get_bigendian_uint32(const UINT8 *base)
982 return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
985 /*-------------------------------------------------
986 put_bigendian_uint32 - write a UINT32 to
987 the data stream in bigendian order
988 -------------------------------------------------*/
990 static inline void put_bigendian_uint32(UINT8 *base, UINT32 value)
992 base[0] = value >> 24;
993 base[1] = value >> 16;
994 base[2] = value >> 8;
998 /*-------------------------------------------------
999 put_bigendian_uint24 - write a UINT24 to
1000 the data stream in bigendian order
1001 -------------------------------------------------*/
1003 static inline void put_bigendian_uint24(UINT8 *base, UINT32 value)
1006 base[0] = value >> 16;
1007 base[1] = value >> 8;
1011 /*-------------------------------------------------
1012 get_bigendian_uint24 - fetch a UINT24 from
1013 the data stream in bigendian order
1014 -------------------------------------------------*/
1016 static inline UINT32 get_bigendian_uint24(const UINT8 *base)
1018 return (base[0] << 16) | (base[1] << 8) | base[2];
1021 /*-------------------------------------------------
1022 get_bigendian_uint16 - fetch a UINT16 from
1023 the data stream in bigendian order
1024 -------------------------------------------------*/
1026 static inline UINT16 get_bigendian_uint16(const UINT8 *base)
1028 return (base[0] << 8) | base[1];
1031 /*-------------------------------------------------
1032 put_bigendian_uint16 - write a UINT16 to
1033 the data stream in bigendian order
1034 -------------------------------------------------*/
1036 static inline void put_bigendian_uint16(UINT8 *base, UINT16 value)
1038 base[0] = value >> 8;
1042 /*-------------------------------------------------
1043 map_extract - extract a single map
1044 entry from the datastream
1045 -------------------------------------------------*/
1047 static inline void map_extract(const UINT8 *base, map_entry *entry)
1049 entry->offset = get_bigendian_uint64(&base[0]);
1050 entry->crc = get_bigendian_uint32(&base[8]);
1051 entry->length = get_bigendian_uint16(&base[12]) | (base[14] << 16);
1052 entry->flags = base[15];
1055 /*-------------------------------------------------
1056 map_assemble - write a single map
1057 entry to the datastream
1058 -------------------------------------------------*/
1060 static inline void map_assemble(UINT8 *base, map_entry *entry)
1062 put_bigendian_uint64(&base[0], entry->offset);
1063 put_bigendian_uint32(&base[8], entry->crc);
1064 put_bigendian_uint16(&base[12], entry->length);
1065 base[14] = entry->length >> 16;
1066 base[15] = entry->flags;
1069 /*-------------------------------------------------
1070 map_size_v5 - calculate CHDv5 map size
1071 -------------------------------------------------*/
1072 static inline int map_size_v5(chd_header* header)
1074 return header->hunkcount * header->mapentrybytes;
1077 /*-------------------------------------------------
1078 crc16 - calculate CRC16 (from hashing.cpp)
1079 -------------------------------------------------*/
1080 uint16_t crc16(const void *data, uint32_t length)
1082 uint16_t crc = 0xffff;
1084 static const uint16_t s_table[256] =
1086 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1087 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1088 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1089 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1090 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1091 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1092 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1093 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1094 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1095 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1096 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1097 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1098 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1099 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1100 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1101 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1102 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1103 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1104 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1105 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1106 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1107 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1108 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1109 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1110 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1111 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1112 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1113 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1114 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1115 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1116 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1117 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1120 const uint8_t *src = (uint8_t*)data;
1122 /* fetch the current value into a local and rip through the source data */
1123 while (length-- != 0)
1124 crc = (crc << 8) ^ s_table[(crc >> 8) ^ *src++];
1128 /*-------------------------------------------------
1129 compressed - test if CHD file is compressed
1130 +-------------------------------------------------*/
1132 static inline int chd_compressed(chd_header* header) {
1133 return header->compression[0] != CHD_CODEC_NONE;
1136 /*-------------------------------------------------
1137 decompress_v5_map - decompress the v5 map
1138 -------------------------------------------------*/
1140 static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
1145 uint8_t lastcomp = 0;
1146 uint32_t last_self = 0;
1147 uint64_t last_parent = 0;
1148 struct bitstream* bitbuf;
1155 uint8_t *compressed_ptr;
1157 struct huffman_decoder* decoder;
1158 enum huffman_error err;
1160 int rawmapsize = map_size_v5(header);
1162 if (!chd_compressed(header))
1164 header->rawmap = (uint8_t*)malloc(rawmapsize);
1166 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1167 result = core_fread(chd->file, header->rawmap, rawmapsize);
1171 /* read the reader */
1172 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1173 result = core_fread(chd->file, rawbuf, sizeof(rawbuf));
1174 mapbytes = get_bigendian_uint32(&rawbuf[0]);
1175 firstoffs = get_bigendian_uint48(&rawbuf[4]);
1176 mapcrc = get_bigendian_uint16(&rawbuf[10]);
1177 lengthbits = rawbuf[12];
1178 selfbits = rawbuf[13];
1179 parentbits = rawbuf[14];
1181 /* now read the map */
1182 compressed_ptr = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes);
1183 core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
1184 result = core_fread(chd->file, compressed_ptr, mapbytes);
1185 bitbuf = create_bitstream(compressed_ptr, sizeof(uint8_t) * mapbytes);
1186 header->rawmap = (uint8_t*)malloc(rawmapsize);
1188 /* first decode the compression types */
1189 decoder = create_huffman_decoder(16, 8);
1190 err = huffman_import_tree_rle(decoder, bitbuf);
1191 if (err != HUFFERR_NONE)
1192 return CHDERR_DECOMPRESSION_ERROR;
1193 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1195 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1197 rawmap[0] = lastcomp, repcount--;
1200 uint8_t val = huffman_decode_one(decoder, bitbuf);
1201 if (val == COMPRESSION_RLE_SMALL)
1202 rawmap[0] = lastcomp, repcount = 2 + huffman_decode_one(decoder, bitbuf);
1203 else if (val == COMPRESSION_RLE_LARGE)
1204 rawmap[0] = lastcomp, repcount = 2 + 16 + (huffman_decode_one(decoder, bitbuf) << 4), repcount += huffman_decode_one(decoder, bitbuf);
1206 rawmap[0] = lastcomp = val;
1210 /* then iterate through the hunks and extract the needed data */
1211 curoffset = firstoffs;
1212 for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1214 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1215 uint64_t offset = curoffset;
1216 uint32_t length = 0;
1221 case COMPRESSION_TYPE_0:
1222 case COMPRESSION_TYPE_1:
1223 case COMPRESSION_TYPE_2:
1224 case COMPRESSION_TYPE_3:
1225 curoffset += length = bitstream_read(bitbuf, lengthbits);
1226 crc = bitstream_read(bitbuf, 16);
1229 case COMPRESSION_NONE:
1230 curoffset += length = header->hunkbytes;
1231 crc = bitstream_read(bitbuf, 16);
1234 case COMPRESSION_SELF:
1235 last_self = offset = bitstream_read(bitbuf, selfbits);
1238 case COMPRESSION_PARENT:
1239 offset = bitstream_read(bitbuf, parentbits);
1240 last_parent = offset;
1243 /* pseudo-types; convert into base types */
1244 case COMPRESSION_SELF_1:
1246 case COMPRESSION_SELF_0:
1247 rawmap[0] = COMPRESSION_SELF;
1251 case COMPRESSION_PARENT_SELF:
1252 rawmap[0] = COMPRESSION_PARENT;
1253 last_parent = offset = ( ((uint64_t)hunknum) * ((uint64_t)header->hunkbytes) ) / header->unitbytes;
1256 case COMPRESSION_PARENT_1:
1257 last_parent += header->hunkbytes / header->unitbytes;
1258 case COMPRESSION_PARENT_0:
1259 rawmap[0] = COMPRESSION_PARENT;
1260 offset = last_parent;
1264 put_bigendian_uint24(&rawmap[1], length);
1267 put_bigendian_uint48(&rawmap[4], offset);
1270 put_bigendian_uint16(&rawmap[10], crc);
1273 free(compressed_ptr);
1275 free(decoder->lookup);
1276 free(decoder->huffnode);
1279 /* verify the final CRC */
1280 if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc)
1281 return CHDERR_DECOMPRESSION_ERROR;
1286 /*-------------------------------------------------
1287 map_extract_old - extract a single map
1288 entry in old format from the datastream
1289 -------------------------------------------------*/
1291 static inline void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 hunkbytes)
1293 entry->offset = get_bigendian_uint64(&base[0]);
1295 entry->length = entry->offset >> 44;
1296 entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
1298 entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
1300 entry->offset = (entry->offset << 20) >> 20;
1304 /***************************************************************************
1306 ***************************************************************************/
1308 /*-------------------------------------------------
1309 chd_open_file - open a CHD file for access
1310 -------------------------------------------------*/
1312 chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd)
1314 chd_file *newchd = NULL;
1318 /* verify parameters */
1320 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1322 /* punt if invalid parent */
1323 if (parent != NULL && parent->cookie != COOKIE_VALUE)
1324 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1326 /* allocate memory for the final result */
1327 newchd = (chd_file *)malloc(sizeof(**chd));
1329 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1330 memset(newchd, 0, sizeof(*newchd));
1331 newchd->cookie = COOKIE_VALUE;
1332 newchd->parent = parent;
1333 newchd->file = file;
1335 /* now attempt to read the header */
1336 err = header_read(newchd, &newchd->header);
1337 if (err != CHDERR_NONE)
1340 /* validate the header */
1341 err = header_validate(&newchd->header);
1342 if (err != CHDERR_NONE)
1345 /* make sure we don't open a read-only file writeable */
1346 if (mode == CHD_OPEN_READWRITE && !(newchd->header.flags & CHDFLAGS_IS_WRITEABLE))
1347 EARLY_EXIT(err = CHDERR_FILE_NOT_WRITEABLE);
1349 /* also, never open an older version writeable */
1350 if (mode == CHD_OPEN_READWRITE && newchd->header.version < CHD_HEADER_VERSION)
1351 EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
1353 /* if we need a parent, make sure we have one */
1354 if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
1355 EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1357 /* make sure we have a valid parent */
1360 /* check MD5 if it isn't empty */
1361 if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1362 memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1363 memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1364 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1366 /* check SHA1 if it isn't empty */
1367 if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1368 memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1369 memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1370 EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1373 /* now read the hunk map */
1374 if (newchd->header.version < 5)
1376 err = map_read(newchd);
1380 err = decompress_v5_map(newchd, &(newchd->header));
1382 if (err != CHDERR_NONE)
1386 /* allocate and init the hunk cache */
1387 newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1388 newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1389 if (newchd->cache == NULL || newchd->compare == NULL)
1390 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1391 newchd->cachehunk = ~0;
1392 newchd->comparehunk = ~0;
1394 /* allocate the temporary compressed buffer */
1395 newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1396 if (newchd->compressed == NULL)
1397 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1399 /* find the codec interface */
1400 if (newchd->header.version < 5)
1402 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1404 if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1406 newchd->codecintf[0] = &codec_interfaces[intfnum];
1411 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1412 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1414 /* initialize the codec */
1415 if (newchd->codecintf[0]->init != NULL)
1417 err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1418 if (err != CHDERR_NONE)
1425 /* verify the compression types and initialize the codecs */
1426 for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1429 for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1431 if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1433 newchd->codecintf[decompnum] = &codec_interfaces[i];
1438 if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1439 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1441 /* initialize the codec */
1442 if (newchd->codecintf[decompnum]->init != NULL)
1445 switch (newchd->header.compression[decompnum])
1447 case CHD_CODEC_ZLIB:
1448 codec = &newchd->zlib_codec_data;
1451 case CHD_CODEC_CD_ZLIB:
1452 codec = &newchd->cdzl_codec_data;
1455 case CHD_CODEC_CD_LZMA:
1456 codec = &newchd->cdlz_codec_data;
1459 case CHD_CODEC_CD_FLAC:
1460 codec = &newchd->cdfl_codec_data;
1465 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1467 err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1468 if (err != CHDERR_NONE)
1484 /*-------------------------------------------------
1485 chd_precache - precache underlying file in
1487 -------------------------------------------------*/
1489 chd_error chd_precache(chd_file *chd)
1491 ssize_t size, count;
1493 if (chd->file_cache == NULL)
1495 core_fseek(chd->file, 0, SEEK_END);
1496 size = core_ftell(chd->file);
1498 return CHDERR_INVALID_DATA;
1499 chd->file_cache = malloc(size);
1500 if (chd->file_cache == NULL)
1501 return CHDERR_OUT_OF_MEMORY;
1502 core_fseek(chd->file, 0, SEEK_SET);
1503 count = core_fread(chd->file, chd->file_cache, size);
1506 free(chd->file_cache);
1507 chd->file_cache = NULL;
1508 return CHDERR_READ_ERROR;
1515 /*-------------------------------------------------
1516 chd_open - open a CHD file by
1518 -------------------------------------------------*/
1520 chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1523 core_file *file = NULL;
1526 /* choose the proper mode */
1533 err = CHDERR_INVALID_PARAMETER;
1538 file = core_fopen(filename);
1541 err = CHDERR_FILE_NOT_FOUND;
1545 /* now open the CHD */
1546 err = chd_open_file(file, mode, parent, chd);
1547 if (err != CHDERR_NONE)
1550 /* we now own this file */
1551 (*chd)->owns_file = TRUE;
1554 if ((err != CHDERR_NONE) && (file != NULL))
1559 /*-------------------------------------------------
1560 chd_close - close a CHD file for access
1561 -------------------------------------------------*/
1563 void chd_close(chd_file *chd)
1565 /* punt if NULL or invalid */
1566 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1569 /* deinit the codec */
1570 if (chd->header.version < 5)
1572 if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1573 (*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1578 /* Free the codecs */
1579 for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
1583 if (chd->codecintf[i] == NULL)
1586 switch (chd->codecintf[i]->compression)
1588 case CHD_CODEC_CD_LZMA:
1589 codec = &chd->cdlz_codec_data;
1592 case CHD_CODEC_ZLIB:
1593 codec = &chd->zlib_codec_data;
1596 case CHD_CODEC_CD_ZLIB:
1597 codec = &chd->cdzl_codec_data;
1600 case CHD_CODEC_CD_FLAC:
1601 codec = &chd->cdfl_codec_data;
1607 (*chd->codecintf[i]->free)(codec);
1611 /* Free the raw map */
1612 if (chd->header.rawmap != NULL)
1613 free(chd->header.rawmap);
1616 /* free the compressed data buffer */
1617 if (chd->compressed != NULL)
1618 free(chd->compressed);
1620 /* free the hunk cache and compare data */
1621 if (chd->compare != NULL)
1623 if (chd->cache != NULL)
1626 /* free the hunk map */
1627 if (chd->map != NULL)
1630 /* free the CRC table */
1631 if (chd->crctable != NULL)
1632 free(chd->crctable);
1634 /* free the CRC map */
1635 if (chd->crcmap != NULL)
1638 /* close the file */
1639 if (chd->owns_file && chd->file != NULL)
1640 core_fclose(chd->file);
1642 if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1644 if (chd->file_cache)
1645 free(chd->file_cache);
1647 /* free our memory */
1651 /*-------------------------------------------------
1652 chd_core_file - return the associated
1654 -------------------------------------------------*/
1656 core_file *chd_core_file(chd_file *chd)
1661 /*-------------------------------------------------
1662 chd_error_string - return an error string for
1664 -------------------------------------------------*/
1666 const char *chd_error_string(chd_error err)
1670 case CHDERR_NONE: return "no error";
1671 case CHDERR_NO_INTERFACE: return "no drive interface";
1672 case CHDERR_OUT_OF_MEMORY: return "out of memory";
1673 case CHDERR_INVALID_FILE: return "invalid file";
1674 case CHDERR_INVALID_PARAMETER: return "invalid parameter";
1675 case CHDERR_INVALID_DATA: return "invalid data";
1676 case CHDERR_FILE_NOT_FOUND: return "file not found";
1677 case CHDERR_REQUIRES_PARENT: return "requires parent";
1678 case CHDERR_FILE_NOT_WRITEABLE: return "file not writeable";
1679 case CHDERR_READ_ERROR: return "read error";
1680 case CHDERR_WRITE_ERROR: return "write error";
1681 case CHDERR_CODEC_ERROR: return "codec error";
1682 case CHDERR_INVALID_PARENT: return "invalid parent";
1683 case CHDERR_HUNK_OUT_OF_RANGE: return "hunk out of range";
1684 case CHDERR_DECOMPRESSION_ERROR: return "decompression error";
1685 case CHDERR_COMPRESSION_ERROR: return "compression error";
1686 case CHDERR_CANT_CREATE_FILE: return "can't create file";
1687 case CHDERR_CANT_VERIFY: return "can't verify file";
1688 case CHDERR_NOT_SUPPORTED: return "operation not supported";
1689 case CHDERR_METADATA_NOT_FOUND: return "can't find metadata";
1690 case CHDERR_INVALID_METADATA_SIZE: return "invalid metadata size";
1691 case CHDERR_UNSUPPORTED_VERSION: return "unsupported CHD version";
1692 case CHDERR_VERIFY_INCOMPLETE: return "incomplete verify";
1693 case CHDERR_INVALID_METADATA: return "invalid metadata";
1694 case CHDERR_INVALID_STATE: return "invalid state";
1695 case CHDERR_OPERATION_PENDING: return "operation pending";
1696 case CHDERR_NO_ASYNC_OPERATION: return "no async operation in progress";
1697 case CHDERR_UNSUPPORTED_FORMAT: return "unsupported format";
1698 default: return "undocumented error";
1702 /***************************************************************************
1703 CHD HEADER MANAGEMENT
1704 ***************************************************************************/
1706 /*-------------------------------------------------
1707 chd_get_header - return a pointer to the
1708 extracted header data
1709 -------------------------------------------------*/
1711 const chd_header *chd_get_header(chd_file *chd)
1713 /* punt if NULL or invalid */
1714 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1717 return &chd->header;
1720 /***************************************************************************
1721 CORE DATA READ/WRITE
1722 ***************************************************************************/
1724 /*-------------------------------------------------
1725 chd_read - read a single hunk from the CHD
1727 -------------------------------------------------*/
1729 chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1731 /* punt if NULL or invalid */
1732 if (chd == NULL || chd->cookie != COOKIE_VALUE)
1733 return CHDERR_INVALID_PARAMETER;
1735 /* if we're past the end, fail */
1736 if (hunknum >= chd->header.totalhunks)
1737 return CHDERR_HUNK_OUT_OF_RANGE;
1739 /* perform the read */
1740 return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1743 /***************************************************************************
1745 ***************************************************************************/
1747 /*-------------------------------------------------
1748 chd_get_metadata - get the indexed metadata
1750 -------------------------------------------------*/
1752 chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1754 metadata_entry metaentry;
1758 /* if we didn't find it, just return */
1759 err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1760 if (err != CHDERR_NONE)
1762 /* unless we're an old version and they are requesting hard disk metadata */
1763 if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1765 char faux_metadata[256];
1768 /* fill in the faux metadata */
1769 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);
1770 faux_length = (UINT32)strlen(faux_metadata) + 1;
1772 /* copy the metadata itself */
1773 memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1775 /* return the length of the data and the tag */
1776 if (resultlen != NULL)
1777 *resultlen = faux_length;
1778 if (resulttag != NULL)
1779 *resulttag = HARD_DISK_METADATA_TAG;
1785 /* read the metadata */
1786 outputlen = MIN(outputlen, metaentry.length);
1787 core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1788 count = core_fread(chd->file, output, outputlen);
1789 if (count != outputlen)
1790 return CHDERR_READ_ERROR;
1792 /* return the length of the data and the tag */
1793 if (resultlen != NULL)
1794 *resultlen = metaentry.length;
1795 if (resulttag != NULL)
1796 *resulttag = metaentry.metatag;
1797 if (resultflags != NULL)
1798 *resultflags = metaentry.flags;
1802 /***************************************************************************
1804 ***************************************************************************/
1806 /*-------------------------------------------------
1807 chd_codec_config - set internal codec
1809 -------------------------------------------------*/
1811 chd_error chd_codec_config(chd_file *chd, int param, void *config)
1813 return CHDERR_INVALID_PARAMETER;
1816 /*-------------------------------------------------
1817 chd_get_codec_name - get the name of a
1819 -------------------------------------------------*/
1821 const char *chd_get_codec_name(UINT32 codec)
1826 /***************************************************************************
1827 INTERNAL HEADER OPERATIONS
1828 ***************************************************************************/
1830 /*-------------------------------------------------
1831 header_validate - check the validity of a
1833 -------------------------------------------------*/
1835 static chd_error header_validate(const chd_header *header)
1839 /* require a valid version */
1840 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1841 return CHDERR_UNSUPPORTED_VERSION;
1843 /* require a valid length */
1844 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1845 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1846 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1847 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1848 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1849 return CHDERR_INVALID_PARAMETER;
1851 /* Do not validate v5 header */
1852 if (header->version <= 4)
1854 /* require valid flags */
1855 if (header->flags & CHDFLAGS_UNDEFINED)
1856 return CHDERR_INVALID_PARAMETER;
1858 /* require a supported compression mechanism */
1859 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1860 if (codec_interfaces[intfnum].compression == header->compression[0])
1863 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1864 return CHDERR_INVALID_PARAMETER;
1866 /* require a valid hunksize */
1867 if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1868 return CHDERR_INVALID_PARAMETER;
1870 /* require a valid hunk count */
1871 if (header->totalhunks == 0)
1872 return CHDERR_INVALID_PARAMETER;
1874 /* require a valid MD5 and/or SHA1 if we're using a parent */
1875 if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1876 return CHDERR_INVALID_PARAMETER;
1878 /* if we're V3 or later, the obsolete fields must be 0 */
1879 if (header->version >= 3 &&
1880 (header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1881 header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1882 return CHDERR_INVALID_PARAMETER;
1884 /* if we're pre-V3, the obsolete fields must NOT be 0 */
1885 if (header->version < 3 &&
1886 (header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1887 header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1888 return CHDERR_INVALID_PARAMETER;
1894 /*-------------------------------------------------
1895 header_guess_unitbytes - for older CHD formats,
1896 guess at the bytes/unit based on metadata
1897 -------------------------------------------------*/
1899 static UINT32 header_guess_unitbytes(chd_file *chd)
1901 /* look for hard disk metadata; if found, then the unit size == sector size */
1904 if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
1905 sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
1908 /* look for CD-ROM metadata; if found, then the unit size == CD frame size */
1909 if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1910 chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1911 chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1912 chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1913 chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
1914 return CD_FRAME_SIZE;
1916 /* otherwise, just map 1:1 with the hunk size */
1917 return chd->header.hunkbytes;
1920 /*-------------------------------------------------
1921 header_read - read a CHD header into the
1922 internal data structure
1923 -------------------------------------------------*/
1925 static chd_error header_read(chd_file *chd, chd_header *header)
1927 UINT8 rawheader[CHD_MAX_HEADER_SIZE];
1932 return CHDERR_INVALID_PARAMETER;
1934 /* punt if invalid file */
1935 if (chd->file == NULL)
1936 return CHDERR_INVALID_FILE;
1939 core_fseek(chd->file, 0, SEEK_SET);
1940 count = core_fread(chd->file, rawheader, sizeof(rawheader));
1941 if (count != sizeof(rawheader))
1942 return CHDERR_READ_ERROR;
1944 /* verify the tag */
1945 if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
1946 return CHDERR_INVALID_DATA;
1948 /* extract the direct data */
1949 memset(header, 0, sizeof(*header));
1950 header->length = get_bigendian_uint32(&rawheader[8]);
1951 header->version = get_bigendian_uint32(&rawheader[12]);
1953 /* make sure it's a version we understand */
1954 if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1955 return CHDERR_UNSUPPORTED_VERSION;
1957 /* make sure the length is expected */
1958 if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1959 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1960 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1961 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1962 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1964 return CHDERR_INVALID_DATA;
1966 /* extract the common data */
1967 header->flags = get_bigendian_uint32(&rawheader[16]);
1968 header->compression[0] = get_bigendian_uint32(&rawheader[20]);
1969 header->compression[1] = CHD_CODEC_NONE;
1970 header->compression[2] = CHD_CODEC_NONE;
1971 header->compression[3] = CHD_CODEC_NONE;
1973 /* extract the V1/V2-specific data */
1974 if (header->version < 3)
1976 int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
1977 header->obsolete_hunksize = get_bigendian_uint32(&rawheader[24]);
1978 header->totalhunks = get_bigendian_uint32(&rawheader[28]);
1979 header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
1980 header->obsolete_heads = get_bigendian_uint32(&rawheader[36]);
1981 header->obsolete_sectors = get_bigendian_uint32(&rawheader[40]);
1982 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
1983 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
1984 header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
1985 header->hunkbytes = seclen * header->obsolete_hunksize;
1986 header->unitbytes = header_guess_unitbytes(chd);
1987 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
1988 header->metaoffset = 0;
1991 /* extract the V3-specific data */
1992 else if (header->version == 3)
1994 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
1995 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
1996 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
1997 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
1998 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
1999 header->hunkbytes = get_bigendian_uint32(&rawheader[76]);
2000 header->unitbytes = header_guess_unitbytes(chd);
2001 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2002 memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
2003 memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
2006 /* extract the V4-specific data */
2007 else if (header->version == 4)
2009 header->totalhunks = get_bigendian_uint32(&rawheader[24]);
2010 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2011 header->metaoffset = get_bigendian_uint64(&rawheader[36]);
2012 header->hunkbytes = get_bigendian_uint32(&rawheader[44]);
2013 header->unitbytes = header_guess_unitbytes(chd);
2014 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2015 memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
2016 memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
2017 memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
2020 /* extract the V5-specific data */
2021 else if (header->version == 5)
2024 header->compression[0] = get_bigendian_uint32(&rawheader[16]);
2025 header->compression[1] = get_bigendian_uint32(&rawheader[20]);
2026 header->compression[2] = get_bigendian_uint32(&rawheader[24]);
2027 header->compression[3] = get_bigendian_uint32(&rawheader[28]);
2028 header->logicalbytes = get_bigendian_uint64(&rawheader[32]);
2029 header->mapoffset = get_bigendian_uint64(&rawheader[40]);
2030 header->metaoffset = get_bigendian_uint64(&rawheader[48]);
2031 header->hunkbytes = get_bigendian_uint32(&rawheader[56]);
2032 header->hunkcount = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
2033 header->unitbytes = get_bigendian_uint32(&rawheader[60]);
2034 header->unitcount = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2035 memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
2036 memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
2037 memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
2039 /* determine properties of map entries */
2040 header->mapentrybytes = chd_compressed(header) ? 12 : 4;
2043 header->totalhunks = header->hunkcount;
2046 /* Unknown version */
2052 /* guess it worked */
2056 /***************************************************************************
2057 INTERNAL HUNK READ/WRITE
2058 ***************************************************************************/
2060 /*-------------------------------------------------
2061 hunk_read_compressed - read a compressed
2063 -------------------------------------------------*/
2065 static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
2068 if (chd->file_cache != NULL)
2070 return chd->file_cache + offset;
2074 core_fseek(chd->file, offset, SEEK_SET);
2075 bytes = core_fread(chd->file, chd->compressed, size);
2078 return chd->compressed;
2082 /*-------------------------------------------------
2083 hunk_read_uncompressed - read an uncompressed
2085 -------------------------------------------------*/
2087 static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2090 if (chd->file_cache != NULL)
2092 memcpy(dest, chd->file_cache + offset, size);
2096 core_fseek(chd->file, offset, SEEK_SET);
2097 bytes = core_fread(chd->file, dest, size);
2099 return CHDERR_READ_ERROR;
2104 /*-------------------------------------------------
2105 hunk_read_into_cache - read a hunk into
2106 the CHD's hunk cache
2107 -------------------------------------------------*/
2109 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2114 if (hunknum > chd->maxhunk)
2115 chd->maxhunk = hunknum;
2117 /* if we're already in the cache, we're done */
2118 if (chd->cachehunk == hunknum)
2120 chd->cachehunk = ~0;
2122 /* otherwise, read the data */
2123 err = hunk_read_into_memory(chd, hunknum, chd->cache);
2124 if (err != CHDERR_NONE)
2127 /* mark the hunk successfully cached in */
2128 chd->cachehunk = hunknum;
2132 /*-------------------------------------------------
2133 hunk_read_into_memory - read a hunk into
2134 memory at the given location
2135 -------------------------------------------------*/
2137 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2141 /* punt if no file */
2142 if (chd->file == NULL)
2143 return CHDERR_INVALID_FILE;
2145 /* return an error if out of range */
2146 if (hunknum >= chd->header.totalhunks)
2147 return CHDERR_HUNK_OUT_OF_RANGE;
2149 if (chd->header.version < 5)
2151 map_entry *entry = &chd->map[hunknum];
2153 UINT8* compressed_bytes;
2155 /* switch off the entry type */
2156 switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2158 /* compressed data */
2159 case V34_MAP_ENTRY_TYPE_COMPRESSED:
2163 /* read it into the decompression buffer */
2164 compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
2165 if (compressed_bytes == NULL)
2166 return CHDERR_READ_ERROR;
2168 /* now decompress using the codec */
2170 codec = &chd->zlib_codec_data;
2171 if (chd->codecintf[0]->decompress != NULL)
2172 err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
2173 if (err != CHDERR_NONE)
2178 /* uncompressed data */
2179 case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2180 err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2181 if (err != CHDERR_NONE)
2185 /* mini-compressed data */
2186 case V34_MAP_ENTRY_TYPE_MINI:
2187 put_bigendian_uint64(&dest[0], entry->offset);
2188 for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2189 dest[bytes] = dest[bytes - 8];
2192 /* self-referenced data */
2193 case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2194 if (chd->cachehunk == entry->offset && dest == chd->cache)
2196 return hunk_read_into_memory(chd, entry->offset, dest);
2198 /* parent-referenced data */
2199 case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2200 err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2201 if (err != CHDERR_NONE)
2209 /* get a pointer to the map entry */
2214 uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2215 UINT8* compressed_bytes;
2217 /* uncompressed case */
2218 if (!chd_compressed(&chd->header))
2220 blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
2221 if (blockoffs != 0) {
2223 core_fseek(chd->file, blockoffs, SEEK_SET);
2224 result = core_fread(chd->file, dest, chd->header.hunkbytes);
2226 else if (m_parent_missing)
2227 throw CHDERR_REQUIRES_PARENT; */
2228 } else if (chd->parent) {
2229 err = hunk_read_into_memory(chd->parent, hunknum, dest);
2230 if (err != CHDERR_NONE)
2233 memset(dest, 0, chd->header.hunkbytes);
2238 /* compressed case */
2239 blocklen = get_bigendian_uint24(&rawmap[1]);
2240 blockoffs = get_bigendian_uint48(&rawmap[4]);
2241 blockcrc = get_bigendian_uint16(&rawmap[10]);
2245 case COMPRESSION_TYPE_0:
2246 case COMPRESSION_TYPE_1:
2247 case COMPRESSION_TYPE_2:
2248 case COMPRESSION_TYPE_3:
2249 compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
2250 if (compressed_bytes == NULL)
2251 return CHDERR_READ_ERROR;
2252 switch (chd->codecintf[rawmap[0]]->compression)
2254 case CHD_CODEC_CD_LZMA:
2255 codec = &chd->cdlz_codec_data;
2258 case CHD_CODEC_ZLIB:
2259 codec = &chd->zlib_codec_data;
2262 case CHD_CODEC_CD_ZLIB:
2263 codec = &chd->cdzl_codec_data;
2266 case CHD_CODEC_CD_FLAC:
2267 codec = &chd->cdfl_codec_data;
2271 return CHDERR_DECOMPRESSION_ERROR;
2272 chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
2273 if (dest != NULL && crc16(dest, chd->header.hunkbytes) != blockcrc)
2274 return CHDERR_DECOMPRESSION_ERROR;
2277 case COMPRESSION_NONE:
2278 err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest);
2279 if (err != CHDERR_NONE)
2281 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2282 return CHDERR_DECOMPRESSION_ERROR;
2285 case COMPRESSION_SELF:
2286 return hunk_read_into_memory(chd, blockoffs, dest);
2288 case COMPRESSION_PARENT:
2291 if (m_parent_missing)
2292 return CHDERR_REQUIRES_PARENT;
2293 return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
2295 return CHDERR_DECOMPRESSION_ERROR;
2300 /* We should not reach this code */
2301 return CHDERR_DECOMPRESSION_ERROR;
2304 /***************************************************************************
2306 ***************************************************************************/
2308 /*-------------------------------------------------
2309 map_read - read the initial sector map
2310 -------------------------------------------------*/
2312 static chd_error map_read(chd_file *chd)
2314 UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2315 UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2316 UINT64 fileoffset, maxoffset = 0;
2317 UINT8 cookie[MAP_ENTRY_SIZE];
2322 /* first allocate memory */
2323 chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2325 return CHDERR_OUT_OF_MEMORY;
2327 /* read the map entries in in chunks and extract to the map list */
2328 fileoffset = chd->header.length;
2329 for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2331 /* compute how many entries this time */
2332 int entries = chd->header.totalhunks - i, j;
2333 if (entries > MAP_STACK_ENTRIES)
2334 entries = MAP_STACK_ENTRIES;
2336 /* read that many */
2337 core_fseek(chd->file, fileoffset, SEEK_SET);
2338 count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2339 if (count != entries * entrysize)
2341 err = CHDERR_READ_ERROR;
2344 fileoffset += entries * entrysize;
2346 /* process that many */
2347 if (entrysize == MAP_ENTRY_SIZE)
2349 for (j = 0; j < entries; j++)
2350 map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2354 for (j = 0; j < entries; j++)
2355 map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2358 /* track the maximum offset */
2359 for (j = 0; j < entries; j++)
2360 if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2361 (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2362 maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2365 /* verify the cookie */
2366 core_fseek(chd->file, fileoffset, SEEK_SET);
2367 count = core_fread(chd->file, &cookie, entrysize);
2368 if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2370 err = CHDERR_INVALID_FILE;
2374 /* verify the length */
2375 if (maxoffset > core_fsize(chd->file))
2377 err = CHDERR_INVALID_FILE;
2389 /***************************************************************************
2390 INTERNAL METADATA ACCESS
2391 ***************************************************************************/
2393 /*-------------------------------------------------
2394 metadata_find_entry - find a metadata entry
2395 -------------------------------------------------*/
2397 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2399 /* start at the beginning */
2400 metaentry->offset = chd->header.metaoffset;
2401 metaentry->prev = 0;
2403 /* loop until we run out of options */
2404 while (metaentry->offset != 0)
2406 UINT8 raw_meta_header[METADATA_HEADER_SIZE];
2409 /* read the raw header */
2410 core_fseek(chd->file, metaentry->offset, SEEK_SET);
2411 count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2412 if (count != sizeof(raw_meta_header))
2415 /* extract the data */
2416 metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2417 metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2418 metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2420 /* flags are encoded in the high byte of length */
2421 metaentry->flags = metaentry->length >> 24;
2422 metaentry->length &= 0x00ffffff;
2424 /* if we got a match, proceed */
2425 if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2426 if (metaindex-- == 0)
2429 /* no match, fetch the next link */
2430 metaentry->prev = metaentry->offset;
2431 metaentry->offset = metaentry->next;
2434 /* if we get here, we didn't find it */
2435 return CHDERR_METADATA_NOT_FOUND;
2438 /***************************************************************************
2439 ZLIB COMPRESSION CODEC
2440 ***************************************************************************/
2442 /*-------------------------------------------------
2443 zlib_codec_init - initialize the ZLIB codec
2444 -------------------------------------------------*/
2446 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2448 zlib_codec_data *data = (zlib_codec_data*)codec;
2452 /* clear the buffers */
2453 memset(data, 0, sizeof(zlib_codec_data));
2455 /* init the inflater first */
2456 data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */
2457 data->inflater.avail_in = 0;
2458 data->inflater.zalloc = zlib_fast_alloc;
2459 data->inflater.zfree = zlib_fast_free;
2460 data->inflater.opaque = &data->allocator;
2461 zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2463 /* convert errors */
2464 if (zerr == Z_MEM_ERROR)
2465 err = CHDERR_OUT_OF_MEMORY;
2466 else if (zerr != Z_OK)
2467 err = CHDERR_CODEC_ERROR;
2471 /* handle an error */
2472 if (err != CHDERR_NONE)
2478 /*-------------------------------------------------
2479 zlib_codec_free - free data for the ZLIB
2481 -------------------------------------------------*/
2483 static void zlib_codec_free(void *codec)
2485 zlib_codec_data *data = (zlib_codec_data *)codec;
2487 /* deinit the streams */
2492 inflateEnd(&data->inflater);
2494 /* free our fast memory */
2495 zlib_allocator_free(&data->allocator);
2499 /*-------------------------------------------------
2500 zlib_codec_decompress - decompress data using
2502 -------------------------------------------------*/
2504 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2506 zlib_codec_data *data = (zlib_codec_data *)codec;
2509 /* reset the decompressor */
2510 data->inflater.next_in = (Bytef *)src;
2511 data->inflater.avail_in = complen;
2512 data->inflater.total_in = 0;
2513 data->inflater.next_out = (Bytef *)dest;
2514 data->inflater.avail_out = destlen;
2515 data->inflater.total_out = 0;
2516 zerr = inflateReset(&data->inflater);
2518 return CHDERR_DECOMPRESSION_ERROR;
2521 zerr = inflate(&data->inflater, Z_FINISH);
2522 if (data->inflater.total_out != destlen)
2523 return CHDERR_DECOMPRESSION_ERROR;
2528 /*-------------------------------------------------
2529 zlib_fast_alloc - fast malloc for ZLIB, which
2530 allocates and frees memory frequently
2531 -------------------------------------------------*/
2532 #define ZLIB_MIN_ALIGNMENT_BITS 512
2533 #define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
2535 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2537 zlib_allocator *alloc = (zlib_allocator *)opaque;
2538 uintptr_t paddr = 0;
2542 /* compute the size, rounding to the nearest 1k */
2543 size = (size * items + 0x3ff) & ~0x3ff;
2545 /* reuse a hunk if we can */
2546 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2548 ptr = alloc->allocptr[i];
2549 if (ptr && size == *ptr)
2551 /* set the low bit of the size so we don't match next time */
2553 return (voidpf)(alloc->allocptr2[i]);
2557 /* alloc a new one */
2558 ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
2562 /* put it into the list */
2563 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2564 if (!alloc->allocptr[i])
2566 alloc->allocptr[i] = ptr;
2567 paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
2568 alloc->allocptr2[i] = (uint32_t*)paddr;
2572 /* set the low bit of the size so we don't match next time */
2574 return (voidpf)paddr;
2577 /*-------------------------------------------------
2578 zlib_fast_free - fast free for ZLIB, which
2579 allocates and frees memory frequently
2580 -------------------------------------------------*/
2582 static void zlib_fast_free(voidpf opaque, voidpf address)
2584 zlib_allocator *alloc = (zlib_allocator *)opaque;
2585 UINT32 *ptr = (UINT32 *)address;
2589 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2590 if (ptr == alloc->allocptr2[i])
2592 /* clear the low bit of the size to allow matches */
2593 *(alloc->allocptr[i]) &= ~1;
2598 /*-------------------------------------------------
2600 -------------------------------------------------*/
2601 static void zlib_allocator_free(voidpf opaque)
2603 zlib_allocator *alloc = (zlib_allocator *)opaque;
2606 for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2607 if (alloc->allocptr[i])
2608 free(alloc->allocptr[i]);