Update libchdr (replace libflac with dr_flac)
[pcsx_rearmed.git] / deps / libchdr / src / libchdr_chd.c
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
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
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
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
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
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
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
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 */
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
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
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
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
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
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
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
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         if (flac_decoder_init(&cdfl->decoder))
798                 return CHDERR_OUT_OF_MEMORY;
799
800         return CHDERR_NONE;
801 }
802
803 static void cdfl_codec_free(void *codec)
804 {
805         cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
806         flac_decoder_free(&cdfl->decoder);
807 #ifdef WANT_SUBCODE
808         zlib_codec_free(&cdfl->subcode_decompressor);
809 #endif
810         if (cdfl->buffer)
811                 free(cdfl->buffer);
812 }
813
814 static chd_error cdfl_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
815 {
816         uint32_t framenum;
817         uint8_t *buffer;
818 #ifdef WANT_SUBCODE
819         uint32_t offset;
820         chd_error ret;
821 #endif
822         cdfl_codec_data *cdfl = (cdfl_codec_data*)codec;
823
824         /* reset and decode */
825         uint32_t frames = destlen / CD_FRAME_SIZE;
826
827         if (!flac_decoder_reset(&cdfl->decoder, 44100, 2, cdfl_codec_blocksize(frames * CD_MAX_SECTOR_DATA), src, complen))
828                 return CHDERR_DECOMPRESSION_ERROR;
829         buffer = &cdfl->buffer[0];
830         if (!flac_decoder_decode_interleaved(&cdfl->decoder, (int16_t *)(buffer), frames * CD_MAX_SECTOR_DATA/4, cdfl->swap_endian))
831                 return CHDERR_DECOMPRESSION_ERROR;
832
833 #ifdef WANT_SUBCODE
834         /* inflate the subcode data */
835         offset = flac_decoder_finish(&cdfl->decoder);
836         ret = zlib_codec_decompress(&cdfl->subcode_decompressor, src + offset, complen - offset, &cdfl->buffer[frames * CD_MAX_SECTOR_DATA], frames * CD_MAX_SUBCODE_DATA);
837         if (ret != CHDERR_NONE)
838                 return ret;
839 #else
840         flac_decoder_finish(&cdfl->decoder);
841 #endif
842
843         /* reassemble the data */
844         for (framenum = 0; framenum < frames; framenum++)
845         {
846                 memcpy(&dest[framenum * CD_FRAME_SIZE], &cdfl->buffer[framenum * CD_MAX_SECTOR_DATA], CD_MAX_SECTOR_DATA);
847 #ifdef WANT_SUBCODE
848                 memcpy(&dest[framenum * CD_FRAME_SIZE + CD_MAX_SECTOR_DATA], &cdfl->buffer[frames * CD_MAX_SECTOR_DATA + framenum * CD_MAX_SUBCODE_DATA], CD_MAX_SUBCODE_DATA);
849 #endif
850         }
851
852         return CHDERR_NONE;
853 }
854 /***************************************************************************
855     CODEC INTERFACES
856 ***************************************************************************/
857
858 static const codec_interface codec_interfaces[] =
859 {
860         /* "none" or no compression */
861         {
862                 CHDCOMPRESSION_NONE,
863                 "none",
864                 FALSE,
865                 NULL,
866                 NULL,
867                 NULL,
868                 NULL
869         },
870
871         /* standard zlib compression */
872         {
873                 CHDCOMPRESSION_ZLIB,
874                 "zlib",
875                 FALSE,
876                 zlib_codec_init,
877                 zlib_codec_free,
878                 zlib_codec_decompress,
879                 NULL
880         },
881
882         /* zlib+ compression */
883         {
884                 CHDCOMPRESSION_ZLIB_PLUS,
885                 "zlib+",
886                 FALSE,
887                 zlib_codec_init,
888                 zlib_codec_free,
889                 zlib_codec_decompress,
890                 NULL
891         },
892
893         /* V5 zlib compression */
894         {
895                 CHD_CODEC_ZLIB,
896                 "zlib (Deflate)",
897                 FALSE,
898                 zlib_codec_init,
899                 zlib_codec_free,
900                 zlib_codec_decompress,
901                 NULL
902         },
903
904         /* V5 CD zlib compression */
905         {
906                 CHD_CODEC_CD_ZLIB,
907                 "cdzl (CD Deflate)",
908                 FALSE,
909                 cdzl_codec_init,
910                 cdzl_codec_free,
911                 cdzl_codec_decompress,
912                 NULL
913         },
914
915         /* V5 CD lzma compression */
916         {
917                 CHD_CODEC_CD_LZMA,
918                 "cdlz (CD LZMA)",
919                 FALSE,
920                 cdlz_codec_init,
921                 cdlz_codec_free,
922                 cdlz_codec_decompress,
923                 NULL
924         },
925
926         /* V5 CD flac compression */
927         {
928                 CHD_CODEC_CD_FLAC,
929                 "cdfl (CD FLAC)",
930                 FALSE,
931                 cdfl_codec_init,
932                 cdfl_codec_free,
933                 cdfl_codec_decompress,
934                 NULL
935         },
936 };
937
938 /***************************************************************************
939     INLINE FUNCTIONS
940 ***************************************************************************/
941
942 /*-------------------------------------------------
943     get_bigendian_uint64 - fetch a UINT64 from
944     the data stream in bigendian order
945 -------------------------------------------------*/
946
947 static inline UINT64 get_bigendian_uint64(const UINT8 *base)
948 {
949         return ((UINT64)base[0] << 56) | ((UINT64)base[1] << 48) | ((UINT64)base[2] << 40) | ((UINT64)base[3] << 32) |
950                         ((UINT64)base[4] << 24) | ((UINT64)base[5] << 16) | ((UINT64)base[6] << 8) | (UINT64)base[7];
951 }
952
953 /*-------------------------------------------------
954     put_bigendian_uint64 - write a UINT64 to
955     the data stream in bigendian order
956 -------------------------------------------------*/
957
958 static inline void put_bigendian_uint64(UINT8 *base, UINT64 value)
959 {
960         base[0] = value >> 56;
961         base[1] = value >> 48;
962         base[2] = value >> 40;
963         base[3] = value >> 32;
964         base[4] = value >> 24;
965         base[5] = value >> 16;
966         base[6] = value >> 8;
967         base[7] = value;
968 }
969
970 /*-------------------------------------------------
971     get_bigendian_uint48 - fetch a UINT48 from
972     the data stream in bigendian order
973 -------------------------------------------------*/
974
975 static inline UINT64 get_bigendian_uint48(const UINT8 *base)
976 {
977         return  ((UINT64)base[0] << 40) | ((UINT64)base[1] << 32) |
978                         ((UINT64)base[2] << 24) | ((UINT64)base[3] << 16) | ((UINT64)base[4] << 8) | (UINT64)base[5];
979 }
980
981 /*-------------------------------------------------
982     put_bigendian_uint48 - write a UINT48 to
983     the data stream in bigendian order
984 -------------------------------------------------*/
985
986 static inline void put_bigendian_uint48(UINT8 *base, UINT64 value)
987 {
988         value &= 0xffffffffffff;
989         base[0] = value >> 40;
990         base[1] = value >> 32;
991         base[2] = value >> 24;
992         base[3] = value >> 16;
993         base[4] = value >> 8;
994         base[5] = value;
995 }
996 /*-------------------------------------------------
997     get_bigendian_uint32 - fetch a UINT32 from
998     the data stream in bigendian order
999 -------------------------------------------------*/
1000
1001 static inline UINT32 get_bigendian_uint32(const UINT8 *base)
1002 {
1003         return (base[0] << 24) | (base[1] << 16) | (base[2] << 8) | base[3];
1004 }
1005
1006 /*-------------------------------------------------
1007     put_bigendian_uint32 - write a UINT32 to
1008     the data stream in bigendian order
1009 -------------------------------------------------*/
1010
1011 static inline void put_bigendian_uint32(UINT8 *base, UINT32 value)
1012 {
1013         base[0] = value >> 24;
1014         base[1] = value >> 16;
1015         base[2] = value >> 8;
1016         base[3] = value;
1017 }
1018
1019 /*-------------------------------------------------
1020     put_bigendian_uint24 - write a UINT24 to
1021     the data stream in bigendian order
1022 -------------------------------------------------*/
1023
1024 static inline void put_bigendian_uint24(UINT8 *base, UINT32 value)
1025 {
1026         value &= 0xffffff;
1027         base[0] = value >> 16;
1028         base[1] = value >> 8;
1029         base[2] = value;
1030 }
1031
1032 /*-------------------------------------------------
1033     get_bigendian_uint24 - fetch a UINT24 from
1034     the data stream in bigendian order
1035 -------------------------------------------------*/
1036
1037 static inline UINT32 get_bigendian_uint24(const UINT8 *base)
1038 {
1039         return (base[0] << 16) | (base[1] << 8) | base[2];
1040 }
1041
1042 /*-------------------------------------------------
1043     get_bigendian_uint16 - fetch a UINT16 from
1044     the data stream in bigendian order
1045 -------------------------------------------------*/
1046
1047 static inline UINT16 get_bigendian_uint16(const UINT8 *base)
1048 {
1049         return (base[0] << 8) | base[1];
1050 }
1051
1052 /*-------------------------------------------------
1053     put_bigendian_uint16 - write a UINT16 to
1054     the data stream in bigendian order
1055 -------------------------------------------------*/
1056
1057 static inline void put_bigendian_uint16(UINT8 *base, UINT16 value)
1058 {
1059         base[0] = value >> 8;
1060         base[1] = value;
1061 }
1062
1063 /*-------------------------------------------------
1064     map_extract - extract a single map
1065     entry from the datastream
1066 -------------------------------------------------*/
1067
1068 static inline void map_extract(const UINT8 *base, map_entry *entry)
1069 {
1070         entry->offset = get_bigendian_uint64(&base[0]);
1071         entry->crc = get_bigendian_uint32(&base[8]);
1072         entry->length = get_bigendian_uint16(&base[12]) | (base[14] << 16);
1073         entry->flags = base[15];
1074 }
1075
1076 /*-------------------------------------------------
1077     map_assemble - write a single map
1078     entry to the datastream
1079 -------------------------------------------------*/
1080
1081 static inline void map_assemble(UINT8 *base, map_entry *entry)
1082 {
1083         put_bigendian_uint64(&base[0], entry->offset);
1084         put_bigendian_uint32(&base[8], entry->crc);
1085         put_bigendian_uint16(&base[12], entry->length);
1086         base[14] = entry->length >> 16;
1087         base[15] = entry->flags;
1088 }
1089
1090 /*-------------------------------------------------
1091     map_size_v5 - calculate CHDv5 map size
1092 -------------------------------------------------*/
1093 static inline int map_size_v5(chd_header* header)
1094 {
1095         return header->hunkcount * header->mapentrybytes;
1096 }
1097
1098 /*-------------------------------------------------
1099     crc16 - calculate CRC16 (from hashing.cpp)
1100 -------------------------------------------------*/
1101 uint16_t crc16(const void *data, uint32_t length)
1102 {
1103         uint16_t crc = 0xffff;
1104
1105         static const uint16_t s_table[256] =
1106         {
1107                 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
1108                 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
1109                 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
1110                 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
1111                 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
1112                 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
1113                 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
1114                 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
1115                 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
1116                 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
1117                 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
1118                 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
1119                 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
1120                 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
1121                 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
1122                 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
1123                 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
1124                 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
1125                 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
1126                 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
1127                 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
1128                 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
1129                 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
1130                 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
1131                 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
1132                 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
1133                 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
1134                 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
1135                 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
1136                 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
1137                 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
1138                 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
1139         };
1140
1141         const uint8_t *src = (uint8_t*)data;
1142
1143         /* fetch the current value into a local and rip through the source data */
1144         while (length-- != 0)
1145                 crc = (crc << 8) ^ s_table[(crc >> 8) ^ *src++];
1146         return crc;
1147 }
1148
1149 /*-------------------------------------------------
1150         compressed - test if CHD file is compressed
1151 +-------------------------------------------------*/
1152 static inline int chd_compressed(chd_header* header) {
1153         return header->compression[0] != CHD_CODEC_NONE;
1154 }
1155
1156 /*-------------------------------------------------
1157         decompress_v5_map - decompress the v5 map
1158 -------------------------------------------------*/
1159
1160 static chd_error decompress_v5_map(chd_file* chd, chd_header* header)
1161 {
1162         int result = 0;
1163         int hunknum;
1164         int repcount = 0;
1165         uint8_t lastcomp = 0;
1166         uint32_t last_self = 0;
1167         uint64_t last_parent = 0;
1168         struct bitstream* bitbuf;
1169         uint32_t mapbytes;
1170         uint64_t firstoffs;
1171         uint16_t mapcrc;
1172         uint8_t lengthbits;
1173         uint8_t selfbits;
1174         uint8_t parentbits;
1175         uint8_t *compressed_ptr;
1176         uint8_t rawbuf[16];
1177         struct huffman_decoder* decoder;
1178         enum huffman_error err;
1179         uint64_t curoffset;     
1180         int rawmapsize = map_size_v5(header);
1181
1182         if (!chd_compressed(header))
1183         {
1184                 header->rawmap = (uint8_t*)malloc(rawmapsize);
1185                 core_fseek(chd->file, header->mapoffset, SEEK_SET);
1186                 result = core_fread(chd->file, header->rawmap, rawmapsize);
1187                 return CHDERR_NONE;
1188         }
1189
1190         /* read the reader */
1191         core_fseek(chd->file, header->mapoffset, SEEK_SET);
1192         result = core_fread(chd->file, rawbuf, sizeof(rawbuf));
1193         mapbytes = get_bigendian_uint32(&rawbuf[0]);
1194         firstoffs = get_bigendian_uint48(&rawbuf[4]);
1195         mapcrc = get_bigendian_uint16(&rawbuf[10]);
1196         lengthbits = rawbuf[12];
1197         selfbits = rawbuf[13];
1198         parentbits = rawbuf[14];
1199
1200         /* now read the map */
1201         compressed_ptr = (uint8_t*)malloc(sizeof(uint8_t) * mapbytes);
1202         core_fseek(chd->file, header->mapoffset + 16, SEEK_SET);
1203         result = core_fread(chd->file, compressed_ptr, mapbytes);
1204         bitbuf = create_bitstream(compressed_ptr, sizeof(uint8_t) * mapbytes);
1205         header->rawmap = (uint8_t*)malloc(rawmapsize);
1206
1207         /* first decode the compression types */
1208         decoder = create_huffman_decoder(16, 8);
1209         if (decoder == NULL)
1210         {
1211                 free(compressed_ptr);
1212                 free(bitbuf);
1213                 return CHDERR_OUT_OF_MEMORY;
1214         }
1215
1216         err = huffman_import_tree_rle(decoder, bitbuf);
1217         if (err != HUFFERR_NONE)
1218         {
1219                 free(compressed_ptr);
1220                 free(bitbuf);
1221                 delete_huffman_decoder(decoder);
1222                 return CHDERR_DECOMPRESSION_ERROR;
1223         }
1224
1225         for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1226         {
1227                 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1228                 if (repcount > 0)
1229                         rawmap[0] = lastcomp, repcount--;
1230                 else
1231                 {
1232                         uint8_t val = huffman_decode_one(decoder, bitbuf);
1233                         if (val == COMPRESSION_RLE_SMALL)
1234                                 rawmap[0] = lastcomp, repcount = 2 + huffman_decode_one(decoder, bitbuf);
1235                         else if (val == COMPRESSION_RLE_LARGE)
1236                                 rawmap[0] = lastcomp, repcount = 2 + 16 + (huffman_decode_one(decoder, bitbuf) << 4), repcount += huffman_decode_one(decoder, bitbuf);
1237                         else
1238                                 rawmap[0] = lastcomp = val;
1239                 }
1240         }
1241
1242         /* then iterate through the hunks and extract the needed data */
1243         curoffset = firstoffs;
1244         for (hunknum = 0; hunknum < header->hunkcount; hunknum++)
1245         {
1246                 uint8_t *rawmap = header->rawmap + (hunknum * 12);
1247                 uint64_t offset = curoffset;
1248                 uint32_t length = 0;
1249                 uint16_t crc = 0;
1250                 switch (rawmap[0])
1251                 {
1252                         /* base types */
1253                         case COMPRESSION_TYPE_0:
1254                         case COMPRESSION_TYPE_1:
1255                         case COMPRESSION_TYPE_2:
1256                         case COMPRESSION_TYPE_3:
1257                                 curoffset += length = bitstream_read(bitbuf, lengthbits);
1258                                 crc = bitstream_read(bitbuf, 16);
1259                                 break;
1260
1261                         case COMPRESSION_NONE:
1262                                 curoffset += length = header->hunkbytes;
1263                                 crc = bitstream_read(bitbuf, 16);
1264                                 break;
1265
1266                         case COMPRESSION_SELF:
1267                                 last_self = offset = bitstream_read(bitbuf, selfbits);
1268                                 break;
1269
1270                         case COMPRESSION_PARENT:
1271                                 offset = bitstream_read(bitbuf, parentbits);
1272                                 last_parent = offset;
1273                                 break;
1274
1275                         /* pseudo-types; convert into base types */
1276                         case COMPRESSION_SELF_1:
1277                                 last_self++;
1278                         case COMPRESSION_SELF_0:
1279                                 rawmap[0] = COMPRESSION_SELF;
1280                                 offset = last_self;
1281                                 break;
1282
1283                         case COMPRESSION_PARENT_SELF:
1284                                 rawmap[0] = COMPRESSION_PARENT;
1285                                 last_parent = offset = ( ((uint64_t)hunknum) * ((uint64_t)header->hunkbytes) ) / header->unitbytes;
1286                                 break;
1287
1288                         case COMPRESSION_PARENT_1:
1289                                 last_parent += header->hunkbytes / header->unitbytes;
1290                         case COMPRESSION_PARENT_0:
1291                                 rawmap[0] = COMPRESSION_PARENT;
1292                                 offset = last_parent;
1293                                 break;
1294                 }
1295                 /* UINT24 length */
1296                 put_bigendian_uint24(&rawmap[1], length);
1297
1298                 /* UINT48 offset */
1299                 put_bigendian_uint48(&rawmap[4], offset);
1300
1301                 /* crc16 */
1302                 put_bigendian_uint16(&rawmap[10], crc);
1303         }
1304
1305         /* free memory */
1306         free(compressed_ptr);
1307         free(bitbuf);
1308         delete_huffman_decoder(decoder);
1309
1310         /* verify the final CRC */
1311         if (crc16(&header->rawmap[0], header->hunkcount * 12) != mapcrc)
1312                 return CHDERR_DECOMPRESSION_ERROR;
1313
1314         return CHDERR_NONE;
1315 }
1316
1317 /*-------------------------------------------------
1318     map_extract_old - extract a single map
1319     entry in old format from the datastream
1320 -------------------------------------------------*/
1321
1322 static inline void map_extract_old(const UINT8 *base, map_entry *entry, UINT32 hunkbytes)
1323 {
1324         entry->offset = get_bigendian_uint64(&base[0]);
1325         entry->crc = 0;
1326         entry->length = entry->offset >> 44;
1327         entry->flags = MAP_ENTRY_FLAG_NO_CRC | ((entry->length == hunkbytes) ? V34_MAP_ENTRY_TYPE_UNCOMPRESSED : V34_MAP_ENTRY_TYPE_COMPRESSED);
1328 #ifdef __MWERKS__
1329         entry->offset = entry->offset & 0x00000FFFFFFFFFFFLL;
1330 #else
1331         entry->offset = (entry->offset << 20) >> 20;
1332 #endif
1333 }
1334
1335 /***************************************************************************
1336     CHD FILE MANAGEMENT
1337 ***************************************************************************/
1338
1339 /*-------------------------------------------------
1340     chd_open_file - open a CHD file for access
1341 -------------------------------------------------*/
1342
1343 CHD_EXPORT chd_error chd_open_file(core_file *file, int mode, chd_file *parent, chd_file **chd)
1344 {
1345         chd_file *newchd = NULL;
1346         chd_error err;
1347         int intfnum;
1348
1349         /* verify parameters */
1350         if (file == NULL)
1351                 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1352
1353         /* punt if invalid parent */
1354         if (parent != NULL && parent->cookie != COOKIE_VALUE)
1355                 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1356
1357         /* allocate memory for the final result */
1358         newchd = (chd_file *)malloc(sizeof(**chd));
1359         if (newchd == NULL)
1360                 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1361         memset(newchd, 0, sizeof(*newchd));
1362         newchd->cookie = COOKIE_VALUE;
1363         newchd->parent = parent;
1364         newchd->file = file;
1365
1366         /* now attempt to read the header */
1367         err = header_read(newchd, &newchd->header);
1368         if (err != CHDERR_NONE)
1369                 EARLY_EXIT(err);
1370
1371         /* validate the header */
1372         err = header_validate(&newchd->header);
1373         if (err != CHDERR_NONE)
1374                 EARLY_EXIT(err);
1375
1376         /* make sure we don't open a read-only file writeable */
1377         if (mode == CHD_OPEN_READWRITE && !(newchd->header.flags & CHDFLAGS_IS_WRITEABLE))
1378                 EARLY_EXIT(err = CHDERR_FILE_NOT_WRITEABLE);
1379
1380         /* also, never open an older version writeable */
1381         if (mode == CHD_OPEN_READWRITE && newchd->header.version < CHD_HEADER_VERSION)
1382                 EARLY_EXIT(err = CHDERR_UNSUPPORTED_VERSION);
1383
1384         /* if we need a parent, make sure we have one */
1385         if (parent == NULL && (newchd->header.flags & CHDFLAGS_HAS_PARENT))
1386                 EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1387
1388         /* make sure we have a valid parent */
1389         if (parent != NULL)
1390         {
1391                 /* check MD5 if it isn't empty */
1392                 if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1393                         memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1394                         memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1395                         EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1396
1397                 /* check SHA1 if it isn't empty */
1398                 if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1399                         memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1400                         memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1401                         EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1402         }
1403
1404         /* now read the hunk map */
1405         if (newchd->header.version < 5)
1406         {
1407                 err = map_read(newchd);
1408                 if (err != CHDERR_NONE)
1409                         EARLY_EXIT(err);
1410         }
1411         else
1412         {
1413                 err = decompress_v5_map(newchd, &(newchd->header));
1414         }
1415         if (err != CHDERR_NONE)
1416                 EARLY_EXIT(err);
1417
1418 #ifdef NEED_CACHE_HUNK
1419         /* allocate and init the hunk cache */
1420         newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1421         newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1422         if (newchd->cache == NULL || newchd->compare == NULL)
1423                 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1424         newchd->cachehunk = ~0;
1425         newchd->comparehunk = ~0;
1426 #endif
1427
1428         /* allocate the temporary compressed buffer */
1429         newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1430         if (newchd->compressed == NULL)
1431                 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1432
1433         /* find the codec interface */
1434         if (newchd->header.version < 5)
1435         {
1436                 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1437                 {
1438                         if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1439                         {
1440                                 newchd->codecintf[0] = &codec_interfaces[intfnum];
1441                                 break;
1442                         }
1443                 }
1444
1445                 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1446                         EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1447
1448                 /* initialize the codec */
1449                 if (newchd->codecintf[0]->init != NULL)
1450                 {
1451                         err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1452                         if (err != CHDERR_NONE)
1453                                 EARLY_EXIT(err);
1454                 }
1455         }
1456         else
1457         {
1458                 int decompnum;
1459                 /* verify the compression types and initialize the codecs */
1460                 for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1461                 {
1462                         int i;
1463                         for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1464                         {
1465                                 if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1466                                 {
1467                                         newchd->codecintf[decompnum] = &codec_interfaces[i];
1468                                         break;
1469                                 }
1470                         }
1471
1472                         if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1473                                 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1474
1475                         /* initialize the codec */
1476                         if (newchd->codecintf[decompnum]->init != NULL)
1477                         {
1478                                 void* codec = NULL;
1479                                 switch (newchd->header.compression[decompnum])
1480                                 {
1481                                         case CHD_CODEC_ZLIB:
1482                                                 codec = &newchd->zlib_codec_data;
1483                                                 break;
1484
1485                                         case CHD_CODEC_CD_ZLIB:
1486                                                 codec = &newchd->cdzl_codec_data;
1487                                                 break;
1488
1489                                         case CHD_CODEC_CD_LZMA:
1490                                                 codec = &newchd->cdlz_codec_data;
1491                                                 break;
1492
1493                                         case CHD_CODEC_CD_FLAC:
1494                                                 codec = &newchd->cdfl_codec_data;
1495                                                 break;
1496                                 }
1497
1498                                 if (codec == NULL)
1499                                         EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1500
1501                                 err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1502                                 if (err != CHDERR_NONE)
1503                                         EARLY_EXIT(err);
1504                         }
1505                 }
1506         }
1507
1508         /* all done */
1509         *chd = newchd;
1510         return CHDERR_NONE;
1511
1512 cleanup:
1513         if (newchd != NULL)
1514                 chd_close(newchd);
1515         return err;
1516 }
1517
1518 /*-------------------------------------------------
1519     chd_precache - precache underlying file in
1520     memory
1521 -------------------------------------------------*/
1522
1523 CHD_EXPORT chd_error chd_precache(chd_file *chd)
1524 {
1525 #ifdef _MSC_VER
1526         size_t size, count;
1527 #else
1528         ssize_t size, count;
1529 #endif
1530
1531         if (chd->file_cache == NULL)
1532         {
1533                 core_fseek(chd->file, 0, SEEK_END);
1534                 size = core_ftell(chd->file);
1535                 if (size <= 0)
1536                         return CHDERR_INVALID_DATA;
1537                 chd->file_cache = malloc(size);
1538                 if (chd->file_cache == NULL)
1539                         return CHDERR_OUT_OF_MEMORY;
1540                 core_fseek(chd->file, 0, SEEK_SET);
1541                 count = core_fread(chd->file, chd->file_cache, size);
1542                 if (count != size)
1543                 {
1544                         free(chd->file_cache);
1545                         chd->file_cache = NULL;
1546                         return CHDERR_READ_ERROR;
1547                 }
1548         }
1549
1550         return CHDERR_NONE;
1551 }
1552
1553 /*-------------------------------------------------
1554     chd_open - open a CHD file by
1555     filename
1556 -------------------------------------------------*/
1557
1558 CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1559 {
1560         chd_error err;
1561         core_file *file = NULL;
1562
1563         /* choose the proper mode */
1564         switch(mode)
1565         {
1566                 case CHD_OPEN_READ:
1567                         break;
1568
1569                 default:
1570                         err = CHDERR_INVALID_PARAMETER;
1571                         goto cleanup;
1572         }
1573
1574         /* open the file */
1575         file = core_fopen(filename);
1576         if (file == 0)
1577         {
1578                 err = CHDERR_FILE_NOT_FOUND;
1579                 goto cleanup;
1580         }
1581
1582         /* now open the CHD */
1583         err = chd_open_file(file, mode, parent, chd);
1584         if (err != CHDERR_NONE)
1585                 goto cleanup;
1586
1587         /* we now own this file */
1588         (*chd)->owns_file = TRUE;
1589
1590 cleanup:
1591         if ((err != CHDERR_NONE) && (file != NULL))
1592                 core_fclose(file);
1593         return err;
1594 }
1595
1596 /*-------------------------------------------------
1597     chd_close - close a CHD file for access
1598 -------------------------------------------------*/
1599
1600 CHD_EXPORT void chd_close(chd_file *chd)
1601 {
1602         /* punt if NULL or invalid */
1603         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1604                 return;
1605
1606         /* deinit the codec */
1607         if (chd->header.version < 5)
1608         {
1609                 if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1610                         (*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1611         }
1612         else
1613         {
1614                 int i;
1615                 /* Free the codecs */
1616                 for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
1617                 {
1618                         void* codec = NULL;
1619
1620                         if (chd->codecintf[i] == NULL)
1621                                 continue;
1622
1623                         switch (chd->codecintf[i]->compression)
1624                         {
1625                                 case CHD_CODEC_CD_LZMA:
1626                                         codec = &chd->cdlz_codec_data;
1627                                         break;
1628
1629                                 case CHD_CODEC_ZLIB:
1630                                         codec = &chd->zlib_codec_data;
1631                                         break;
1632
1633                                 case CHD_CODEC_CD_ZLIB:
1634                                         codec = &chd->cdzl_codec_data;
1635                                         break;
1636
1637                                 case CHD_CODEC_CD_FLAC:
1638                                         codec = &chd->cdfl_codec_data;
1639                                         break;
1640                         }
1641
1642                         if (codec)
1643                         {
1644                                 (*chd->codecintf[i]->free)(codec);
1645                         }
1646                 }
1647
1648                 /* Free the raw map */
1649                 if (chd->header.rawmap != NULL)
1650                         free(chd->header.rawmap);
1651         }
1652
1653         /* free the compressed data buffer */
1654         if (chd->compressed != NULL)
1655                 free(chd->compressed);
1656
1657 #ifdef NEED_CACHE_HUNK
1658         /* free the hunk cache and compare data */
1659         if (chd->compare != NULL)
1660                 free(chd->compare);
1661         if (chd->cache != NULL)
1662                 free(chd->cache);
1663 #endif
1664
1665         /* free the hunk map */
1666         if (chd->map != NULL)
1667                 free(chd->map);
1668
1669         /* close the file */
1670         if (chd->owns_file && chd->file != NULL)
1671                 core_fclose(chd->file);
1672
1673 #ifdef NEED_CACHE_HUNK
1674         if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1675 #endif
1676         if (chd->file_cache)
1677                 free(chd->file_cache);
1678
1679         /* free our memory */
1680         free(chd);
1681 }
1682
1683 /*-------------------------------------------------
1684     chd_core_file - return the associated
1685     core_file
1686 -------------------------------------------------*/
1687
1688 CHD_EXPORT core_file *chd_core_file(chd_file *chd)
1689 {
1690         return chd->file;
1691 }
1692
1693 /*-------------------------------------------------
1694     chd_error_string - return an error string for
1695     the given CHD error
1696 -------------------------------------------------*/
1697
1698 CHD_EXPORT const char *chd_error_string(chd_error err)
1699 {
1700         switch (err)
1701         {
1702                 case CHDERR_NONE:                                               return "no error";
1703                 case CHDERR_NO_INTERFACE:                               return "no drive interface";
1704                 case CHDERR_OUT_OF_MEMORY:                              return "out of memory";
1705                 case CHDERR_INVALID_FILE:                               return "invalid file";
1706                 case CHDERR_INVALID_PARAMETER:                  return "invalid parameter";
1707                 case CHDERR_INVALID_DATA:                               return "invalid data";
1708                 case CHDERR_FILE_NOT_FOUND:                             return "file not found";
1709                 case CHDERR_REQUIRES_PARENT:                    return "requires parent";
1710                 case CHDERR_FILE_NOT_WRITEABLE:                 return "file not writeable";
1711                 case CHDERR_READ_ERROR:                                 return "read error";
1712                 case CHDERR_WRITE_ERROR:                                return "write error";
1713                 case CHDERR_CODEC_ERROR:                                return "codec error";
1714                 case CHDERR_INVALID_PARENT:                             return "invalid parent";
1715                 case CHDERR_HUNK_OUT_OF_RANGE:                  return "hunk out of range";
1716                 case CHDERR_DECOMPRESSION_ERROR:                return "decompression error";
1717                 case CHDERR_COMPRESSION_ERROR:                  return "compression error";
1718                 case CHDERR_CANT_CREATE_FILE:                   return "can't create file";
1719                 case CHDERR_CANT_VERIFY:                                return "can't verify file";
1720                 case CHDERR_NOT_SUPPORTED:                              return "operation not supported";
1721                 case CHDERR_METADATA_NOT_FOUND:                 return "can't find metadata";
1722                 case CHDERR_INVALID_METADATA_SIZE:              return "invalid metadata size";
1723                 case CHDERR_UNSUPPORTED_VERSION:                return "unsupported CHD version";
1724                 case CHDERR_VERIFY_INCOMPLETE:                  return "incomplete verify";
1725                 case CHDERR_INVALID_METADATA:                   return "invalid metadata";
1726                 case CHDERR_INVALID_STATE:                              return "invalid state";
1727                 case CHDERR_OPERATION_PENDING:                  return "operation pending";
1728                 case CHDERR_NO_ASYNC_OPERATION:                 return "no async operation in progress";
1729                 case CHDERR_UNSUPPORTED_FORMAT:                 return "unsupported format";
1730                 default:                                                                return "undocumented error";
1731         }
1732 }
1733
1734 /***************************************************************************
1735     CHD HEADER MANAGEMENT
1736 ***************************************************************************/
1737
1738 /*-------------------------------------------------
1739     chd_get_header - return a pointer to the
1740     extracted header data
1741 -------------------------------------------------*/
1742
1743 CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
1744 {
1745         /* punt if NULL or invalid */
1746         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1747                 return NULL;
1748
1749         return &chd->header;
1750 }
1751
1752 /***************************************************************************
1753     CORE DATA READ/WRITE
1754 ***************************************************************************/
1755
1756 /*-------------------------------------------------
1757     chd_read - read a single hunk from the CHD
1758     file
1759 -------------------------------------------------*/
1760
1761 CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1762 {
1763         /* punt if NULL or invalid */
1764         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1765                 return CHDERR_INVALID_PARAMETER;
1766
1767         /* if we're past the end, fail */
1768         if (hunknum >= chd->header.totalhunks)
1769                 return CHDERR_HUNK_OUT_OF_RANGE;
1770
1771         /* perform the read */
1772         return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1773 }
1774
1775 /***************************************************************************
1776     METADATA MANAGEMENT
1777 ***************************************************************************/
1778
1779 /*-------------------------------------------------
1780     chd_get_metadata - get the indexed metadata
1781     of the given type
1782 -------------------------------------------------*/
1783
1784 CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1785 {
1786         metadata_entry metaentry;
1787         chd_error err;
1788         UINT32 count;
1789
1790         /* if we didn't find it, just return */
1791         err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1792         if (err != CHDERR_NONE)
1793         {
1794                 /* unless we're an old version and they are requesting hard disk metadata */
1795                 if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1796                 {
1797                         char faux_metadata[256];
1798                         UINT32 faux_length;
1799
1800                         /* fill in the faux metadata */
1801                         sprintf(faux_metadata, HARD_DISK_METADATA_FORMAT, chd->header.obsolete_cylinders, chd->header.obsolete_heads, chd->header.obsolete_sectors, chd->header.hunkbytes / chd->header.obsolete_hunksize);
1802                         faux_length = (UINT32)strlen(faux_metadata) + 1;
1803
1804                         /* copy the metadata itself */
1805                         memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1806
1807                         /* return the length of the data and the tag */
1808                         if (resultlen != NULL)
1809                                 *resultlen = faux_length;
1810                         if (resulttag != NULL)
1811                                 *resulttag = HARD_DISK_METADATA_TAG;
1812                         return CHDERR_NONE;
1813                 }
1814                 return err;
1815         }
1816
1817         /* read the metadata */
1818         outputlen = MIN(outputlen, metaentry.length);
1819         core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1820         count = core_fread(chd->file, output, outputlen);
1821         if (count != outputlen)
1822                 return CHDERR_READ_ERROR;
1823
1824         /* return the length of the data and the tag */
1825         if (resultlen != NULL)
1826                 *resultlen = metaentry.length;
1827         if (resulttag != NULL)
1828                 *resulttag = metaentry.metatag;
1829         if (resultflags != NULL)
1830                 *resultflags = metaentry.flags;
1831         return CHDERR_NONE;
1832 }
1833
1834 /***************************************************************************
1835     CODEC INTERFACES
1836 ***************************************************************************/
1837
1838 /*-------------------------------------------------
1839     chd_codec_config - set internal codec
1840     parameters
1841 -------------------------------------------------*/
1842
1843 CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config)
1844 {
1845         return CHDERR_INVALID_PARAMETER;
1846 }
1847
1848 /*-------------------------------------------------
1849     chd_get_codec_name - get the name of a
1850     particular codec
1851 -------------------------------------------------*/
1852
1853 CHD_EXPORT const char *chd_get_codec_name(UINT32 codec)
1854 {
1855         return "Unknown";
1856 }
1857
1858 /***************************************************************************
1859     INTERNAL HEADER OPERATIONS
1860 ***************************************************************************/
1861
1862 /*-------------------------------------------------
1863     header_validate - check the validity of a
1864     CHD header
1865 -------------------------------------------------*/
1866
1867 static chd_error header_validate(const chd_header *header)
1868 {
1869         int intfnum;
1870
1871         /* require a valid version */
1872         if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1873                 return CHDERR_UNSUPPORTED_VERSION;
1874
1875         /* require a valid length */
1876         if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1877                 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1878                 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1879                 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1880                 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1881                 return CHDERR_INVALID_PARAMETER;
1882
1883         /* Do not validate v5 header */
1884         if (header->version <= 4)
1885         {
1886                 /* require valid flags */
1887                 if (header->flags & CHDFLAGS_UNDEFINED)
1888                         return CHDERR_INVALID_PARAMETER;
1889
1890                 /* require a supported compression mechanism */
1891                 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1892                         if (codec_interfaces[intfnum].compression == header->compression[0])
1893                                 break;
1894
1895                 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1896                         return CHDERR_INVALID_PARAMETER;
1897
1898                 /* require a valid hunksize */
1899                 if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1900                         return CHDERR_INVALID_PARAMETER;
1901
1902                 /* require a valid hunk count */
1903                 if (header->totalhunks == 0)
1904                         return CHDERR_INVALID_PARAMETER;
1905
1906                 /* require a valid MD5 and/or SHA1 if we're using a parent */
1907                 if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1908                         return CHDERR_INVALID_PARAMETER;
1909
1910                 /* if we're V3 or later, the obsolete fields must be 0 */
1911                 if (header->version >= 3 &&
1912                         (header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1913                          header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1914                         return CHDERR_INVALID_PARAMETER;
1915
1916                 /* if we're pre-V3, the obsolete fields must NOT be 0 */
1917                 if (header->version < 3 &&
1918                         (header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1919                          header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1920                         return CHDERR_INVALID_PARAMETER;
1921         }
1922
1923         return CHDERR_NONE;
1924 }
1925
1926 /*-------------------------------------------------
1927     header_guess_unitbytes - for older CHD formats,
1928     guess at the bytes/unit based on metadata
1929 -------------------------------------------------*/
1930
1931 static UINT32 header_guess_unitbytes(chd_file *chd)
1932 {
1933         /* look for hard disk metadata; if found, then the unit size == sector size */
1934         char metadata[512];
1935         int i0, i1, i2, i3;
1936         if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
1937                 sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
1938                 return i3;
1939
1940         /* look for CD-ROM metadata; if found, then the unit size == CD frame size */
1941         if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1942                 chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1943                 chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1944                 chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1945                 chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
1946                 return CD_FRAME_SIZE;
1947
1948         /* otherwise, just map 1:1 with the hunk size */
1949         return chd->header.hunkbytes;
1950 }
1951
1952 /*-------------------------------------------------
1953     header_read - read a CHD header into the
1954     internal data structure
1955 -------------------------------------------------*/
1956
1957 static chd_error header_read(chd_file *chd, chd_header *header)
1958 {
1959         UINT8 rawheader[CHD_MAX_HEADER_SIZE];
1960         UINT32 count;
1961
1962         /* punt if NULL */
1963         if (header == NULL)
1964                 return CHDERR_INVALID_PARAMETER;
1965
1966         /* punt if invalid file */
1967         if (chd->file == NULL)
1968                 return CHDERR_INVALID_FILE;
1969
1970         /* seek and read */
1971         core_fseek(chd->file, 0, SEEK_SET);
1972         count = core_fread(chd->file, rawheader, sizeof(rawheader));
1973         if (count != sizeof(rawheader))
1974                 return CHDERR_READ_ERROR;
1975
1976         /* verify the tag */
1977         if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
1978                 return CHDERR_INVALID_DATA;
1979
1980         /* extract the direct data */
1981         memset(header, 0, sizeof(*header));
1982         header->length        = get_bigendian_uint32(&rawheader[8]);
1983         header->version       = get_bigendian_uint32(&rawheader[12]);
1984
1985         /* make sure it's a version we understand */
1986         if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1987                 return CHDERR_UNSUPPORTED_VERSION;
1988
1989         /* make sure the length is expected */
1990         if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1991                 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1992                 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1993                 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1994                 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1995
1996                 return CHDERR_INVALID_DATA;
1997
1998         /* extract the common data */
1999         header->flags           = get_bigendian_uint32(&rawheader[16]);
2000         header->compression[0]  = get_bigendian_uint32(&rawheader[20]);
2001         header->compression[1]  = CHD_CODEC_NONE;
2002         header->compression[2]  = CHD_CODEC_NONE;
2003         header->compression[3]  = CHD_CODEC_NONE;
2004
2005         /* extract the V1/V2-specific data */
2006         if (header->version < 3)
2007         {
2008                 int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
2009                 header->obsolete_hunksize  = get_bigendian_uint32(&rawheader[24]);
2010                 header->totalhunks         = get_bigendian_uint32(&rawheader[28]);
2011                 header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
2012                 header->obsolete_heads     = get_bigendian_uint32(&rawheader[36]);
2013                 header->obsolete_sectors   = get_bigendian_uint32(&rawheader[40]);
2014                 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2015                 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2016                 header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
2017                 header->hunkbytes = seclen * header->obsolete_hunksize;
2018                 header->unitbytes          = header_guess_unitbytes(chd);
2019                 header->unitcount          = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2020                 header->metaoffset = 0;
2021         }
2022
2023         /* extract the V3-specific data */
2024         else if (header->version == 3)
2025         {
2026                 header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2027                 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2028                 header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2029                 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2030                 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2031                 header->hunkbytes    = get_bigendian_uint32(&rawheader[76]);
2032                 header->unitbytes    = header_guess_unitbytes(chd);
2033                 header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2034                 memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
2035                 memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
2036         }
2037
2038         /* extract the V4-specific data */
2039         else if (header->version == 4)
2040         {
2041                 header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2042                 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2043                 header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2044                 header->hunkbytes    = get_bigendian_uint32(&rawheader[44]);
2045                 header->unitbytes    = header_guess_unitbytes(chd);
2046                 header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2047                 memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
2048                 memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
2049                 memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
2050         }
2051
2052         /* extract the V5-specific data */
2053         else if (header->version == 5)
2054         {
2055                 /* TODO */
2056                 header->compression[0]  = get_bigendian_uint32(&rawheader[16]);
2057                 header->compression[1]  = get_bigendian_uint32(&rawheader[20]);
2058                 header->compression[2]  = get_bigendian_uint32(&rawheader[24]);
2059                 header->compression[3]  = get_bigendian_uint32(&rawheader[28]);
2060                 header->logicalbytes    = get_bigendian_uint64(&rawheader[32]);
2061                 header->mapoffset       = get_bigendian_uint64(&rawheader[40]);
2062                 header->metaoffset      = get_bigendian_uint64(&rawheader[48]);
2063                 header->hunkbytes       = get_bigendian_uint32(&rawheader[56]);
2064                 header->hunkcount       = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
2065                 header->unitbytes       = get_bigendian_uint32(&rawheader[60]);
2066                 header->unitcount       = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2067                 memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
2068                 memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
2069                 memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
2070
2071                 /* determine properties of map entries */
2072                 header->mapentrybytes = chd_compressed(header) ? 12 : 4;
2073
2074                 /* hack */
2075                 header->totalhunks              = header->hunkcount;
2076         }
2077
2078         /* Unknown version */
2079         else
2080         {
2081                 /* TODO */
2082         }
2083
2084         /* guess it worked */
2085         return CHDERR_NONE;
2086 }
2087
2088 /***************************************************************************
2089     INTERNAL HUNK READ/WRITE
2090 ***************************************************************************/
2091
2092 /*-------------------------------------------------
2093     hunk_read_compressed - read a compressed
2094     hunk
2095 -------------------------------------------------*/
2096
2097 static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
2098 {
2099 #ifdef _MSC_VER
2100         size_t bytes;
2101 #else
2102         ssize_t bytes;
2103 #endif
2104         if (chd->file_cache != NULL)
2105         {
2106                 return chd->file_cache + offset;
2107         }
2108         else
2109         {
2110                 core_fseek(chd->file, offset, SEEK_SET);
2111                 bytes = core_fread(chd->file, chd->compressed, size);
2112                 if (bytes != size)
2113                         return NULL;
2114                 return chd->compressed;
2115         }
2116 }
2117
2118 /*-------------------------------------------------
2119     hunk_read_uncompressed - read an uncompressed
2120     hunk
2121 -------------------------------------------------*/
2122
2123 static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2124 {
2125 #ifdef _MSC_VER
2126         size_t bytes;
2127 #else
2128         ssize_t bytes;
2129 #endif
2130         if (chd->file_cache != NULL)
2131         {
2132                 memcpy(dest, chd->file_cache + offset, size);
2133         }
2134         else
2135         {
2136                 core_fseek(chd->file, offset, SEEK_SET);
2137                 bytes = core_fread(chd->file, dest, size);
2138                 if (bytes != size)
2139                         return CHDERR_READ_ERROR;
2140         }
2141         return CHDERR_NONE;
2142 }
2143
2144 #ifdef NEED_CACHE_HUNK
2145 /*-------------------------------------------------
2146     hunk_read_into_cache - read a hunk into
2147     the CHD's hunk cache
2148 -------------------------------------------------*/
2149
2150 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2151 {
2152         chd_error err;
2153
2154         /* track the max */
2155         if (hunknum > chd->maxhunk)
2156                 chd->maxhunk = hunknum;
2157
2158         /* if we're already in the cache, we're done */
2159         if (chd->cachehunk == hunknum)
2160                 return CHDERR_NONE;
2161         chd->cachehunk = ~0;
2162
2163         /* otherwise, read the data */
2164         err = hunk_read_into_memory(chd, hunknum, chd->cache);
2165         if (err != CHDERR_NONE)
2166                 return err;
2167
2168         /* mark the hunk successfully cached in */
2169         chd->cachehunk = hunknum;
2170         return CHDERR_NONE;
2171 }
2172 #endif
2173
2174 /*-------------------------------------------------
2175     hunk_read_into_memory - read a hunk into
2176     memory at the given location
2177 -------------------------------------------------*/
2178
2179 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2180 {
2181         chd_error err;
2182
2183         /* punt if no file */
2184         if (chd->file == NULL)
2185                 return CHDERR_INVALID_FILE;
2186
2187         /* return an error if out of range */
2188         if (hunknum >= chd->header.totalhunks)
2189                 return CHDERR_HUNK_OUT_OF_RANGE;
2190
2191         if (dest == NULL)
2192                 return CHDERR_INVALID_PARAMETER;
2193
2194         if (chd->header.version < 5)
2195         {
2196                 map_entry *entry = &chd->map[hunknum];
2197                 UINT32 bytes;
2198                 UINT8* compressed_bytes;
2199
2200                 /* switch off the entry type */
2201                 switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2202                 {
2203                         /* compressed data */
2204                         case V34_MAP_ENTRY_TYPE_COMPRESSED:
2205             {
2206                void *codec = NULL;
2207
2208                                 /* read it into the decompression buffer */
2209                                 compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
2210                                 if (compressed_bytes == NULL)
2211                                         return CHDERR_READ_ERROR;
2212
2213                                 /* now decompress using the codec */
2214                                 err = CHDERR_NONE;
2215                                 codec = &chd->zlib_codec_data;
2216                                 if (chd->codecintf[0]->decompress != NULL)
2217                                         err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
2218                                 if (err != CHDERR_NONE)
2219                                         return err;
2220                                 break;
2221                         }
2222
2223                         /* uncompressed data */
2224                         case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2225                                 err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2226                                 if (err != CHDERR_NONE)
2227                                         return err;
2228                                 break;
2229
2230                         /* mini-compressed data */
2231                         case V34_MAP_ENTRY_TYPE_MINI:
2232                                 put_bigendian_uint64(&dest[0], entry->offset);
2233                                 for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2234                                         dest[bytes] = dest[bytes - 8];
2235                                 break;
2236
2237                         /* self-referenced data */
2238                         case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2239 #ifdef NEED_CACHE_HUNK
2240                                 if (chd->cachehunk == entry->offset && dest == chd->cache)
2241                                         break;
2242 #endif
2243                                 return hunk_read_into_memory(chd, entry->offset, dest);
2244
2245                         /* parent-referenced data */
2246                         case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2247                                 err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2248                                 if (err != CHDERR_NONE)
2249                                         return err;
2250                                 break;
2251                 }
2252                 return CHDERR_NONE;
2253         }
2254         else
2255         {
2256                 void* codec = NULL;
2257                 /* get a pointer to the map entry */
2258                 uint64_t blockoffs;
2259                 uint32_t blocklen;
2260 #ifdef VERIFY_BLOCK_CRC
2261                 uint16_t blockcrc;
2262 #endif
2263                 uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2264                 UINT8* compressed_bytes;
2265
2266                 /* uncompressed case */
2267                 if (!chd_compressed(&chd->header))
2268                 {
2269                         blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
2270                         if (blockoffs != 0) {
2271                                 core_fseek(chd->file, blockoffs, SEEK_SET);
2272                                 int result = core_fread(chd->file, dest, chd->header.hunkbytes);
2273                         /* TODO
2274                         else if (m_parent_missing)
2275                                 throw CHDERR_REQUIRES_PARENT; */
2276                         } else if (chd->parent) {
2277                                 err = hunk_read_into_memory(chd->parent, hunknum, dest);
2278                                 if (err != CHDERR_NONE)
2279                                         return err;
2280                         } else {
2281                                 memset(dest, 0, chd->header.hunkbytes);
2282                         }
2283
2284                         return CHDERR_NONE;
2285                 }
2286
2287                 /* compressed case */
2288                 blocklen = get_bigendian_uint24(&rawmap[1]);
2289                 blockoffs = get_bigendian_uint48(&rawmap[4]);
2290 #ifdef VERIFY_BLOCK_CRC
2291                 blockcrc = get_bigendian_uint16(&rawmap[10]);
2292 #endif
2293                 codec = NULL;
2294                 switch (rawmap[0])
2295                 {
2296                         case COMPRESSION_TYPE_0:
2297                         case COMPRESSION_TYPE_1:
2298                         case COMPRESSION_TYPE_2:
2299                         case COMPRESSION_TYPE_3:
2300                                 compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
2301                                 if (compressed_bytes == NULL)
2302                                         return CHDERR_READ_ERROR;
2303                                 switch (chd->codecintf[rawmap[0]]->compression)
2304                                 {
2305                                         case CHD_CODEC_CD_LZMA:
2306                                                 codec = &chd->cdlz_codec_data;
2307                                                 break;
2308
2309                                         case CHD_CODEC_ZLIB:
2310                                                 codec = &chd->zlib_codec_data;
2311                                                 break;
2312
2313                                         case CHD_CODEC_CD_ZLIB:
2314                                                 codec = &chd->cdzl_codec_data;
2315                                                 break;
2316
2317                                         case CHD_CODEC_CD_FLAC:
2318                                                 codec = &chd->cdfl_codec_data;
2319                                                 break;
2320                                 }
2321                                 if (codec==NULL)
2322                                         return CHDERR_CODEC_ERROR;
2323                                 err = chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
2324                                 if (err != CHDERR_NONE)
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_NONE:
2333                                 err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest);
2334                                 if (err != CHDERR_NONE)
2335                                         return err;
2336 #ifdef VERIFY_BLOCK_CRC
2337                                 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2338                                         return CHDERR_DECOMPRESSION_ERROR;
2339 #endif
2340                                 return CHDERR_NONE;
2341
2342                         case COMPRESSION_SELF:
2343                                 return hunk_read_into_memory(chd, blockoffs, dest);
2344
2345                         case COMPRESSION_PARENT:
2346 #if 0
2347                                 /* TODO */
2348                                 if (m_parent_missing)
2349                                         return CHDERR_REQUIRES_PARENT;
2350                                 return m_parent->read_bytes(uint64_t(blockoffs) * uint64_t(m_parent->unit_bytes()), dest, m_hunkbytes);
2351 #endif
2352                                 return CHDERR_DECOMPRESSION_ERROR;
2353                 }
2354                 return CHDERR_NONE;
2355         }
2356
2357         /* We should not reach this code */
2358         return CHDERR_DECOMPRESSION_ERROR;
2359 }
2360
2361 /***************************************************************************
2362     INTERNAL MAP ACCESS
2363 ***************************************************************************/
2364
2365 /*-------------------------------------------------
2366     map_read - read the initial sector map
2367 -------------------------------------------------*/
2368
2369 static chd_error map_read(chd_file *chd)
2370 {
2371         UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2372         UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2373         UINT64 fileoffset, maxoffset = 0;
2374         UINT8 cookie[MAP_ENTRY_SIZE];
2375         UINT32 count;
2376         chd_error err;
2377         int i;
2378
2379         /* first allocate memory */
2380         chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2381         if (!chd->map)
2382                 return CHDERR_OUT_OF_MEMORY;
2383
2384         /* read the map entries in in chunks and extract to the map list */
2385         fileoffset = chd->header.length;
2386         for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2387         {
2388                 /* compute how many entries this time */
2389                 int entries = chd->header.totalhunks - i, j;
2390                 if (entries > MAP_STACK_ENTRIES)
2391                         entries = MAP_STACK_ENTRIES;
2392
2393                 /* read that many */
2394                 core_fseek(chd->file, fileoffset, SEEK_SET);
2395                 count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2396                 if (count != entries * entrysize)
2397                 {
2398                         err = CHDERR_READ_ERROR;
2399                         goto cleanup;
2400                 }
2401                 fileoffset += entries * entrysize;
2402
2403                 /* process that many */
2404                 if (entrysize == MAP_ENTRY_SIZE)
2405                 {
2406                         for (j = 0; j < entries; j++)
2407                                 map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2408                 }
2409                 else
2410                 {
2411                         for (j = 0; j < entries; j++)
2412                                 map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2413                 }
2414
2415                 /* track the maximum offset */
2416                 for (j = 0; j < entries; j++)
2417                         if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2418                                 (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2419                                 maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2420         }
2421
2422         /* verify the cookie */
2423         core_fseek(chd->file, fileoffset, SEEK_SET);
2424         count = core_fread(chd->file, &cookie, entrysize);
2425         if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2426         {
2427                 err = CHDERR_INVALID_FILE;
2428                 goto cleanup;
2429         }
2430
2431         /* verify the length */
2432         if (maxoffset > core_fsize(chd->file))
2433         {
2434                 err = CHDERR_INVALID_FILE;
2435                 goto cleanup;
2436         }
2437         return CHDERR_NONE;
2438
2439 cleanup:
2440         if (chd->map)
2441                 free(chd->map);
2442         chd->map = NULL;
2443         return err;
2444 }
2445
2446 /***************************************************************************
2447     INTERNAL METADATA ACCESS
2448 ***************************************************************************/
2449
2450 /*-------------------------------------------------
2451     metadata_find_entry - find a metadata entry
2452 -------------------------------------------------*/
2453
2454 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2455 {
2456         /* start at the beginning */
2457         metaentry->offset = chd->header.metaoffset;
2458         metaentry->prev = 0;
2459
2460         /* loop until we run out of options */
2461         while (metaentry->offset != 0)
2462         {
2463                 UINT8   raw_meta_header[METADATA_HEADER_SIZE];
2464                 UINT32  count;
2465
2466                 /* read the raw header */
2467                 core_fseek(chd->file, metaentry->offset, SEEK_SET);
2468                 count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2469                 if (count != sizeof(raw_meta_header))
2470                         break;
2471
2472                 /* extract the data */
2473                 metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2474                 metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2475                 metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2476
2477                 /* flags are encoded in the high byte of length */
2478                 metaentry->flags = metaentry->length >> 24;
2479                 metaentry->length &= 0x00ffffff;
2480
2481                 /* if we got a match, proceed */
2482                 if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2483                         if (metaindex-- == 0)
2484                                 return CHDERR_NONE;
2485
2486                 /* no match, fetch the next link */
2487                 metaentry->prev = metaentry->offset;
2488                 metaentry->offset = metaentry->next;
2489         }
2490
2491         /* if we get here, we didn't find it */
2492         return CHDERR_METADATA_NOT_FOUND;
2493 }
2494
2495 /***************************************************************************
2496     ZLIB COMPRESSION CODEC
2497 ***************************************************************************/
2498
2499 /*-------------------------------------------------
2500     zlib_codec_init - initialize the ZLIB codec
2501 -------------------------------------------------*/
2502
2503 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2504 {
2505         int zerr;
2506         chd_error err;
2507         zlib_codec_data *data = (zlib_codec_data*)codec;
2508
2509         /* clear the buffers */
2510         memset(data, 0, sizeof(zlib_codec_data));
2511
2512         /* init the inflater first */
2513         data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */
2514         data->inflater.avail_in = 0;
2515         data->inflater.zalloc = zlib_fast_alloc;
2516         data->inflater.zfree = zlib_fast_free;
2517         data->inflater.opaque = &data->allocator;
2518         zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2519
2520         /* convert errors */
2521         if (zerr == Z_MEM_ERROR)
2522                 err = CHDERR_OUT_OF_MEMORY;
2523         else if (zerr != Z_OK)
2524                 err = CHDERR_CODEC_ERROR;
2525         else
2526                 err = CHDERR_NONE;
2527
2528         /* handle an error */
2529         if (err != CHDERR_NONE)
2530                 free(data);
2531
2532         return err;
2533 }
2534
2535 /*-------------------------------------------------
2536     zlib_codec_free - free data for the ZLIB
2537     codec
2538 -------------------------------------------------*/
2539
2540 static void zlib_codec_free(void *codec)
2541 {
2542         zlib_codec_data *data = (zlib_codec_data *)codec;
2543
2544         /* deinit the streams */
2545         if (data != NULL)
2546         {
2547                 int i;
2548
2549                 inflateEnd(&data->inflater);
2550
2551                 /* free our fast memory */
2552                 zlib_allocator_free(&data->allocator);
2553         }
2554 }
2555
2556 /*-------------------------------------------------
2557     zlib_codec_decompress - decompress data using
2558     the ZLIB codec
2559 -------------------------------------------------*/
2560
2561 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2562 {
2563         zlib_codec_data *data = (zlib_codec_data *)codec;
2564         int zerr;
2565
2566         /* reset the decompressor */
2567         data->inflater.next_in = (Bytef *)src;
2568         data->inflater.avail_in = complen;
2569         data->inflater.total_in = 0;
2570         data->inflater.next_out = (Bytef *)dest;
2571         data->inflater.avail_out = destlen;
2572         data->inflater.total_out = 0;
2573         zerr = inflateReset(&data->inflater);
2574         if (zerr != Z_OK)
2575                 return CHDERR_DECOMPRESSION_ERROR;
2576
2577         /* do it */
2578         zerr = inflate(&data->inflater, Z_FINISH);
2579         if (data->inflater.total_out != destlen)
2580                 return CHDERR_DECOMPRESSION_ERROR;
2581
2582         return CHDERR_NONE;
2583 }
2584
2585 /*-------------------------------------------------
2586     zlib_fast_alloc - fast malloc for ZLIB, which
2587     allocates and frees memory frequently
2588 -------------------------------------------------*/
2589
2590 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
2591 #define ZLIB_MIN_ALIGNMENT_BITS 512
2592 #define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
2593
2594 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2595 {
2596         zlib_allocator *alloc = (zlib_allocator *)opaque;
2597         uintptr_t paddr = 0;
2598         UINT32 *ptr;
2599         int i;
2600
2601         /* compute the size, rounding to the nearest 1k */
2602         size = (size * items + 0x3ff) & ~0x3ff;
2603
2604         /* reuse a hunk if we can */
2605         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2606         {
2607                 ptr = alloc->allocptr[i];
2608                 if (ptr && size == *ptr)
2609                 {
2610                         /* set the low bit of the size so we don't match next time */
2611                         *ptr |= 1;
2612
2613                         /* return aligned block address */
2614                         return (voidpf)(alloc->allocptr2[i]);
2615                 }
2616         }
2617
2618         /* alloc a new one */
2619     ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
2620         if (!ptr)
2621                 return NULL;
2622
2623         /* put it into the list */
2624         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2625                 if (!alloc->allocptr[i])
2626                 {
2627                         alloc->allocptr[i] = ptr;
2628                         paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
2629                         alloc->allocptr2[i] = (uint32_t*)paddr;
2630                         break;
2631                 }
2632
2633         /* set the low bit of the size so we don't match next time */
2634         *ptr = size | 1;
2635
2636         /* return aligned block address */
2637         return (voidpf)paddr;
2638 }
2639
2640 /*-------------------------------------------------
2641     zlib_fast_free - fast free for ZLIB, which
2642     allocates and frees memory frequently
2643 -------------------------------------------------*/
2644
2645 static void zlib_fast_free(voidpf opaque, voidpf address)
2646 {
2647         zlib_allocator *alloc = (zlib_allocator *)opaque;
2648         UINT32 *ptr = (UINT32 *)address;
2649         int i;
2650
2651         /* find the hunk */
2652         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2653                 if (ptr == alloc->allocptr2[i])
2654                 {
2655                         /* clear the low bit of the size to allow matches */
2656                         *(alloc->allocptr[i]) &= ~1;
2657                         return;
2658                 }
2659 }
2660
2661 /*-------------------------------------------------
2662     zlib_allocator_free
2663 -------------------------------------------------*/
2664 static void zlib_allocator_free(voidpf opaque)
2665 {
2666         zlib_allocator *alloc = (zlib_allocator *)opaque;
2667         int i;
2668
2669         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2670                 if (alloc->allocptr[i])
2671                         free(alloc->allocptr[i]);
2672 }