1 /***************************************************************************
2 
3     chd.c
4 
5     MAME Compressed Hunks of Data file format
6 
7 ****************************************************************************
8 
9     Copyright Aaron Giles
10     All rights reserved.
11 
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions are
14     met:
15 
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
21           distribution.
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.
25 
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.
37 
38 ***************************************************************************/
39 
40 #include <stddef.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <time.h>
45 
46 #include <libchdr/chd.h>
47 #include <libchdr/cdrom.h>
48 #include <libchdr/flac.h>
49 #include <libchdr/huffman.h>
50 
51 #include "LzmaEnc.h"
52 #include "LzmaDec.h"
53 #include "zlib.h"
54 
55 #undef TRUE
56 #undef FALSE
57 #define TRUE 1
58 #define FALSE 0
59 
60 #undef MAX
61 #undef MIN
62 #define MAX(x, y) (((x) > (y)) ? (x) : (y))
63 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
64 
65 #define SHA1_DIGEST_SIZE 20
66 
67 /***************************************************************************
68     DEBUGGING
69 ***************************************************************************/
70 
71 #define PRINTF_MAX_HUNK				(0)
72 
73 /***************************************************************************
74     CONSTANTS
75 ***************************************************************************/
76 
77 #define MAP_STACK_ENTRIES			512			/* max number of entries to use on the stack */
78 #define MAP_ENTRY_SIZE				16			/* V3 and later */
79 #define OLD_MAP_ENTRY_SIZE			8			/* V1-V2 */
80 #define METADATA_HEADER_SIZE		16			/* metadata header size */
81 
82 #define MAP_ENTRY_FLAG_TYPE_MASK	0x0f		/* what type of hunk */
83 #define MAP_ENTRY_FLAG_NO_CRC		0x10		/* no CRC is present */
84 
85 #define CHD_V1_SECTOR_SIZE			512			/* size of a "sector" in the V1 header */
86 
87 #define COOKIE_VALUE				0xbaadf00d
88 #define MAX_ZLIB_ALLOCS				64
89 
90 #define END_OF_LIST_COOKIE			"EndOfListCookie"
91 
92 #define NO_MATCH					(~0)
93 
94 #ifdef WANT_RAW_DATA_SECTOR
95 static const uint8_t s_cd_sync_header[12] = { 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 };
96 #endif
97 
98 /* V3-V4 entry types */
99 enum
100 {
101 	V34_MAP_ENTRY_TYPE_INVALID = 0,             /* invalid type */
102 	V34_MAP_ENTRY_TYPE_COMPRESSED = 1,          /* standard compression */
103 	V34_MAP_ENTRY_TYPE_UNCOMPRESSED = 2,        /* uncompressed data */
104 	V34_MAP_ENTRY_TYPE_MINI = 3,                /* mini: use offset as raw data */
105 	V34_MAP_ENTRY_TYPE_SELF_HUNK = 4,           /* same as another hunk in this file */
106 	V34_MAP_ENTRY_TYPE_PARENT_HUNK = 5,         /* same as a hunk in the parent file */
107 	V34_MAP_ENTRY_TYPE_2ND_COMPRESSED = 6       /* compressed with secondary algorithm (usually FLAC CDDA) */
108 };
109 
110 /* V5 compression types */
111 enum
112 {
113 	/* codec #0
114 	 * these types are live when running */
115 	COMPRESSION_TYPE_0 = 0,
116 	/* codec #1 */
117 	COMPRESSION_TYPE_1 = 1,
118 	/* codec #2 */
119 	COMPRESSION_TYPE_2 = 2,
120 	/* codec #3 */
121 	COMPRESSION_TYPE_3 = 3,
122 	/* no compression; implicit length = hunkbytes */
123 	COMPRESSION_NONE = 4,
124 	/* same as another block in this chd */
125 	COMPRESSION_SELF = 5,
126 	/* same as a hunk's worth of units in the parent chd */
127 	COMPRESSION_PARENT = 6,
128 
129 	/* start of small RLE run (4-bit length)
130 	 * these additional pseudo-types are used for compressed encodings: */
131 	COMPRESSION_RLE_SMALL,
132 	/* start of large RLE run (8-bit length) */
133 	COMPRESSION_RLE_LARGE,
134 	/* same as the last COMPRESSION_SELF block */
135 	COMPRESSION_SELF_0,
136 	/* same as the last COMPRESSION_SELF block + 1 */
137 	COMPRESSION_SELF_1,
138 	/* same block in the parent */
139 	COMPRESSION_PARENT_SELF,
140 	/* same as the last COMPRESSION_PARENT block */
141 	COMPRESSION_PARENT_0,
142 	/* same as the last COMPRESSION_PARENT block + 1 */
143 	COMPRESSION_PARENT_1
144 };
145 
146 /***************************************************************************
147     MACROS
148 ***************************************************************************/
149 
150 #define EARLY_EXIT(x)				do { (void)(x); goto cleanup; } while (0)
151 
152 /***************************************************************************
153     TYPE DEFINITIONS
154 ***************************************************************************/
155 
156 /* interface to a codec */
157 typedef struct _codec_interface codec_interface;
158 struct _codec_interface
159 {
160 	UINT32		compression;								/* type of compression */
161 	const char *compname;									/* name of the algorithm */
162 	UINT8		lossy;										/* is this a lossy algorithm? */
163 	chd_error	(*init)(void *codec, UINT32 hunkbytes);		/* codec initialize */
164 	void		(*free)(void *codec);						/* codec free */
165 	chd_error	(*decompress)(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen); /* decompress data */
166 	chd_error	(*config)(void *codec, int param, void *config); /* configure */
167 };
168 
169 /* a single map entry */
170 typedef struct _map_entry map_entry;
171 struct _map_entry
172 {
173 	UINT64					offset;			/* offset within the file of the data */
174 	UINT32					crc;			/* 32-bit CRC of the data */
175 	UINT32					length;			/* length of the data */
176 	UINT8					flags;			/* misc flags */
177 };
178 
179 /* a single metadata entry */
180 typedef struct _metadata_entry metadata_entry;
181 struct _metadata_entry
182 {
183 	UINT64					offset;			/* offset within the file of the header */
184 	UINT64					next;			/* offset within the file of the next header */
185 	UINT64					prev;			/* offset within the file of the previous header */
186 	UINT32					length;			/* length of the metadata */
187 	UINT32					metatag;		/* metadata tag */
188 	UINT8					flags;			/* flag bits */
189 };
190 
191 /* codec-private data for the ZLIB codec */
192 
193 typedef struct _zlib_allocator zlib_allocator;
194 struct _zlib_allocator
195 {
196 	UINT32 *				allocptr[MAX_ZLIB_ALLOCS];
197 	UINT32 *				allocptr2[MAX_ZLIB_ALLOCS];
198 };
199 
200 typedef struct _zlib_codec_data zlib_codec_data;
201 struct _zlib_codec_data
202 {
203 	z_stream				inflater;
204 	zlib_allocator			allocator;
205 };
206 
207 /* codec-private data for the LZMA codec */
208 #define MAX_LZMA_ALLOCS 64
209 
210 typedef struct _lzma_allocator lzma_allocator;
211 struct _lzma_allocator
212 {
213 	void *(*Alloc)(void *p, size_t size);
214  	void (*Free)(void *p, void *address); /* address can be 0 */
215 	void (*FreeSz)(void *p, void *address, size_t size); /* address can be 0 */
216 	uint32_t*	allocptr[MAX_LZMA_ALLOCS];
217 	uint32_t*	allocptr2[MAX_LZMA_ALLOCS];
218 };
219 
220 typedef struct _lzma_codec_data lzma_codec_data;
221 struct _lzma_codec_data
222 {
223 	CLzmaDec		decoder;
224 	lzma_allocator	allocator;
225 };
226 
227 /* codec-private data for the CDZL codec */
228 typedef struct _cdzl_codec_data cdzl_codec_data;
229 struct _cdzl_codec_data {
230 	/* internal state */
231 	zlib_codec_data		base_decompressor;
232 #ifdef WANT_SUBCODE
233 	zlib_codec_data		subcode_decompressor;
234 #endif
235 	uint8_t*			buffer;
236 };
237 
238 /* codec-private data for the CDLZ codec */
239 typedef struct _cdlz_codec_data cdlz_codec_data;
240 struct _cdlz_codec_data {
241 	/* internal state */
242 	lzma_codec_data		base_decompressor;
243 #ifdef WANT_SUBCODE
244 	zlib_codec_data		subcode_decompressor;
245 #endif
246 	uint8_t*			buffer;
247 };
248 
249 /* codec-private data for the CDFL codec */
250 typedef struct _cdfl_codec_data cdfl_codec_data;
251 struct _cdfl_codec_data {
252 	/* internal state */
253 	int		swap_endian;
254 	flac_decoder	decoder;
255 #ifdef WANT_SUBCODE
256 	zlib_codec_data		subcode_decompressor;
257 #endif
258 	uint8_t*	buffer;
259 };
260 
261 /* internal representation of an open CHD file */
262 struct _chd_file
263 {
264 	UINT32					cookie;			/* cookie, should equal COOKIE_VALUE */
265 
266 	core_file *				file;			/* handle to the open core file */
267 	UINT8					owns_file;		/* flag indicating if this file should be closed on chd_close() */
268 	chd_header				header;			/* header, extracted from file */
269 
270 	chd_file *				parent;			/* pointer to parent file, or NULL */
271 
272 	map_entry *				map;			/* array of map entries */
273 
274 #ifdef NEED_CACHE_HUNK
275 	UINT8 *					cache;			/* hunk cache pointer */
276 	UINT32					cachehunk;		/* index of currently cached hunk */
277 
278 	UINT8 *					compare;		/* hunk compare pointer */
279 	UINT32					comparehunk;	/* index of current compare data */
280 #endif
281 
282 	UINT8 *					compressed;		/* pointer to buffer for compressed data */
283 	const codec_interface *	codecintf[4];	/* interface to the codec */
284 
285 	zlib_codec_data			zlib_codec_data;		/* zlib codec data */
286 	cdzl_codec_data			cdzl_codec_data;		/* cdzl codec data */
287 	cdlz_codec_data			cdlz_codec_data;		/* cdlz codec data */
288 	cdfl_codec_data			cdfl_codec_data;		/* cdfl codec data */
289 
290 #ifdef NEED_CACHE_HUNK
291 	UINT32					maxhunk;		/* maximum hunk accessed */
292 #endif
293 
294 	UINT8 *					file_cache;		/* cache of underlying file */
295 };
296 
297 
298 /***************************************************************************
299     GLOBAL VARIABLES
300 ***************************************************************************/
301 
302 static const UINT8 nullmd5[CHD_MD5_BYTES] = { 0 };
303 static const UINT8 nullsha1[CHD_SHA1_BYTES] = { 0 };
304 
305 /***************************************************************************
306     PROTOTYPES
307 ***************************************************************************/
308 
309 /* internal header operations */
310 static chd_error header_validate(const chd_header *header);
311 static chd_error header_read(chd_file *chd, chd_header *header);
312 
313 /* internal hunk read/write */
314 #ifdef NEED_CACHE_HUNK
315 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum);
316 #endif
317 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest);
318 
319 /* internal map access */
320 static chd_error map_read(chd_file *chd);
321 
322 /* metadata management */
323 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry);
324 
325 /* zlib compression codec */
326 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes);
327 static void zlib_codec_free(void *codec);
328 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
329 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size);
330 static void zlib_fast_free(voidpf opaque, voidpf address);
331 static void zlib_allocator_free(voidpf opaque);
332 
333 /* lzma compression codec */
334 static chd_error lzma_codec_init(void *codec, uint32_t hunkbytes);
335 static void lzma_codec_free(void *codec);
336 static chd_error lzma_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
337 
338 /* cdzl compression codec */
339 static chd_error cdzl_codec_init(void* codec, uint32_t hunkbytes);
340 static void cdzl_codec_free(void* codec);
341 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
342 
343 /* cdlz compression codec */
344 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes);
345 static void cdlz_codec_free(void* codec);
346 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
347 
348 /* cdfl compression codec */
349 static chd_error cdfl_codec_init(void* codec, uint32_t hunkbytes);
350 static void cdfl_codec_free(void* codec);
351 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen);
352 
353 /***************************************************************************
354  *  LZMA ALLOCATOR HELPER
355  ***************************************************************************
356  */
357 
358 static void *lzma_fast_alloc(void *p, size_t size);
359 static void lzma_fast_free(void *p, void *address);
360 
361 /*-------------------------------------------------
362  *  lzma_allocator_init
363  *-------------------------------------------------
364  */
365 
lzma_allocator_init(void * p)366 static void lzma_allocator_init(void* p)
367 {
368 	lzma_allocator *codec = (lzma_allocator *)(p);
369 
370 	/* reset pointer list */
371 	memset(codec->allocptr, 0, sizeof(codec->allocptr));
372 	memset(codec->allocptr2, 0, sizeof(codec->allocptr2));
373 	codec->Alloc = lzma_fast_alloc;
374 	codec->Free = lzma_fast_free;
375 }
376 
377 /*-------------------------------------------------
378  *  lzma_allocator_free
379  *-------------------------------------------------
380  */
381 
lzma_allocator_free(void * p)382 static void lzma_allocator_free(void* p )
383 {
384 	int i;
385 	lzma_allocator *codec = (lzma_allocator *)(p);
386 
387 	/* free our memory */
388 	for (i = 0 ; i < MAX_LZMA_ALLOCS ; i++)
389 	{
390 		if (codec->allocptr[i] != NULL)
391 			free(codec->allocptr[i]);
392 	}
393 }
394 
395 /*-------------------------------------------------
396  *  lzma_fast_alloc - fast malloc for lzma, which
397  *  allocates and frees memory frequently
398  *-------------------------------------------------
399  */
400 
401 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
402 #define LZMA_MIN_ALIGNMENT_BITS 512
403 #define LZMA_MIN_ALIGNMENT_BYTES (LZMA_MIN_ALIGNMENT_BITS / 8)
404 
lzma_fast_alloc(void * p,size_t size)405 static void *lzma_fast_alloc(void *p, size_t size)
406 {
407 	int scan;
408 	uint32_t *addr        = NULL;
409 	lzma_allocator *codec = (lzma_allocator *)(p);
410 	uintptr_t vaddr = 0;
411 
412 	/* compute the size, rounding to the nearest 1k */
413 	size = (size + 0x3ff) & ~0x3ff;
414 
415 	/* reuse a hunk if we can */
416 	for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
417 	{
418 		uint32_t *ptr = codec->allocptr[scan];
419 		if (ptr != NULL && size == *ptr)
420 		{
421 			/* set the low bit of the size so we don't match next time */
422 			*ptr |= 1;
423 
424 			/* return aligned address of the block */
425 			return codec->allocptr2[scan];
426 		}
427 	}
428 
429 	/* alloc a new one and put it into the list */
430 	addr = (uint32_t *)malloc(size + sizeof(uint32_t) + LZMA_MIN_ALIGNMENT_BYTES);
431 	if (addr==NULL)
432 		return NULL;
433 	for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
434 	{
435 		if (codec->allocptr[scan] == NULL)
436 		{
437 			/* store block address */
438 			codec->allocptr[scan] = addr;
439 
440 			/* compute aligned address, store it */
441 			vaddr = (uintptr_t)addr;
442 			vaddr = (vaddr + sizeof(uint32_t) + (LZMA_MIN_ALIGNMENT_BYTES-1)) & (~(LZMA_MIN_ALIGNMENT_BYTES-1));
443 			codec->allocptr2[scan] = (uint32_t*)vaddr;
444 			break;
445 		}
446 	}
447 
448 	/* set the low bit of the size so we don't match next time */
449 	*addr = size | 1;
450 
451 	/* return aligned address */
452 	return (void*)vaddr;
453 }
454 
455 /*-------------------------------------------------
456  *  lzma_fast_free - fast free for lzma, which
457  *  allocates and frees memory frequently
458  *-------------------------------------------------
459  */
460 
lzma_fast_free(void * p,void * address)461 static void lzma_fast_free(void *p, void *address)
462 {
463 	int scan;
464 	uint32_t *ptr = NULL;
465 	lzma_allocator *codec = NULL;
466 
467 	if (address == NULL)
468 		return;
469 
470 	codec = (lzma_allocator *)(p);
471 
472 	/* find the hunk */
473 	ptr = (uint32_t *)address;
474 	for (scan = 0; scan < MAX_LZMA_ALLOCS; scan++)
475 	{
476 		if (ptr == codec->allocptr2[scan])
477 		{
478 			/* clear the low bit of the size to allow matches */
479 			*codec->allocptr[scan] &= ~1;
480 			return;
481 		}
482 	}
483 }
484 
485 /***************************************************************************
486  *  LZMA DECOMPRESSOR
487  ***************************************************************************
488  */
489 
490 /*-------------------------------------------------
491  *  lzma_codec_init - constructor
492  *-------------------------------------------------
493  */
494 
lzma_codec_init(void * codec,uint32_t hunkbytes)495 static chd_error lzma_codec_init(void* codec, uint32_t hunkbytes)
496 {
497 	CLzmaEncHandle enc;
498 	CLzmaEncProps encoder_props;
499 	Byte decoder_props[LZMA_PROPS_SIZE];
500 	SizeT props_size;
501 	lzma_allocator* alloc;
502 	lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
503 
504 	/* construct the decoder */
505 	LzmaDec_Construct(&lzma_codec->decoder);
506 
507 	/* FIXME: this code is written in a way that makes it impossible to safely upgrade the LZMA SDK
508 	 * This code assumes that the current version of the encoder imposes the same requirements on the
509 	 * decoder as the encoder used to produce the file.  This is not necessarily true.  The format
510 	 * needs to be changed so the encoder properties are written to the file.
511 
512 	 * configure the properties like the compressor did */
513 	LzmaEncProps_Init(&encoder_props);
514 	encoder_props.level = 9;
515 	encoder_props.reduceSize = hunkbytes;
516 	LzmaEncProps_Normalize(&encoder_props);
517 
518 	/* convert to decoder properties */
519 	alloc = &lzma_codec->allocator;
520 	lzma_allocator_init(alloc);
521 	enc = LzmaEnc_Create((ISzAlloc*)alloc);
522 	if (!enc)
523 		return CHDERR_DECOMPRESSION_ERROR;
524 	if (LzmaEnc_SetProps(enc, &encoder_props) != SZ_OK)
525 	{
526 		LzmaEnc_Destroy(enc, (ISzAlloc*)&alloc, (ISzAlloc*)&alloc);
527 		return CHDERR_DECOMPRESSION_ERROR;
528 	}
529 	props_size = sizeof(decoder_props);
530 	if (LzmaEnc_WriteProperties(enc, decoder_props, &props_size) != SZ_OK)
531 	{
532 		LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
533 		return CHDERR_DECOMPRESSION_ERROR;
534 	}
535 	LzmaEnc_Destroy(enc, (ISzAlloc*)alloc, (ISzAlloc*)alloc);
536 
537 	/* do memory allocations */
538 	if (LzmaDec_Allocate(&lzma_codec->decoder, decoder_props, LZMA_PROPS_SIZE, (ISzAlloc*)alloc) != SZ_OK)
539 		return CHDERR_DECOMPRESSION_ERROR;
540 
541 	/* Okay */
542 	return CHDERR_NONE;
543 }
544 
545 /*-------------------------------------------------
546  *  lzma_codec_free
547  *-------------------------------------------------
548  */
549 
lzma_codec_free(void * codec)550 static void lzma_codec_free(void* codec)
551 {
552 	lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
553 
554 	/* free memory */
555 	LzmaDec_Free(&lzma_codec->decoder, (ISzAlloc*)&lzma_codec->allocator);
556 	lzma_allocator_free(&lzma_codec->allocator);
557 }
558 
559 /*-------------------------------------------------
560  *  decompress - decompress data using the LZMA
561  *  codec
562  *-------------------------------------------------
563  */
564 
lzma_codec_decompress(void * codec,const uint8_t * src,uint32_t complen,uint8_t * dest,uint32_t destlen)565 static chd_error lzma_codec_decompress(void* codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
566 {
567 	ELzmaStatus status;
568 	SRes res;
569 	SizeT consumedlen, decodedlen;
570 	/* initialize */
571 	lzma_codec_data* lzma_codec = (lzma_codec_data*) codec;
572 	LzmaDec_Init(&lzma_codec->decoder);
573 
574 	/* decode */
575 	consumedlen = complen;
576 	decodedlen = destlen;
577 	res = LzmaDec_DecodeToBuf(&lzma_codec->decoder, dest, &decodedlen, src, &consumedlen, LZMA_FINISH_END, &status);
578 	if ((res != SZ_OK && res != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) || consumedlen != complen || decodedlen != destlen)
579 		return CHDERR_DECOMPRESSION_ERROR;
580 	return CHDERR_NONE;
581 }
582 
583 /* cdlz */
cdlz_codec_init(void * codec,uint32_t hunkbytes)584 static chd_error cdlz_codec_init(void* codec, uint32_t hunkbytes)
585 {
586 	chd_error ret;
587 	cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
588 
589 	/* allocate buffer */
590 	cdlz->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
591 	if (cdlz->buffer == NULL)
592 		return CHDERR_OUT_OF_MEMORY;
593 
594 	/* make sure the CHD's hunk size is an even multiple of the frame size */
595 	ret = lzma_codec_init(&cdlz->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
596 	if (ret != CHDERR_NONE)
597 		return ret;
598 
599 #ifdef WANT_SUBCODE
600 	ret = zlib_codec_init(&cdlz->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
601 	if (ret != CHDERR_NONE)
602 		return ret;
603 #endif
604 
605 	if (hunkbytes % CD_FRAME_SIZE != 0)
606 		return CHDERR_CODEC_ERROR;
607 
608 	return CHDERR_NONE;
609 }
610 
cdlz_codec_free(void * codec)611 static void cdlz_codec_free(void* codec)
612 {
613 	cdlz_codec_data* cdlz = (cdlz_codec_data*) codec;
614 	free(cdlz->buffer);
615 	lzma_codec_free(&cdlz->base_decompressor);
616 #ifdef WANT_SUBCODE
617 	zlib_codec_free(&cdlz->subcode_decompressor);
618 #endif
619 }
620 
cdlz_codec_decompress(void * codec,const uint8_t * src,uint32_t complen,uint8_t * dest,uint32_t destlen)621 static chd_error cdlz_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
622 {
623 	uint32_t framenum;
624 	cdlz_codec_data* cdlz = (cdlz_codec_data*)codec;
625 
626 	/* determine header bytes */
627 	uint32_t frames = destlen / CD_FRAME_SIZE;
628 	uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
629 	uint32_t ecc_bytes = (frames + 7) / 8;
630 	uint32_t header_bytes = ecc_bytes + complen_bytes;
631 
632 	/* extract compressed length of base */
633 	uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
634 	if (complen_bytes > 2)
635 		complen_base = (complen_base << 8) | src[ecc_bytes + 2];
636 
637 	/* reset and decode */
638 	lzma_codec_decompress(&cdlz->base_decompressor, &src[header_bytes], complen_base, &cdlz->buffer[0], frames * CD_MAX_SECTOR_DATA);
639 #ifdef WANT_SUBCODE
640 	zlib_codec_decompress(&cdlz->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdlz->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
641 #endif
642 
643 	/* reassemble the data */
644 	for (framenum = 0; framenum < frames; framenum++)
645 	{
646 		uint8_t *sector;
647 
648 		memcpy(&dest[framenum * CD_FRAME_SIZE], &cdlz->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
649 #ifdef WANT_SUBCODE
650 		memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdlz->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
651 #endif
652 
653 #ifdef WANT_RAW_DATA_SECTOR
654 		/* reconstitute the ECC data and sync header */
655 		sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
656 		if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
657 		{
658 			memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
659 			ecc_generate(sector);
660 		}
661 #endif
662 	}
663 	return CHDERR_NONE;
664 }
665 
666 /* cdzl */
667 
cdzl_codec_init(void * codec,uint32_t hunkbytes)668 static chd_error cdzl_codec_init(void *codec, uint32_t hunkbytes)
669 {
670 	chd_error ret;
671 	cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
672 
673 	/* make sure the CHD's hunk size is an even multiple of the frame size */
674 	if (hunkbytes % CD_FRAME_SIZE != 0)
675 		return CHDERR_CODEC_ERROR;
676 
677 	cdzl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
678 	if (cdzl->buffer == NULL)
679 		return CHDERR_OUT_OF_MEMORY;
680 
681 	ret = zlib_codec_init(&cdzl->base_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
682 	if (ret != CHDERR_NONE)
683 		return ret;
684 
685 #ifdef WANT_SUBCODE
686 	ret = zlib_codec_init(&cdzl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SUBCODE_DATA);
687 	if (ret != CHDERR_NONE)
688 		return ret;
689 #endif
690 
691 	return CHDERR_NONE;
692 }
693 
cdzl_codec_free(void * codec)694 static void cdzl_codec_free(void *codec)
695 {
696 	cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
697 	zlib_codec_free(&cdzl->base_decompressor);
698 #ifdef WANT_SUBCODE
699 	zlib_codec_free(&cdzl->subcode_decompressor);
700 #endif
701 	free(cdzl->buffer);
702 }
703 
cdzl_codec_decompress(void * codec,const uint8_t * src,uint32_t complen,uint8_t * dest,uint32_t destlen)704 static chd_error cdzl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
705 {
706 	uint32_t framenum;
707 	cdzl_codec_data* cdzl = (cdzl_codec_data*)codec;
708 
709 	/* determine header bytes */
710 	uint32_t frames = destlen / CD_FRAME_SIZE;
711 	uint32_t complen_bytes = (destlen < 65536) ? 2 : 3;
712 	uint32_t ecc_bytes = (frames + 7) / 8;
713 	uint32_t header_bytes = ecc_bytes + complen_bytes;
714 
715 	/* extract compressed length of base */
716 	uint32_t complen_base = (src[ecc_bytes + 0] << 8) | src[ecc_bytes + 1];
717 	if (complen_bytes > 2)
718 		complen_base = (complen_base << 8) | src[ecc_bytes + 2];
719 
720 	/* reset and decode */
721 	zlib_codec_decompress(&cdzl->base_decompressor, &src[header_bytes], complen_base, &cdzl->buffer[0], frames * CD_MAX_SECTOR_DATA);
722 #ifdef WANT_SUBCODE
723 	zlib_codec_decompress(&cdzl->subcode_decompressor, &src[header_bytes + complen_base], complen - complen_base - header_bytes, &cdzl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
724 #endif
725 
726 	/* reassemble the data */
727 	for (framenum = 0; framenum < frames; framenum++)
728 	{
729 		uint8_t *sector;
730 
731 		memcpy(&dest[framenum * CD_FRAME_SIZE], &cdzl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
732 #ifdef WANT_SUBCODE
733 		memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdzl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
734 #endif
735 
736 #ifdef WANT_RAW_DATA_SECTOR
737 		/* reconstitute the ECC data and sync header */
738 		sector = (uint8_t *)&dest[framenum * CD_FRAME_SIZE];
739 		if ((src[framenum / 8] & (1 << (framenum % 8))) != 0)
740 		{
741 			memcpy(sector, s_cd_sync_header, sizeof(s_cd_sync_header));
742 			ecc_generate(sector);
743 		}
744 #endif
745 	}
746 	return CHDERR_NONE;
747 }
748 
749 /***************************************************************************
750  *  CD FLAC DECOMPRESSOR
751  ***************************************************************************
752  */
753 
754 /*------------------------------------------------------
755  *  cdfl_codec_blocksize - return the optimal block size
756  *------------------------------------------------------
757  */
758 
cdfl_codec_blocksize(uint32_t bytes)759 static uint32_t cdfl_codec_blocksize(uint32_t bytes)
760 {
761 	/* determine FLAC block size, which must be 16-65535
762 	 * clamp to 2k since that's supposed to be the sweet spot */
763 	uint32_t hunkbytes = bytes / 4;
764 	while (hunkbytes > 2048)
765 		hunkbytes /= 2;
766 	return hunkbytes;
767 }
768 
cdfl_codec_init(void * codec,uint32_t hunkbytes)769 static chd_error cdfl_codec_init(void *codec, uint32_t hunkbytes)
770 {
771 #ifdef WANT_SUBCODE
772 	chd_error ret;
773 #endif
774 	uint16_t native_endian = 0;
775 	cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
776 
777 	/* make sure the CHD's hunk size is an even multiple of the frame size */
778 	if (hunkbytes % CD_FRAME_SIZE != 0)
779 		return CHDERR_CODEC_ERROR;
780 
781 	cdfl->buffer = (uint8_t*)malloc(sizeof(uint8_t) * hunkbytes);
782 	if (cdfl->buffer == NULL)
783 		return CHDERR_OUT_OF_MEMORY;
784 
785 	/* determine whether we want native or swapped samples */
786 	*(uint8_t *)(&native_endian) = 1;
787 	cdfl->swap_endian = (native_endian & 1);
788 
789 #ifdef WANT_SUBCODE
790 	/* init zlib inflater */
791 	ret = zlib_codec_init(&cdfl->subcode_decompressor, (hunkbytes / CD_FRAME_SIZE) * CD_MAX_SECTOR_DATA);
792 	if (ret != CHDERR_NONE)
793 		return ret;
794 #endif
795 
796 	/* flac decoder init */
797 	flac_decoder_init(&cdfl->decoder);
798 	if (cdfl->decoder.decoder == NULL)
799 		return CHDERR_OUT_OF_MEMORY;
800 
801 	return CHDERR_NONE;
802 }
803 
cdfl_codec_free(void * codec)804 static void cdfl_codec_free(void *codec)
805 {
806 	cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
807 	flac_decoder_free(&cdfl->decoder);
808 #ifdef WANT_SUBCODE
809 	zlib_codec_free(&cdfl->subcode_decompressor);
810 #endif
811 	if (cdfl->buffer)
812 		free(cdfl->buffer);
813 }
814 
cdfl_codec_decompress(void * codec,const uint8_t * src,uint32_t complen,uint8_t * dest,uint32_t destlen)815 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
816 {
817 	uint32_t framenum;
818 	uint8_t *buffer;
819 #ifdef WANT_SUBCODE
820 	uint32_t offset;
821 	chd_error ret;
822 #endif
823 	cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
824 
825 	/* reset and decode */
826 	uint32_t frames = destlen / CD_FRAME_SIZE;
827 
828 	if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
829 		return CHDERR_DECOMPRESSION_ERROR;
830 	buffer = &cdfl->buffer[0];
831 	if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian))
832 		return CHDERR_DECOMPRESSION_ERROR;
833 
834 #ifdef WANT_SUBCODE
835 	/* inflate the subcode data */
836 	offset = flac_decoder_finish(&cdfl->decoder);
837 	ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
838 	if (ret != CHDERR_NONE)
839 		return ret;
840 #else
841 	flac_decoder_finish(&cdfl->decoder);
842 #endif
843 
844 	/* reassemble the data */
845 	for (framenum = 0; framenum < frames; framenum++)
846 	{
847 		memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
848 #ifdef WANT_SUBCODE
849 		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);
850 #endif
851 	}
852 
853 	return CHDERR_NONE;
854 }
855 /***************************************************************************
856     CODEC INTERFACES
857 ***************************************************************************/
858 
859 static const codec_interface codec_interfaces[] =
860 {
861 	/* "none" or no compression */
862 	{
863 		CHDCOMPRESSION_NONE,
864 		"none",
865 		FALSE,
866 		NULL,
867 		NULL,
868 		NULL,
869 		NULL
870 	},
871 
872 	/* standard zlib compression */
873 	{
874 		CHDCOMPRESSION_ZLIB,
875 		"zlib",
876 		FALSE,
877 		zlib_codec_init,
878 		zlib_codec_free,
879 		zlib_codec_decompress,
880 		NULL
881 	},
882 
883 	/* zlib+ compression */
884 	{
885 		CHDCOMPRESSION_ZLIB_PLUS,
886 		"zlib+",
887 		FALSE,
888 		zlib_codec_init,
889 		zlib_codec_free,
890 		zlib_codec_decompress,
891 		NULL
892 	},
893 
894 	/* V5 zlib compression */
895 	{
896 		CHD_CODEC_ZLIB,
897 		"zlib (Deflate)",
898 		FALSE,
899 		zlib_codec_init,
900 		zlib_codec_free,
901 		zlib_codec_decompress,
902 		NULL
903 	},
904 
905 	/* V5 CD zlib compression */
906 	{
907 		CHD_CODEC_CD_ZLIB,
908 		"cdzl (CD Deflate)",
909 		FALSE,
910 		cdzl_codec_init,
911 		cdzl_codec_free,
912 		cdzl_codec_decompress,
913 		NULL
914 	},
915 
916 	/* V5 CD lzma compression */
917 	{
918 		CHD_CODEC_CD_LZMA,
919 		"cdlz (CD LZMA)",
920 		FALSE,
921 		cdlz_codec_init,
922 		cdlz_codec_free,
923 		cdlz_codec_decompress,
924 		NULL
925 	},
926 
927 	/* V5 CD flac compression */
928 	{
929 		CHD_CODEC_CD_FLAC,
930 		"cdfl (CD FLAC)",
931 		FALSE,
932 		cdfl_codec_init,
933 		cdfl_codec_free,
934 		cdfl_codec_decompress,
935 		NULL
936 	},
937 };
938 
939 /***************************************************************************
940     INLINE FUNCTIONS
941 ***************************************************************************/
942 
943 /*-------------------------------------------------
944     get_bigendian_uint64 - fetch a UINT64 from
945     the data stream in bigendian order
946 -------------------------------------------------*/
947 
get_bigendian_uint64(const UINT8 * base)948 static INLINE UINT64 get_bigendian_uint64(const UINT8 *base)
949 {
950 	return ((UINT64)base[0] << 56) | ((UINT64)base[1] << 48) | ((UINT64)base[2] << 40) | ((UINT64)base[3] << 32) |
951 			((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
952 }
953 
954 /*-------------------------------------------------
955     put_bigendian_uint64 - write a UINT64 to
956     the data stream in bigendian order
957 -------------------------------------------------*/
958 
put_bigendian_uint64(UINT8 * base,UINT64 value)959 static INLINE void put_bigendian_uint64(UINT8 *base, UINT64 value)
960 {
961 	base[0] = value >> 56;
962 	base[1] = value >> 48;
963 	base[2] = value >> 40;
964 	base[3] = value >> 32;
965 	base[4] = value >> 24;
966 	base[5] = value >> 16;
967 	base[6] = value >> 8;
968 	base[7] = value;
969 }
970 
971 /*-------------------------------------------------
972     get_bigendian_uint48 - fetch a UINT48 from
973     the data stream in bigendian order
974 -------------------------------------------------*/
975 
get_bigendian_uint48(const UINT8 * base)976 static INLINE UINT64 get_bigendian_uint48(const UINT8 *base)
977 {
978 	return  ((UINT64)base[0] << 40) | ((UINT64)base[1] << 32) |
979 			((UINT64)base[2] << 24) | ((UINT64)base[3] << 16) | ((UINT64)base[4] << 8) | (UINT64)base[5];
980 }
981 
982 /*-------------------------------------------------
983     put_bigendian_uint48 - write a UINT48 to
984     the data stream in bigendian order
985 -------------------------------------------------*/
986 
put_bigendian_uint48(UINT8 * base,UINT64 value)987 static INLINE void put_bigendian_uint48(UINT8 *base, UINT64 value)
988 {
989 	value &= 0xffffffffffff;
990 	base[0] = value >> 40;
991 	base[1] = value >> 32;
992 	base[2] = value >> 24;
993 	base[3] = value >> 16;
994 	base[4] = value >> 8;
995 	base[5] = value;
996 }
997 /*-------------------------------------------------
998     get_bigendian_uint32 - fetch a UINT32 from
999     the data stream in bigendian order
1000 -------------------------------------------------*/
1001 
get_bigendian_uint32(const UINT8 * base)1002 static INLINE UINT32 get_bigendian_uint32(const UINT8 *base)
1003 {
1004 	return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
1005 }
1006 
1007 /*-------------------------------------------------
1008     put_bigendian_uint32 - write a UINT32 to
1009     the data stream in bigendian order
1010 -------------------------------------------------*/
1011 
put_bigendian_uint32(UINT8 * base,UINT32 value)1012 static INLINE void put_bigendian_uint32(UINT8 *base, UINT32 value)
1013 {
1014 	base[0] = value >> 24;
1015 	base[1] = value >> 16;
1016 	base[2] = value >> 8;
1017 	base[3] = value;
1018 }
1019 
1020 /*-------------------------------------------------
1021     put_bigendian_uint24 - write a UINT24 to
1022     the data stream in bigendian order
1023 -------------------------------------------------*/
1024 
put_bigendian_uint24(UINT8 * base,UINT32 value)1025 static INLINE void put_bigendian_uint24(UINT8 *base, UINT32 value)
1026 {
1027 	value &= 0xffffff;
1028 	base[0] = value >> 16;
1029 	base[1] = value >> 8;
1030 	base[2] = value;
1031 }
1032 
1033 /*-------------------------------------------------
1034     get_bigendian_uint24 - fetch a UINT24 from
1035     the data stream in bigendian order
1036 -------------------------------------------------*/
1037 
get_bigendian_uint24(const UINT8 * base)1038 static INLINE UINT32 get_bigendian_uint24(const UINT8 *base)
1039 {
1040 	return (base[0] << 16) | (base[1] << 8) | base[2];
1041 }
1042 
1043 /*-------------------------------------------------
1044     get_bigendian_uint16 - fetch a UINT16 from
1045     the data stream in bigendian order
1046 -------------------------------------------------*/
1047 
get_bigendian_uint16(const UINT8 * base)1048 static INLINE UINT16 get_bigendian_uint16(const UINT8 *base)
1049 {
1050 	return (base[0] << 8) | base[1];
1051 }
1052 
1053 /*-------------------------------------------------
1054     put_bigendian_uint16 - write a UINT16 to
1055     the data stream in bigendian order
1056 -------------------------------------------------*/
1057 
put_bigendian_uint16(UINT8 * base,UINT16 value)1058 static INLINE void put_bigendian_uint16(UINT8 *base, UINT16 value)
1059 {
1060 	base[0] = value >> 8;
1061 	base[1] = value;
1062 }
1063 
1064 /*-------------------------------------------------
1065     map_extract - extract a single map
1066     entry from the datastream
1067 -------------------------------------------------*/
1068 
map_extract(const UINT8 * base,map_entry * entry)1069 static INLINE void map_extract(const UINT8 *base, map_entry *entry)
1070 {
1071 	entry->offset = get_bigendian_uint64(&base[0]);
1072 	entry->crc = get_bigendian_uint32(&base[8]);
1073 	entry->length = get_bigendian_uint16(&base[12]) | (base[14] << 16);
1074 	entry->flags = base[15];
1075 }
1076 
1077 /*-------------------------------------------------
1078     map_assemble - write a single map
1079     entry to the datastream
1080 -------------------------------------------------*/
1081 
map_assemble(UINT8 * base,map_entry * entry)1082 static INLINE void map_assemble(UINT8 *base, map_entry *entry)
1083 {
1084 	put_bigendian_uint64(&base[0], entry->offset);
1085 	put_bigendian_uint32(&base[8], entry->crc);
1086 	put_bigendian_uint16(&base[12], entry->length);
1087 	base[14] = entry->length >> 16;
1088 	base[15] = entry->flags;
1089 }
1090 
1091 /*-------------------------------------------------
1092     map_size_v5 - calculate CHDv5 map size
1093 -------------------------------------------------*/
map_size_v5(chd_header * header)1094 static INLINE int map_size_v5(chd_header* header)
1095 {
1096 	return header->hunkcount * header->mapentrybytes;
1097 }
1098 
1099 /*-------------------------------------------------
1100     crc16 - calculate CRC16 (from hashing.cpp)
1101 -------------------------------------------------*/
crc16(const void * data,uint32_t length)1102 uint16_t crc16(const void *data, uint32_t length)
1103 {
1104 	uint16_t crc = 0xffff;
1105 
1106 	static const uint16_t s_table[256] =
1107 	{
1108 		0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1109 		0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1110 		0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1111 		0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1112 		0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1113 		0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1114 		0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1115 		0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1116 		0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1117 		0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1118 		0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1119 		0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1120 		0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1121 		0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1122 		0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1123 		0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1124 		0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1125 		0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1126 		0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1127 		0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1128 		0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1129 		0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1130 		0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1131 		0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1132 		0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1133 		0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1134 		0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1135 		0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1136 		0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1137 		0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1138 		0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1139 		0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1140 	};
1141 
1142 	const uint8_t *src = (uint8_t*)data;
1143 
1144 	/* fetch the current value into a local and rip through the source data */
1145 	while (length-- != 0)
1146 		crc = (crc << 8) ^ s_table[(crc >> 8) ^ *src++];
1147 	return crc;
1148 }
1149 
1150 /*-------------------------------------------------
1151 	compressed - test if CHD file is compressed
1152 +-------------------------------------------------*/
chd_compressed(chd_header * header)1153 static INLINE int chd_compressed(chd_header* header) {
1154 	return header->compression[0] != CHD_CODEC_NONE;
1155 }
1156 
1157 /*-------------------------------------------------
1158 	decompress_v5_map - decompress the v5 map
1159 -------------------------------------------------*/
1160 
decompress_v5_map(chd_file * chd,chd_header * header)1161 static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
1162 {
1163 	int result = 0;
1164 	int hunknum;
1165 	int repcount = 0;
1166 	uint8_t lastcomp = 0;
1167 	uint32_t last_self = 0;
1168 	uint64_t last_parent = 0;
1169 	struct bitstream* bitbuf;
1170 	uint32_t mapbytes;
1171 	uint64_t firstoffs;
1172 	uint16_t mapcrc;
1173 	uint8_t lengthbits;
1174 	uint8_t selfbits;
1175 	uint8_t parentbits;
1176 	uint8_t *compressed_ptr;
1177 	uint8_t rawbuf[16];
1178 	struct huffman_decoder* decoder;
1179 	enum huffman_error err;
1180 	uint64_t curoffset;
1181 	int rawmapsize = map_size_v5(header);
1182 
1183 	if (!chd_compressed(header))
1184 	{
1185 		header->rawmap = (uint8_t*)malloc(rawmapsize);
1186 		core_fseek(chd->file, header->mapoffset, SEEK_SET);
1187 		result = core_fread(chd->file, header->rawmap, rawmapsize);
1188 		return CHDERR_NONE;
1189 	}
1190 
1191 	/* read the reader */
1192 	core_fseek(chd->file, header->mapoffset, SEEK_SET);
1193 	result = core_fread(chd->file, rawbuf, sizeof(rawbuf));
1194 	mapbytes = get_bigendian_uint32(&rawbuf[0]);
1195 	firstoffs = get_bigendian_uint48(&rawbuf[4]);
1196 	mapcrc = get_bigendian_uint16(&rawbuf[10]);
1197 	lengthbits = rawbuf[12];
1198 	selfbits = rawbuf[13];
1199 	parentbits = rawbuf[14];
1200 
1201 	/* now read the map */
1202 	compressed_ptr = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes);
1203 	core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
1204 	result = core_fread(chd->file, compressed_ptr, mapbytes);
1205 	bitbuf = create_bitstream(compressed_ptr, sizeof(uint8_t) * mapbytes);
1206 	header->rawmap = (uint8_t*)malloc(rawmapsize);
1207 
1208 	/* first decode the compression types */
1209 	decoder = create_huffman_decoder(16, 8);
1210 	if (decoder == NULL)
1211 	{
1212 		free(compressed_ptr);
1213 		free(bitbuf);
1214 		return CHDERR_OUT_OF_MEMORY;
1215 	}
1216 
1217 	err = huffman_import_tree_rle(decoder, bitbuf);
1218 	if (err != HUFFERR_NONE)
1219 	{
1220 		free(compressed_ptr);
1221 		free(bitbuf);
1222 		delete_huffman_decoder(decoder);
1223 		return CHDERR_DECOMPRESSION_ERROR;
1224 	}
1225 
1226 	for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1227 	{
1228 		uint8_t *rawmap = header->rawmap + (hunknum * 12);
1229 		if (repcount > 0)
1230 			rawmap[0] = lastcomp, repcount--;
1231 		else
1232 		{
1233 			uint8_t val = huffman_decode_one(decoder, bitbuf);
1234 			if (val == COMPRESSION_RLE_SMALL)
1235 				rawmap[0] = lastcomp, repcount = 2 + huffman_decode_one(decoder, bitbuf);
1236 			else if (val == COMPRESSION_RLE_LARGE)
1237 				rawmap[0] = lastcomp, repcount = 2 + 16 + (huffman_decode_one(decoder, bitbuf) << 4), repcount += huffman_decode_one(decoder, bitbuf);
1238 			else
1239 				rawmap[0] = lastcomp = val;
1240 		}
1241 	}
1242 
1243 	/* then iterate through the hunks and extract the needed data */
1244 	curoffset = firstoffs;
1245 	for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1246 	{
1247 		uint8_t *rawmap = header->rawmap + (hunknum * 12);
1248 		uint64_t offset = curoffset;
1249 		uint32_t length = 0;
1250 		uint16_t crc = 0;
1251 		switch (rawmap[0])
1252 		{
1253 			/* base types */
1254 			case COMPRESSION_TYPE_0:
1255 			case COMPRESSION_TYPE_1:
1256 			case COMPRESSION_TYPE_2:
1257 			case COMPRESSION_TYPE_3:
1258 				curoffset += length = bitstream_read(bitbuf, lengthbits);
1259 				crc = bitstream_read(bitbuf, 16);
1260 				break;
1261 
1262 			case COMPRESSION_NONE:
1263 				curoffset += length = header->hunkbytes;
1264 				crc = bitstream_read(bitbuf, 16);
1265 				break;
1266 
1267 			case COMPRESSION_SELF:
1268 				last_self = offset = bitstream_read(bitbuf, selfbits);
1269 				break;
1270 
1271 			case COMPRESSION_PARENT:
1272 				offset = bitstream_read(bitbuf, parentbits);
1273 				last_parent = offset;
1274 				break;
1275 
1276 			/* pseudo-types; convert into base types */
1277 			case COMPRESSION_SELF_1:
1278 				last_self++;
1279 			case COMPRESSION_SELF_0:
1280 				rawmap[0] = COMPRESSION_SELF;
1281 				offset = last_self;
1282 				break;
1283 
1284 			case COMPRESSION_PARENT_SELF:
1285 				rawmap[0] = COMPRESSION_PARENT;
1286 				last_parent = offset = ( ((uint64_t)hunknum) * ((uint64_t)header->hunkbytes) ) / header->unitbytes;
1287 				break;
1288 
1289 			case COMPRESSION_PARENT_1:
1290 				last_parent += header->hunkbytes / header->unitbytes;
1291 			case COMPRESSION_PARENT_0:
1292 				rawmap[0] = COMPRESSION_PARENT;
1293 				offset = last_parent;
1294 				break;
1295 		}
1296 		/* UINT24 length */
1297 		put_bigendian_uint24(&rawmap[1], length);
1298 
1299 		/* UINT48 offset */
1300 		put_bigendian_uint48(&rawmap[4], offset);
1301 
1302 		/* crc16 */
1303 		put_bigendian_uint16(&rawmap[10], crc);
1304 	}
1305 
1306 	/* free memory */
1307 	free(compressed_ptr);
1308 	free(bitbuf);
1309 	delete_huffman_decoder(decoder);
1310 
1311 	/* verify the final CRC */
1312 	if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc)
1313 		return CHDERR_DECOMPRESSION_ERROR;
1314 
1315 	return CHDERR_NONE;
1316 }
1317 
1318 /*-------------------------------------------------
1319     map_extract_old - extract a single map
1320     entry in old format from the datastream
1321 -------------------------------------------------*/
1322 
map_extract_old(const UINT8 * base,map_entry * entry,UINT32 hunkbytes)1323 static INLINE void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 hunkbytes)
1324 {
1325 	entry->offset = get_bigendian_uint64(&base[0]);
1326 	entry->crc = 0;
1327 	entry->length = entry->offset >> 44;
1328 	entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
1329 #ifdef __MWERKS__
1330 	entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
1331 #else
1332 	entry->offset = (entry->offset << 20) >> 20;
1333 #endif
1334 }
1335 
1336 /***************************************************************************
1337     CHD FILE MANAGEMENT
1338 ***************************************************************************/
1339 
1340 /*-------------------------------------------------
1341     chd_open_file - open a CHD file for access
1342 -------------------------------------------------*/
1343 
chd_open_file(core_file * file,int mode,chd_file * parent,chd_file ** chd)1344 CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd)
1345 {
1346 	chd_file *newchd = NULL;
1347 	chd_error err;
1348 	int intfnum;
1349 
1350 	/* verify parameters */
1351 	if (file == NULL)
1352 		EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1353 
1354 	/* punt if invalid parent */
1355 	if (parent != NULL && parent->cookie != COOKIE_VALUE)
1356 		EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1357 
1358 	/* allocate memory for the final result */
1359 	newchd = (chd_file *)malloc(sizeof(**chd));
1360 	if (newchd == NULL)
1361 		EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1362 	memset(newchd, 0, sizeof(*newchd));
1363 	newchd->cookie = COOKIE_VALUE;
1364 	newchd->parent = parent;
1365 	newchd->file = file;
1366 
1367 	/* now attempt to read the header */
1368 	err = header_read(newchd, &newchd->header);
1369 	if (err != CHDERR_NONE)
1370 		EARLY_EXIT(err);
1371 
1372 	/* validate the header */
1373 	err = header_validate(&newchd->header);
1374 	if (err != CHDERR_NONE)
1375 		EARLY_EXIT(err);
1376 
1377 	/* make sure we don't open a read-only file writeable */
1378 	if (mode == CHD_OPEN_READWRITE && !(newchd->header.flags & CHDFLAGS_IS_WRITEABLE))
1379 		EARLY_EXIT(err = CHDERR_FILE_NOT_WRITEABLE);
1380 
1381 	/* also, never open an older version writeable */
1382 	if (mode == CHD_OPEN_READWRITE && newchd->header.version < CHD_HEADER_VERSION)
1383 		EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
1384 
1385 	/* if we need a parent, make sure we have one */
1386 	if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
1387 		EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1388 
1389 	/* make sure we have a valid parent */
1390 	if (parent != NULL)
1391 	{
1392 		/* check MD5 if it isn't empty */
1393 		if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1394 			memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1395 			memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1396 			EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1397 
1398 		/* check SHA1 if it isn't empty */
1399 		if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1400 			memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1401 			memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1402 			EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1403 	}
1404 
1405 	/* now read the hunk map */
1406 	if (newchd->header.version < 5)
1407 	{
1408 		err = map_read(newchd);
1409 		if (err != CHDERR_NONE)
1410 			EARLY_EXIT(err);
1411 	}
1412 	else
1413 	{
1414 		err = decompress_v5_map(newchd, &(newchd->header));
1415 	}
1416 	if (err != CHDERR_NONE)
1417 		EARLY_EXIT(err);
1418 
1419 #ifdef NEED_CACHE_HUNK
1420 	/* allocate and init the hunk cache */
1421 	newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1422 	newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1423 	if (newchd->cache == NULL || newchd->compare == NULL)
1424 		EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1425 	newchd->cachehunk = ~0;
1426 	newchd->comparehunk = ~0;
1427 #endif
1428 
1429 	/* allocate the temporary compressed buffer */
1430 	newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1431 	if (newchd->compressed == NULL)
1432 		EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1433 
1434 	/* find the codec interface */
1435 	if (newchd->header.version < 5)
1436 	{
1437 		for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1438 		{
1439 			if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1440 			{
1441 				newchd->codecintf[0] = &codec_interfaces[intfnum];
1442 				break;
1443 			}
1444 		}
1445 
1446 		if (intfnum == ARRAY_LENGTH(codec_interfaces))
1447 			EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1448 
1449 		/* initialize the codec */
1450 		if (newchd->codecintf[0]->init != NULL)
1451 		{
1452 			err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1453 			if (err != CHDERR_NONE)
1454 				EARLY_EXIT(err);
1455 		}
1456 	}
1457 	else
1458 	{
1459 		int decompnum;
1460 		/* verify the compression types and initialize the codecs */
1461 		for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1462 		{
1463 			int i;
1464 			for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1465 			{
1466 				if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1467 				{
1468 					newchd->codecintf[decompnum] = &codec_interfaces[i];
1469 					break;
1470 				}
1471 			}
1472 
1473 			if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1474 				EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1475 
1476 			/* initialize the codec */
1477 			if (newchd->codecintf[decompnum]->init != NULL)
1478 			{
1479 				void* codec = NULL;
1480 				switch (newchd->header.compression[decompnum])
1481 				{
1482 					case CHD_CODEC_ZLIB:
1483 						codec = &newchd->zlib_codec_data;
1484 						break;
1485 
1486 					case CHD_CODEC_CD_ZLIB:
1487 						codec = &newchd->cdzl_codec_data;
1488 						break;
1489 
1490 					case CHD_CODEC_CD_LZMA:
1491 						codec = &newchd->cdlz_codec_data;
1492 						break;
1493 
1494 					case CHD_CODEC_CD_FLAC:
1495 						codec = &newchd->cdfl_codec_data;
1496 						break;
1497 				}
1498 
1499 				if (codec == NULL)
1500 					EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1501 
1502 				err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1503 				if (err != CHDERR_NONE)
1504 					EARLY_EXIT(err);
1505 			}
1506 		}
1507 	}
1508 
1509 	/* all done */
1510 	*chd = newchd;
1511 	return CHDERR_NONE;
1512 
1513 cleanup:
1514 	if (newchd != NULL)
1515 		chd_close(newchd);
1516 	return err;
1517 }
1518 
1519 /*-------------------------------------------------
1520     chd_precache - precache underlying file in
1521     memory
1522 -------------------------------------------------*/
1523 
chd_precache(chd_file * chd)1524 CHD_EXPORT chd_error chd_precache(chd_file *chd)
1525 {
1526 	ssize_t size, count;
1527 
1528 	if (chd->file_cache == NULL)
1529 	{
1530 		core_fseek(chd->file, 0, SEEK_END);
1531 		size = core_ftell(chd->file);
1532 		if (size <= 0)
1533 			return CHDERR_INVALID_DATA;
1534 		chd->file_cache = malloc(size);
1535 		if (chd->file_cache == NULL)
1536 			return CHDERR_OUT_OF_MEMORY;
1537 		core_fseek(chd->file, 0, SEEK_SET);
1538 		count = core_fread(chd->file, chd->file_cache, size);
1539 		if (count != size)
1540 		{
1541 			free(chd->file_cache);
1542 			chd->file_cache = NULL;
1543 			return CHDERR_READ_ERROR;
1544 		}
1545 	}
1546 
1547 	return CHDERR_NONE;
1548 }
1549 
1550 /*-------------------------------------------------
1551     chd_open - open a CHD file by
1552     filename
1553 -------------------------------------------------*/
1554 
chd_open(const char * filename,int mode,chd_file * parent,chd_file ** chd)1555 CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1556 {
1557 	chd_error err;
1558 	core_file *file = NULL;
1559 
1560 	/* choose the proper mode */
1561 	switch(mode)
1562 	{
1563 		case CHD_OPEN_READ:
1564 			break;
1565 
1566 		default:
1567 			err = CHDERR_INVALID_PARAMETER;
1568 			goto cleanup;
1569 	}
1570 
1571 	/* open the file */
1572 	file = core_fopen(filename);
1573 	if (file == 0)
1574 	{
1575 		err = CHDERR_FILE_NOT_FOUND;
1576 		goto cleanup;
1577 	}
1578 
1579 	/* now open the CHD */
1580 	err = chd_open_file(file, mode, parent, chd);
1581 	if (err != CHDERR_NONE)
1582 		goto cleanup;
1583 
1584 	/* we now own this file */
1585 	(*chd)->owns_file = TRUE;
1586 
1587 cleanup:
1588 	if ((err != CHDERR_NONE) && (file != NULL))
1589 		core_fclose(file);
1590 	return err;
1591 }
1592 
1593 /*-------------------------------------------------
1594     chd_close - close a CHD file for access
1595 -------------------------------------------------*/
1596 
chd_close(chd_file * chd)1597 CHD_EXPORT void chd_close(chd_file *chd)
1598 {
1599 	/* punt if NULL or invalid */
1600 	if (chd == NULL || chd->cookie != COOKIE_VALUE)
1601 		return;
1602 
1603 	/* deinit the codec */
1604 	if (chd->header.version < 5)
1605 	{
1606 		if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1607 			(*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1608 	}
1609 	else
1610 	{
1611 		int i;
1612 		/* Free the codecs */
1613 		for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
1614 		{
1615 			void* codec = NULL;
1616 
1617 			if (chd->codecintf[i] == NULL)
1618 				continue;
1619 
1620 			switch (chd->codecintf[i]->compression)
1621 			{
1622 				case CHD_CODEC_CD_LZMA:
1623 					codec = &chd->cdlz_codec_data;
1624 					break;
1625 
1626 				case CHD_CODEC_ZLIB:
1627 					codec = &chd->zlib_codec_data;
1628 					break;
1629 
1630 				case CHD_CODEC_CD_ZLIB:
1631 					codec = &chd->cdzl_codec_data;
1632 					break;
1633 
1634 				case CHD_CODEC_CD_FLAC:
1635 					codec = &chd->cdfl_codec_data;
1636 					break;
1637 			}
1638 
1639 			if (codec)
1640 			{
1641 				(*chd->codecintf[i]->free)(codec);
1642 			}
1643 		}
1644 
1645 		/* Free the raw map */
1646 		if (chd->header.rawmap != NULL)
1647 			free(chd->header.rawmap);
1648 	}
1649 
1650 	/* free the compressed data buffer */
1651 	if (chd->compressed != NULL)
1652 		free(chd->compressed);
1653 
1654 #ifdef NEED_CACHE_HUNK
1655 	/* free the hunk cache and compare data */
1656 	if (chd->compare != NULL)
1657 		free(chd->compare);
1658 	if (chd->cache != NULL)
1659 		free(chd->cache);
1660 #endif
1661 
1662 	/* free the hunk map */
1663 	if (chd->map != NULL)
1664 		free(chd->map);
1665 
1666 	/* close the file */
1667 	if (chd->owns_file && chd->file != NULL)
1668 		core_fclose(chd->file);
1669 
1670 #ifdef NEED_CACHE_HUNK
1671 	if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1672 #endif
1673 	if (chd->file_cache)
1674 		free(chd->file_cache);
1675 
1676 	/* free our memory */
1677 	free(chd);
1678 }
1679 
1680 /*-------------------------------------------------
1681     chd_core_file - return the associated
1682     core_file
1683 -------------------------------------------------*/
1684 
chd_core_file(chd_file * chd)1685 CHD_EXPORT core_file *chd_core_file(chd_file *chd)
1686 {
1687 	return chd->file;
1688 }
1689 
1690 /*-------------------------------------------------
1691     chd_error_string - return an error string for
1692     the given CHD error
1693 -------------------------------------------------*/
1694 
chd_error_string(chd_error err)1695 CHD_EXPORT const char *chd_error_string(chd_error err)
1696 {
1697 	switch (err)
1698 	{
1699 		case CHDERR_NONE:						return "no error";
1700 		case CHDERR_NO_INTERFACE:				return "no drive interface";
1701 		case CHDERR_OUT_OF_MEMORY:				return "out of memory";
1702 		case CHDERR_INVALID_FILE:				return "invalid file";
1703 		case CHDERR_INVALID_PARAMETER:			return "invalid parameter";
1704 		case CHDERR_INVALID_DATA:				return "invalid data";
1705 		case CHDERR_FILE_NOT_FOUND:				return "file not found";
1706 		case CHDERR_REQUIRES_PARENT:			return "requires parent";
1707 		case CHDERR_FILE_NOT_WRITEABLE:			return "file not writeable";
1708 		case CHDERR_READ_ERROR:					return "read error";
1709 		case CHDERR_WRITE_ERROR:				return "write error";
1710 		case CHDERR_CODEC_ERROR:				return "codec error";
1711 		case CHDERR_INVALID_PARENT:				return "invalid parent";
1712 		case CHDERR_HUNK_OUT_OF_RANGE:			return "hunk out of range";
1713 		case CHDERR_DECOMPRESSION_ERROR:		return "decompression error";
1714 		case CHDERR_COMPRESSION_ERROR:			return "compression error";
1715 		case CHDERR_CANT_CREATE_FILE:			return "can't create file";
1716 		case CHDERR_CANT_VERIFY:				return "can't verify file";
1717 		case CHDERR_NOT_SUPPORTED:				return "operation not supported";
1718 		case CHDERR_METADATA_NOT_FOUND:			return "can't find metadata";
1719 		case CHDERR_INVALID_METADATA_SIZE:		return "invalid metadata size";
1720 		case CHDERR_UNSUPPORTED_VERSION:		return "unsupported CHD version";
1721 		case CHDERR_VERIFY_INCOMPLETE:			return "incomplete verify";
1722 		case CHDERR_INVALID_METADATA:			return "invalid metadata";
1723 		case CHDERR_INVALID_STATE:				return "invalid state";
1724 		case CHDERR_OPERATION_PENDING:			return "operation pending";
1725 		case CHDERR_NO_ASYNC_OPERATION:			return "no async operation in progress";
1726 		case CHDERR_UNSUPPORTED_FORMAT:			return "unsupported format";
1727 		default:								return "undocumented error";
1728 	}
1729 }
1730 
1731 /***************************************************************************
1732     CHD HEADER MANAGEMENT
1733 ***************************************************************************/
1734 
1735 /*-------------------------------------------------
1736     chd_get_header - return a pointer to the
1737     extracted header data
1738 -------------------------------------------------*/
1739 
chd_get_header(chd_file * chd)1740 CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
1741 {
1742 	/* punt if NULL or invalid */
1743 	if (chd == NULL || chd->cookie != COOKIE_VALUE)
1744 		return NULL;
1745 
1746 	return &chd->header;
1747 }
1748 
1749 /***************************************************************************
1750     CORE DATA READ/WRITE
1751 ***************************************************************************/
1752 
1753 /*-------------------------------------------------
1754     chd_read - read a single hunk from the CHD
1755     file
1756 -------------------------------------------------*/
1757 
chd_read(chd_file * chd,UINT32 hunknum,void * buffer)1758 CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1759 {
1760 	/* punt if NULL or invalid */
1761 	if (chd == NULL || chd->cookie != COOKIE_VALUE)
1762 		return CHDERR_INVALID_PARAMETER;
1763 
1764 	/* if we're past the end, fail */
1765 	if (hunknum >= chd->header.totalhunks)
1766 		return CHDERR_HUNK_OUT_OF_RANGE;
1767 
1768 	/* perform the read */
1769 	return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1770 }
1771 
1772 /***************************************************************************
1773     METADATA MANAGEMENT
1774 ***************************************************************************/
1775 
1776 /*-------------------------------------------------
1777     chd_get_metadata - get the indexed metadata
1778     of the given type
1779 -------------------------------------------------*/
1780 
chd_get_metadata(chd_file * chd,UINT32 searchtag,UINT32 searchindex,void * output,UINT32 outputlen,UINT32 * resultlen,UINT32 * resulttag,UINT8 * resultflags)1781 CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1782 {
1783 	metadata_entry metaentry;
1784 	chd_error err;
1785 	UINT32 count;
1786 
1787 	/* if we didn't find it, just return */
1788 	err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1789 	if (err != CHDERR_NONE)
1790 	{
1791 		/* unless we're an old version and they are requesting hard disk metadata */
1792 		if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1793 		{
1794 			char faux_metadata[256];
1795 			UINT32 faux_length;
1796 
1797 			/* fill in the faux metadata */
1798 			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);
1799 			faux_length = (UINT32)strlen(faux_metadata) + 1;
1800 
1801 			/* copy the metadata itself */
1802 			memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1803 
1804 			/* return the length of the data and the tag */
1805 			if (resultlen != NULL)
1806 				*resultlen = faux_length;
1807 			if (resulttag != NULL)
1808 				*resulttag = HARD_DISK_METADATA_TAG;
1809 			return CHDERR_NONE;
1810 		}
1811 		return err;
1812 	}
1813 
1814 	/* read the metadata */
1815 	outputlen = MIN(outputlen, metaentry.length);
1816 	core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1817 	count = core_fread(chd->file, output, outputlen);
1818 	if (count != outputlen)
1819 		return CHDERR_READ_ERROR;
1820 
1821 	/* return the length of the data and the tag */
1822 	if (resultlen != NULL)
1823 		*resultlen = metaentry.length;
1824 	if (resulttag != NULL)
1825 		*resulttag = metaentry.metatag;
1826 	if (resultflags != NULL)
1827 		*resultflags = metaentry.flags;
1828 	return CHDERR_NONE;
1829 }
1830 
1831 /***************************************************************************
1832     CODEC INTERFACES
1833 ***************************************************************************/
1834 
1835 /*-------------------------------------------------
1836     chd_codec_config - set internal codec
1837     parameters
1838 -------------------------------------------------*/
1839 
chd_codec_config(chd_file * chd,int param,void * config)1840 CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config)
1841 {
1842 	return CHDERR_INVALID_PARAMETER;
1843 }
1844 
1845 /*-------------------------------------------------
1846     chd_get_codec_name - get the name of a
1847     particular codec
1848 -------------------------------------------------*/
1849 
chd_get_codec_name(UINT32 codec)1850 CHD_EXPORT const char *chd_get_codec_name(UINT32 codec)
1851 {
1852 	return "Unknown";
1853 }
1854 
1855 /***************************************************************************
1856     INTERNAL HEADER OPERATIONS
1857 ***************************************************************************/
1858 
1859 /*-------------------------------------------------
1860     header_validate - check the validity of a
1861     CHD header
1862 -------------------------------------------------*/
1863 
header_validate(const chd_header * header)1864 static chd_error header_validate(const chd_header *header)
1865 {
1866 	int intfnum;
1867 
1868 	/* require a valid version */
1869 	if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1870 		return CHDERR_UNSUPPORTED_VERSION;
1871 
1872 	/* require a valid length */
1873 	if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1874 		(header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1875 		(header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1876 		(header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1877 		(header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1878 		return CHDERR_INVALID_PARAMETER;
1879 
1880 	/* Do not validate v5 header */
1881 	if (header->version <= 4)
1882 	{
1883 		/* require valid flags */
1884 		if (header->flags & CHDFLAGS_UNDEFINED)
1885 			return CHDERR_INVALID_PARAMETER;
1886 
1887 		/* require a supported compression mechanism */
1888 		for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1889 			if (codec_interfaces[intfnum].compression == header->compression[0])
1890 				break;
1891 
1892 		if (intfnum == ARRAY_LENGTH(codec_interfaces))
1893 			return CHDERR_INVALID_PARAMETER;
1894 
1895 		/* require a valid hunksize */
1896 		if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1897 			return CHDERR_INVALID_PARAMETER;
1898 
1899 		/* require a valid hunk count */
1900 		if (header->totalhunks == 0)
1901 			return CHDERR_INVALID_PARAMETER;
1902 
1903 		/* require a valid MD5 and/or SHA1 if we're using a parent */
1904 		if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1905 			return CHDERR_INVALID_PARAMETER;
1906 
1907 		/* if we're V3 or later, the obsolete fields must be 0 */
1908 		if (header->version >= 3 &&
1909 			(header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1910 			 header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1911 			return CHDERR_INVALID_PARAMETER;
1912 
1913 		/* if we're pre-V3, the obsolete fields must NOT be 0 */
1914 		if (header->version < 3 &&
1915 			(header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1916 			 header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1917 			return CHDERR_INVALID_PARAMETER;
1918 	}
1919 
1920 	return CHDERR_NONE;
1921 }
1922 
1923 /*-------------------------------------------------
1924     header_guess_unitbytes - for older CHD formats,
1925     guess at the bytes/unit based on metadata
1926 -------------------------------------------------*/
1927 
header_guess_unitbytes(chd_file * chd)1928 static UINT32 header_guess_unitbytes(chd_file *chd)
1929 {
1930 	/* look for hard disk metadata; if found, then the unit size == sector size */
1931 	char metadata[512];
1932 	int i0, i1, i2, i3;
1933 	if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
1934 		sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
1935 		return i3;
1936 
1937 	/* look for CD-ROM metadata; if found, then the unit size == CD frame size */
1938 	if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1939 		chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1940 		chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1941 		chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1942 		chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
1943 		return CD_FRAME_SIZE;
1944 
1945 	/* otherwise, just map 1:1 with the hunk size */
1946 	return chd->header.hunkbytes;
1947 }
1948 
1949 /*-------------------------------------------------
1950     header_read - read a CHD header into the
1951     internal data structure
1952 -------------------------------------------------*/
1953 
header_read(chd_file * chd,chd_header * header)1954 static chd_error header_read(chd_file *chd, chd_header *header)
1955 {
1956 	UINT8 rawheader[CHD_MAX_HEADER_SIZE];
1957 	UINT32 count;
1958 
1959 	/* punt if NULL */
1960 	if (header == NULL)
1961 		return CHDERR_INVALID_PARAMETER;
1962 
1963 	/* punt if invalid file */
1964 	if (chd->file == NULL)
1965 		return CHDERR_INVALID_FILE;
1966 
1967 	/* seek and read */
1968 	core_fseek(chd->file, 0, SEEK_SET);
1969 	count = core_fread(chd->file, rawheader, sizeof(rawheader));
1970 	if (count != sizeof(rawheader))
1971 		return CHDERR_READ_ERROR;
1972 
1973 	/* verify the tag */
1974 	if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
1975 		return CHDERR_INVALID_DATA;
1976 
1977 	/* extract the direct data */
1978 	memset(header, 0, sizeof(*header));
1979 	header->length        = get_bigendian_uint32(&rawheader[8]);
1980 	header->version       = get_bigendian_uint32(&rawheader[12]);
1981 
1982 	/* make sure it's a version we understand */
1983 	if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1984 		return CHDERR_UNSUPPORTED_VERSION;
1985 
1986 	/* make sure the length is expected */
1987 	if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1988 		(header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1989 		(header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1990 		(header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1991 		(header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1992 
1993 		return CHDERR_INVALID_DATA;
1994 
1995 	/* extract the common data */
1996 	header->flags         	= get_bigendian_uint32(&rawheader[16]);
1997 	header->compression[0]	= get_bigendian_uint32(&rawheader[20]);
1998 	header->compression[1]	= CHD_CODEC_NONE;
1999 	header->compression[2]	= CHD_CODEC_NONE;
2000 	header->compression[3]	= CHD_CODEC_NONE;
2001 
2002 	/* extract the V1/V2-specific data */
2003 	if (header->version < 3)
2004 	{
2005 		int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
2006 		header->obsolete_hunksize  = get_bigendian_uint32(&rawheader[24]);
2007 		header->totalhunks         = get_bigendian_uint32(&rawheader[28]);
2008 		header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
2009 		header->obsolete_heads     = get_bigendian_uint32(&rawheader[36]);
2010 		header->obsolete_sectors   = get_bigendian_uint32(&rawheader[40]);
2011 		memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2012 		memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2013 		header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
2014 		header->hunkbytes = seclen * header->obsolete_hunksize;
2015 		header->unitbytes          = header_guess_unitbytes(chd);
2016 		header->unitcount          = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2017 		header->metaoffset = 0;
2018 	}
2019 
2020 	/* extract the V3-specific data */
2021 	else if (header->version == 3)
2022 	{
2023 		header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2024 		header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2025 		header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2026 		memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2027 		memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2028 		header->hunkbytes    = get_bigendian_uint32(&rawheader[76]);
2029 		header->unitbytes    = header_guess_unitbytes(chd);
2030 		header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2031 		memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
2032 		memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
2033 	}
2034 
2035 	/* extract the V4-specific data */
2036 	else if (header->version == 4)
2037 	{
2038 		header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2039 		header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2040 		header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2041 		header->hunkbytes    = get_bigendian_uint32(&rawheader[44]);
2042 		header->unitbytes    = header_guess_unitbytes(chd);
2043 		header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2044 		memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
2045 		memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
2046 		memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
2047 	}
2048 
2049 	/* extract the V5-specific data */
2050 	else if (header->version == 5)
2051 	{
2052 		/* TODO */
2053 		header->compression[0]  = get_bigendian_uint32(&rawheader[16]);
2054 		header->compression[1]  = get_bigendian_uint32(&rawheader[20]);
2055 		header->compression[2]  = get_bigendian_uint32(&rawheader[24]);
2056 		header->compression[3]  = get_bigendian_uint32(&rawheader[28]);
2057 		header->logicalbytes    = get_bigendian_uint64(&rawheader[32]);
2058 		header->mapoffset       = get_bigendian_uint64(&rawheader[40]);
2059 		header->metaoffset      = get_bigendian_uint64(&rawheader[48]);
2060 		header->hunkbytes       = get_bigendian_uint32(&rawheader[56]);
2061 		header->hunkcount       = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
2062 		header->unitbytes       = get_bigendian_uint32(&rawheader[60]);
2063 		header->unitcount       = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2064 		memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
2065 		memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
2066 		memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
2067 
2068 		/* determine properties of map entries */
2069 		header->mapentrybytes = chd_compressed(header) ? 12 : 4;
2070 
2071 		/* hack */
2072 		header->totalhunks 		= header->hunkcount;
2073 	}
2074 
2075 	/* Unknown version */
2076 	else
2077 	{
2078 		/* TODO */
2079 	}
2080 
2081 	/* guess it worked */
2082 	return CHDERR_NONE;
2083 }
2084 
2085 /***************************************************************************
2086     INTERNAL HUNK READ/WRITE
2087 ***************************************************************************/
2088 
2089 /*-------------------------------------------------
2090     hunk_read_compressed - read a compressed
2091     hunk
2092 -------------------------------------------------*/
2093 
hunk_read_compressed(chd_file * chd,UINT64 offset,size_t size)2094 static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
2095 {
2096 	ssize_t bytes;
2097 	if (chd->file_cache != NULL)
2098 	{
2099 		return chd->file_cache + offset;
2100 	}
2101 	else
2102 	{
2103 		core_fseek(chd->file, offset, SEEK_SET);
2104 		bytes = core_fread(chd->file, chd->compressed, size);
2105 		if (bytes != size)
2106 			return NULL;
2107 		return chd->compressed;
2108 	}
2109 }
2110 
2111 /*-------------------------------------------------
2112     hunk_read_uncompressed - read an uncompressed
2113     hunk
2114 -------------------------------------------------*/
2115 
hunk_read_uncompressed(chd_file * chd,UINT64 offset,size_t size,UINT8 * dest)2116 static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2117 {
2118 	ssize_t bytes;
2119 	if (chd->file_cache != NULL)
2120 	{
2121 		memcpy(dest, chd->file_cache + offset, size);
2122 	}
2123 	else
2124 	{
2125 		core_fseek(chd->file, offset, SEEK_SET);
2126 		bytes = core_fread(chd->file, dest, size);
2127 		if (bytes != size)
2128 			return CHDERR_READ_ERROR;
2129 	}
2130 	return CHDERR_NONE;
2131 }
2132 
2133 #ifdef NEED_CACHE_HUNK
2134 /*-------------------------------------------------
2135     hunk_read_into_cache - read a hunk into
2136     the CHD's hunk cache
2137 -------------------------------------------------*/
2138 
hunk_read_into_cache(chd_file * chd,UINT32 hunknum)2139 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2140 {
2141 	chd_error err;
2142 
2143 	/* track the max */
2144 	if (hunknum > chd->maxhunk)
2145 		chd->maxhunk = hunknum;
2146 
2147 	/* if we're already in the cache, we're done */
2148 	if (chd->cachehunk == hunknum)
2149 		return CHDERR_NONE;
2150 	chd->cachehunk = ~0;
2151 
2152 	/* otherwise, read the data */
2153 	err = hunk_read_into_memory(chd, hunknum, chd->cache);
2154 	if (err != CHDERR_NONE)
2155 		return err;
2156 
2157 	/* mark the hunk successfully cached in */
2158 	chd->cachehunk = hunknum;
2159 	return CHDERR_NONE;
2160 }
2161 #endif
2162 
2163 /*-------------------------------------------------
2164     hunk_read_into_memory - read a hunk into
2165     memory at the given location
2166 -------------------------------------------------*/
2167 
hunk_read_into_memory(chd_file * chd,UINT32 hunknum,UINT8 * dest)2168 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2169 {
2170 	chd_error err;
2171 
2172 	/* punt if no file */
2173 	if (chd->file == NULL)
2174 		return CHDERR_INVALID_FILE;
2175 
2176 	/* return an error if out of range */
2177 	if (hunknum >= chd->header.totalhunks)
2178 		return CHDERR_HUNK_OUT_OF_RANGE;
2179 
2180 	if (dest == NULL)
2181 		return CHDERR_INVALID_PARAMETER;
2182 
2183 	if (chd->header.version < 5)
2184 	{
2185 		map_entry *entry = &chd->map[hunknum];
2186 		UINT32 bytes;
2187 		UINT8* compressed_bytes;
2188 
2189 		/* switch off the entry type */
2190 		switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2191 		{
2192 			/* compressed data */
2193 			case V34_MAP_ENTRY_TYPE_COMPRESSED:
2194             {
2195                void *codec = NULL;
2196 
2197 				/* read it into the decompression buffer */
2198 				compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
2199 				if (compressed_bytes == NULL)
2200 					return CHDERR_READ_ERROR;
2201 
2202 				/* now decompress using the codec */
2203 				err = CHDERR_NONE;
2204 				codec = &chd->zlib_codec_data;
2205 				if (chd->codecintf[0]->decompress != NULL)
2206 					err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
2207 				if (err != CHDERR_NONE)
2208 					return err;
2209 				break;
2210 			}
2211 
2212 			/* uncompressed data */
2213 			case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2214 				err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2215 				if (err != CHDERR_NONE)
2216 					return err;
2217 				break;
2218 
2219 			/* mini-compressed data */
2220 			case V34_MAP_ENTRY_TYPE_MINI:
2221 				put_bigendian_uint64(&dest[0], entry->offset);
2222 				for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2223 					dest[bytes] = dest[bytes - 8];
2224 				break;
2225 
2226 			/* self-referenced data */
2227 			case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2228 #ifdef NEED_CACHE_HUNK
2229 				if (chd->cachehunk == entry->offset && dest == chd->cache)
2230 					break;
2231 #endif
2232 				return hunk_read_into_memory(chd, entry->offset, dest);
2233 
2234 			/* parent-referenced data */
2235 			case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2236 				err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2237 				if (err != CHDERR_NONE)
2238 					return err;
2239 				break;
2240 		}
2241 		return CHDERR_NONE;
2242 	}
2243 	else
2244 	{
2245 		void* codec = NULL;
2246 		/* get a pointer to the map entry */
2247 		uint64_t blockoffs;
2248 		uint32_t blocklen;
2249 #ifdef VERIFY_BLOCK_CRC
2250 		uint16_t blockcrc;
2251 #endif
2252 		uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2253 		UINT8* compressed_bytes;
2254 
2255 		/* uncompressed case */
2256 		if (!chd_compressed(&chd->header))
2257 		{
2258 			blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
2259 			if (blockoffs != 0) {
2260             int result;
2261 				core_fseek(chd->file, blockoffs, SEEK_SET);
2262 				result = core_fread(chd->file, dest, chd->header.hunkbytes);
2263 			/* TODO
2264 			else if (m_parent_missing)
2265 				throw CHDERR_REQUIRES_PARENT; */
2266 			} else if (chd->parent) {
2267 				err = hunk_read_into_memory(chd->parent, hunknum, dest);
2268 				if (err != CHDERR_NONE)
2269 					return err;
2270 			} else {
2271 				memset(dest, 0, chd->header.hunkbytes);
2272 			}
2273 
2274 			return CHDERR_NONE;
2275 		}
2276 
2277 		/* compressed case */
2278 		blocklen = get_bigendian_uint24(&rawmap[1]);
2279 		blockoffs = get_bigendian_uint48(&rawmap[4]);
2280 #ifdef VERIFY_BLOCK_CRC
2281 		blockcrc = get_bigendian_uint16(&rawmap[10]);
2282 #endif
2283 		codec = NULL;
2284 		switch (rawmap[0])
2285 		{
2286 			case COMPRESSION_TYPE_0:
2287 			case COMPRESSION_TYPE_1:
2288 			case COMPRESSION_TYPE_2:
2289 			case COMPRESSION_TYPE_3:
2290 				compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
2291 				if (compressed_bytes == NULL)
2292 					return CHDERR_READ_ERROR;
2293 				switch (chd->codecintf[rawmap[0]]->compression)
2294 				{
2295 					case CHD_CODEC_CD_LZMA:
2296 						codec = &chd->cdlz_codec_data;
2297 						break;
2298 
2299 					case CHD_CODEC_ZLIB:
2300 						codec = &chd->zlib_codec_data;
2301 						break;
2302 
2303 					case CHD_CODEC_CD_ZLIB:
2304 						codec = &chd->cdzl_codec_data;
2305 						break;
2306 
2307 					case CHD_CODEC_CD_FLAC:
2308 						codec = &chd->cdfl_codec_data;
2309 						break;
2310 				}
2311 				if (codec==NULL)
2312 					return CHDERR_CODEC_ERROR;
2313 				err = chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
2314 				if (err != CHDERR_NONE)
2315 					return err;
2316 #ifdef VERIFY_BLOCK_CRC
2317 				if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2318 					return CHDERR_DECOMPRESSION_ERROR;
2319 #endif
2320 				return CHDERR_NONE;
2321 
2322 			case COMPRESSION_NONE:
2323 				err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest);
2324 				if (err != CHDERR_NONE)
2325 					return err;
2326 #ifdef VERIFY_BLOCK_CRC
2327 				if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2328 					return CHDERR_DECOMPRESSION_ERROR;
2329 #endif
2330 				return CHDERR_NONE;
2331 
2332 			case COMPRESSION_SELF:
2333 				return hunk_read_into_memory(chd, blockoffs, dest);
2334 
2335 			case COMPRESSION_PARENT:
2336 #if 0
2337 				/* TODO */
2338 				if (m_parent_missing)
2339 					return CHDERR_REQUIRES_PARENT;
2340 				return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
2341 #endif
2342 				return CHDERR_DECOMPRESSION_ERROR;
2343 		}
2344 		return CHDERR_NONE;
2345 	}
2346 
2347 	/* We should not reach this code */
2348 	return CHDERR_DECOMPRESSION_ERROR;
2349 }
2350 
2351 /***************************************************************************
2352     INTERNAL MAP ACCESS
2353 ***************************************************************************/
2354 
2355 /*-------------------------------------------------
2356     map_read - read the initial sector map
2357 -------------------------------------------------*/
2358 
map_read(chd_file * chd)2359 static chd_error map_read(chd_file *chd)
2360 {
2361 	UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2362 	UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2363 	UINT64 fileoffset, maxoffset = 0;
2364 	UINT8 cookie[MAP_ENTRY_SIZE];
2365 	UINT32 count;
2366 	chd_error err;
2367 	int i;
2368 
2369 	/* first allocate memory */
2370 	chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2371 	if (!chd->map)
2372 		return CHDERR_OUT_OF_MEMORY;
2373 
2374 	/* read the map entries in in chunks and extract to the map list */
2375 	fileoffset = chd->header.length;
2376 	for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2377 	{
2378 		/* compute how many entries this time */
2379 		int entries = chd->header.totalhunks - i, j;
2380 		if (entries > MAP_STACK_ENTRIES)
2381 			entries = MAP_STACK_ENTRIES;
2382 
2383 		/* read that many */
2384 		core_fseek(chd->file, fileoffset, SEEK_SET);
2385 		count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2386 		if (count != entries * entrysize)
2387 		{
2388 			err = CHDERR_READ_ERROR;
2389 			goto cleanup;
2390 		}
2391 		fileoffset += entries * entrysize;
2392 
2393 		/* process that many */
2394 		if (entrysize == MAP_ENTRY_SIZE)
2395 		{
2396 			for (j = 0; j < entries; j++)
2397 				map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2398 		}
2399 		else
2400 		{
2401 			for (j = 0; j < entries; j++)
2402 				map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2403 		}
2404 
2405 		/* track the maximum offset */
2406 		for (j = 0; j < entries; j++)
2407 			if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2408 				(chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2409 				maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2410 	}
2411 
2412 	/* verify the cookie */
2413 	core_fseek(chd->file, fileoffset, SEEK_SET);
2414 	count = core_fread(chd->file, &cookie, entrysize);
2415 	if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2416 	{
2417 		err = CHDERR_INVALID_FILE;
2418 		goto cleanup;
2419 	}
2420 
2421 	/* verify the length */
2422 	if (maxoffset > core_fsize(chd->file))
2423 	{
2424 		err = CHDERR_INVALID_FILE;
2425 		goto cleanup;
2426 	}
2427 	return CHDERR_NONE;
2428 
2429 cleanup:
2430 	if (chd->map)
2431 		free(chd->map);
2432 	chd->map = NULL;
2433 	return err;
2434 }
2435 
2436 /***************************************************************************
2437     INTERNAL METADATA ACCESS
2438 ***************************************************************************/
2439 
2440 /*-------------------------------------------------
2441     metadata_find_entry - find a metadata entry
2442 -------------------------------------------------*/
2443 
metadata_find_entry(chd_file * chd,UINT32 metatag,UINT32 metaindex,metadata_entry * metaentry)2444 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2445 {
2446 	/* start at the beginning */
2447 	metaentry->offset = chd->header.metaoffset;
2448 	metaentry->prev = 0;
2449 
2450 	/* loop until we run out of options */
2451 	while (metaentry->offset != 0)
2452 	{
2453 		UINT8	raw_meta_header[METADATA_HEADER_SIZE];
2454 		UINT32	count;
2455 
2456 		/* read the raw header */
2457 		core_fseek(chd->file, metaentry->offset, SEEK_SET);
2458 		count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2459 		if (count != sizeof(raw_meta_header))
2460 			break;
2461 
2462 		/* extract the data */
2463 		metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2464 		metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2465 		metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2466 
2467 		/* flags are encoded in the high byte of length */
2468 		metaentry->flags = metaentry->length >> 24;
2469 		metaentry->length &= 0x00ffffff;
2470 
2471 		/* if we got a match, proceed */
2472 		if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2473 			if (metaindex-- == 0)
2474 				return CHDERR_NONE;
2475 
2476 		/* no match, fetch the next link */
2477 		metaentry->prev = metaentry->offset;
2478 		metaentry->offset = metaentry->next;
2479 	}
2480 
2481 	/* if we get here, we didn't find it */
2482 	return CHDERR_METADATA_NOT_FOUND;
2483 }
2484 
2485 /***************************************************************************
2486     ZLIB COMPRESSION CODEC
2487 ***************************************************************************/
2488 
2489 /*-------------------------------------------------
2490     zlib_codec_init - initialize the ZLIB codec
2491 -------------------------------------------------*/
2492 
zlib_codec_init(void * codec,uint32_t hunkbytes)2493 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2494 {
2495 	int zerr;
2496 	chd_error err;
2497 	zlib_codec_data *data = (zlib_codec_data*)codec;
2498 
2499 	/* clear the buffers */
2500 	memset(data, 0, sizeof(zlib_codec_data));
2501 
2502 	/* init the inflater first */
2503 	data->inflater.next_in = (Bytef *)data;	/* bogus, but that's ok */
2504 	data->inflater.avail_in = 0;
2505 	data->inflater.zalloc = zlib_fast_alloc;
2506 	data->inflater.zfree = zlib_fast_free;
2507 	data->inflater.opaque = &data->allocator;
2508 	zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2509 
2510 	/* convert errors */
2511 	if (zerr == Z_MEM_ERROR)
2512 		err = CHDERR_OUT_OF_MEMORY;
2513 	else if (zerr != Z_OK)
2514 		err = CHDERR_CODEC_ERROR;
2515 	else
2516 		err = CHDERR_NONE;
2517 
2518 	/* handle an error */
2519 	if (err != CHDERR_NONE)
2520 		free(data);
2521 
2522 	return err;
2523 }
2524 
2525 /*-------------------------------------------------
2526     zlib_codec_free - free data for the ZLIB
2527     codec
2528 -------------------------------------------------*/
2529 
zlib_codec_free(void * codec)2530 static void zlib_codec_free(void *codec)
2531 {
2532 	zlib_codec_data *data = (zlib_codec_data *)codec;
2533 
2534 	/* deinit the streams */
2535 	if (data != NULL)
2536 	{
2537 		int i;
2538 
2539 		inflateEnd(&data->inflater);
2540 
2541 		/* free our fast memory */
2542 		zlib_allocator_free(&data->allocator);
2543 	}
2544 }
2545 
2546 /*-------------------------------------------------
2547     zlib_codec_decompress - decompress data using
2548     the ZLIB codec
2549 -------------------------------------------------*/
2550 
zlib_codec_decompress(void * codec,const uint8_t * src,uint32_t complen,uint8_t * dest,uint32_t destlen)2551 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2552 {
2553 	zlib_codec_data *data = (zlib_codec_data *)codec;
2554 	int zerr;
2555 
2556 	/* reset the decompressor */
2557 	data->inflater.next_in = (Bytef *)src;
2558 	data->inflater.avail_in = complen;
2559 	data->inflater.total_in = 0;
2560 	data->inflater.next_out = (Bytef *)dest;
2561 	data->inflater.avail_out = destlen;
2562 	data->inflater.total_out = 0;
2563 	zerr = inflateReset(&data->inflater);
2564 	if (zerr != Z_OK)
2565 		return CHDERR_DECOMPRESSION_ERROR;
2566 
2567 	/* do it */
2568 	zerr = inflate(&data->inflater, Z_FINISH);
2569 	if (data->inflater.total_out != destlen)
2570 		return CHDERR_DECOMPRESSION_ERROR;
2571 
2572 	return CHDERR_NONE;
2573 }
2574 
2575 /*-------------------------------------------------
2576     zlib_fast_alloc - fast malloc for ZLIB, which
2577     allocates and frees memory frequently
2578 -------------------------------------------------*/
2579 
2580 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
2581 #define ZLIB_MIN_ALIGNMENT_BITS 512
2582 #define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
2583 
zlib_fast_alloc(voidpf opaque,uInt items,uInt size)2584 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2585 {
2586 	zlib_allocator *alloc = (zlib_allocator *)opaque;
2587 	uintptr_t paddr = 0;
2588 	UINT32 *ptr;
2589 	int i;
2590 
2591 	/* compute the size, rounding to the nearest 1k */
2592 	size = (size * items + 0x3ff) & ~0x3ff;
2593 
2594 	/* reuse a hunk if we can */
2595 	for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2596 	{
2597 		ptr = alloc->allocptr[i];
2598 		if (ptr && size == *ptr)
2599 		{
2600 			/* set the low bit of the size so we don't match next time */
2601 			*ptr |= 1;
2602 
2603 			/* return aligned block address */
2604 			return (voidpf)(alloc->allocptr2[i]);
2605 		}
2606 	}
2607 
2608 	/* alloc a new one */
2609     ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
2610 	if (!ptr)
2611 		return NULL;
2612 
2613 	/* put it into the list */
2614 	for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2615 		if (!alloc->allocptr[i])
2616 		{
2617 			alloc->allocptr[i] = ptr;
2618 			paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
2619 			alloc->allocptr2[i] = (uint32_t*)paddr;
2620 			break;
2621 		}
2622 
2623 	/* set the low bit of the size so we don't match next time */
2624 	*ptr = size | 1;
2625 
2626 	/* return aligned block address */
2627 	return (voidpf)paddr;
2628 }
2629 
2630 /*-------------------------------------------------
2631     zlib_fast_free - fast free for ZLIB, which
2632     allocates and frees memory frequently
2633 -------------------------------------------------*/
2634 
zlib_fast_free(voidpf opaque,voidpf address)2635 static void zlib_fast_free(voidpf opaque, voidpf address)
2636 {
2637 	zlib_allocator *alloc = (zlib_allocator *)opaque;
2638 	UINT32 *ptr = (UINT32 *)address;
2639 	int i;
2640 
2641 	/* find the hunk */
2642 	for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2643 		if (ptr == alloc->allocptr2[i])
2644 		{
2645 			/* clear the low bit of the size to allow matches */
2646 			*(alloc->allocptr[i]) &= ~1;
2647 			return;
2648 		}
2649 }
2650 
2651 /*-------------------------------------------------
2652     zlib_allocator_free
2653 -------------------------------------------------*/
zlib_allocator_free(voidpf opaque)2654 static void zlib_allocator_free(voidpf opaque)
2655 {
2656 	zlib_allocator *alloc = (zlib_allocator *)opaque;
2657 	int i;
2658 
2659 	for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2660 		if (alloc->allocptr[i])
2661 			free(alloc->allocptr[i]);
2662 }
2663