c5cc1794ec3279cca00020b09f8fd76637cda0dc
[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)
1386         {
1387                 /* Detect parent requirement for versions below 5 */
1388                 if (newchd->header.version < 5 && newchd->header.flags & CHDFLAGS_HAS_PARENT)
1389                         EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1390                 /* Detection for version 5 and above - if parentsha1 != 0, we have a parent */
1391                 else if (newchd->header.version >= 5 && memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1392                         EARLY_EXIT(err = CHDERR_REQUIRES_PARENT);
1393         }
1394
1395         /* make sure we have a valid parent */
1396         if (parent != NULL)
1397         {
1398                 /* check MD5 if it isn't empty */
1399                 if (memcmp(nullmd5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0 &&
1400                         memcmp(nullmd5, newchd->parent->header.md5, sizeof(newchd->parent->header.md5)) != 0 &&
1401                         memcmp(newchd->parent->header.md5, newchd->header.parentmd5, sizeof(newchd->header.parentmd5)) != 0)
1402                         EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1403
1404                 /* check SHA1 if it isn't empty */
1405                 if (memcmp(nullsha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0 &&
1406                         memcmp(nullsha1, newchd->parent->header.sha1, sizeof(newchd->parent->header.sha1)) != 0 &&
1407                         memcmp(newchd->parent->header.sha1, newchd->header.parentsha1, sizeof(newchd->header.parentsha1)) != 0)
1408                         EARLY_EXIT(err = CHDERR_INVALID_PARENT);
1409         }
1410
1411         /* now read the hunk map */
1412         if (newchd->header.version < 5)
1413         {
1414                 err = map_read(newchd);
1415                 if (err != CHDERR_NONE)
1416                         EARLY_EXIT(err);
1417         }
1418         else
1419         {
1420                 err = decompress_v5_map(newchd, &(newchd->header));
1421         }
1422         if (err != CHDERR_NONE)
1423                 EARLY_EXIT(err);
1424
1425 #ifdef NEED_CACHE_HUNK
1426         /* allocate and init the hunk cache */
1427         newchd->cache = (UINT8 *)malloc(newchd->header.hunkbytes);
1428         newchd->compare = (UINT8 *)malloc(newchd->header.hunkbytes);
1429         if (newchd->cache == NULL || newchd->compare == NULL)
1430                 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1431         newchd->cachehunk = ~0;
1432         newchd->comparehunk = ~0;
1433 #endif
1434
1435         /* allocate the temporary compressed buffer */
1436         newchd->compressed = (UINT8 *)malloc(newchd->header.hunkbytes);
1437         if (newchd->compressed == NULL)
1438                 EARLY_EXIT(err = CHDERR_OUT_OF_MEMORY);
1439
1440         /* find the codec interface */
1441         if (newchd->header.version < 5)
1442         {
1443                 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1444                 {
1445                         if (codec_interfaces[intfnum].compression == newchd->header.compression[0])
1446                         {
1447                                 newchd->codecintf[0] = &codec_interfaces[intfnum];
1448                                 break;
1449                         }
1450                 }
1451
1452                 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1453                         EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1454
1455                 /* initialize the codec */
1456                 if (newchd->codecintf[0]->init != NULL)
1457                 {
1458                         err = (*newchd->codecintf[0]->init)(&newchd->zlib_codec_data, newchd->header.hunkbytes);
1459                         if (err != CHDERR_NONE)
1460                                 EARLY_EXIT(err);
1461                 }
1462         }
1463         else
1464         {
1465                 int decompnum;
1466                 /* verify the compression types and initialize the codecs */
1467                 for (decompnum = 0; decompnum < ARRAY_LENGTH(newchd->header.compression); decompnum++)
1468                 {
1469                         int i;
1470                         for (i = 0 ; i < ARRAY_LENGTH(codec_interfaces) ; i++)
1471                         {
1472                                 if (codec_interfaces[i].compression == newchd->header.compression[decompnum])
1473                                 {
1474                                         newchd->codecintf[decompnum] = &codec_interfaces[i];
1475                                         break;
1476                                 }
1477                         }
1478
1479                         if (newchd->codecintf[decompnum] == NULL && newchd->header.compression[decompnum] != 0)
1480                                 EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1481
1482                         /* initialize the codec */
1483                         if (newchd->codecintf[decompnum]->init != NULL)
1484                         {
1485                                 void* codec = NULL;
1486                                 switch (newchd->header.compression[decompnum])
1487                                 {
1488                                         case CHD_CODEC_ZLIB:
1489                                                 codec = &newchd->zlib_codec_data;
1490                                                 break;
1491
1492                                         case CHD_CODEC_CD_ZLIB:
1493                                                 codec = &newchd->cdzl_codec_data;
1494                                                 break;
1495
1496                                         case CHD_CODEC_CD_LZMA:
1497                                                 codec = &newchd->cdlz_codec_data;
1498                                                 break;
1499
1500                                         case CHD_CODEC_CD_FLAC:
1501                                                 codec = &newchd->cdfl_codec_data;
1502                                                 break;
1503                                 }
1504
1505                                 if (codec == NULL)
1506                                         EARLY_EXIT(err = CHDERR_UNSUPPORTED_FORMAT);
1507
1508                                 err = (*newchd->codecintf[decompnum]->init)(codec, newchd->header.hunkbytes);
1509                                 if (err != CHDERR_NONE)
1510                                         EARLY_EXIT(err);
1511                         }
1512                 }
1513         }
1514
1515         /* all done */
1516         *chd = newchd;
1517         return CHDERR_NONE;
1518
1519 cleanup:
1520         if (newchd != NULL)
1521                 chd_close(newchd);
1522         return err;
1523 }
1524
1525 /*-------------------------------------------------
1526     chd_precache - precache underlying file in
1527     memory
1528 -------------------------------------------------*/
1529
1530 CHD_EXPORT chd_error chd_precache(chd_file *chd)
1531 {
1532 #ifdef _MSC_VER
1533         size_t size, count;
1534 #else
1535         ssize_t size, count;
1536 #endif
1537
1538         if (chd->file_cache == NULL)
1539         {
1540                 core_fseek(chd->file, 0, SEEK_END);
1541                 size = core_ftell(chd->file);
1542                 if (size <= 0)
1543                         return CHDERR_INVALID_DATA;
1544                 chd->file_cache = malloc(size);
1545                 if (chd->file_cache == NULL)
1546                         return CHDERR_OUT_OF_MEMORY;
1547                 core_fseek(chd->file, 0, SEEK_SET);
1548                 count = core_fread(chd->file, chd->file_cache, size);
1549                 if (count != size)
1550                 {
1551                         free(chd->file_cache);
1552                         chd->file_cache = NULL;
1553                         return CHDERR_READ_ERROR;
1554                 }
1555         }
1556
1557         return CHDERR_NONE;
1558 }
1559
1560 /*-------------------------------------------------
1561     chd_open - open a CHD file by
1562     filename
1563 -------------------------------------------------*/
1564
1565 CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent, chd_file **chd)
1566 {
1567         chd_error err;
1568         core_file *file = NULL;
1569
1570         /* choose the proper mode */
1571         switch(mode)
1572         {
1573                 case CHD_OPEN_READ:
1574                         break;
1575
1576                 default:
1577                         err = CHDERR_INVALID_PARAMETER;
1578                         goto cleanup;
1579         }
1580
1581         /* open the file */
1582         file = core_fopen(filename);
1583         if (file == 0)
1584         {
1585                 err = CHDERR_FILE_NOT_FOUND;
1586                 goto cleanup;
1587         }
1588
1589         /* now open the CHD */
1590         err = chd_open_file(file, mode, parent, chd);
1591         if (err != CHDERR_NONE)
1592                 goto cleanup;
1593
1594         /* we now own this file */
1595         (*chd)->owns_file = TRUE;
1596
1597 cleanup:
1598         if ((err != CHDERR_NONE) && (file != NULL))
1599                 core_fclose(file);
1600         return err;
1601 }
1602
1603 /*-------------------------------------------------
1604     chd_close - close a CHD file for access
1605 -------------------------------------------------*/
1606
1607 CHD_EXPORT void chd_close(chd_file *chd)
1608 {
1609         /* punt if NULL or invalid */
1610         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1611                 return;
1612
1613         /* deinit the codec */
1614         if (chd->header.version < 5)
1615         {
1616                 if (chd->codecintf[0] != NULL && chd->codecintf[0]->free != NULL)
1617                         (*chd->codecintf[0]->free)(&chd->zlib_codec_data);
1618         }
1619         else
1620         {
1621                 int i;
1622                 /* Free the codecs */
1623                 for (i = 0 ; i < ARRAY_LENGTH(chd->codecintf); i++)
1624                 {
1625                         void* codec = NULL;
1626
1627                         if (chd->codecintf[i] == NULL)
1628                                 continue;
1629
1630                         switch (chd->codecintf[i]->compression)
1631                         {
1632                                 case CHD_CODEC_CD_LZMA:
1633                                         codec = &chd->cdlz_codec_data;
1634                                         break;
1635
1636                                 case CHD_CODEC_ZLIB:
1637                                         codec = &chd->zlib_codec_data;
1638                                         break;
1639
1640                                 case CHD_CODEC_CD_ZLIB:
1641                                         codec = &chd->cdzl_codec_data;
1642                                         break;
1643
1644                                 case CHD_CODEC_CD_FLAC:
1645                                         codec = &chd->cdfl_codec_data;
1646                                         break;
1647                         }
1648
1649                         if (codec)
1650                         {
1651                                 (*chd->codecintf[i]->free)(codec);
1652                         }
1653                 }
1654
1655                 /* Free the raw map */
1656                 if (chd->header.rawmap != NULL)
1657                         free(chd->header.rawmap);
1658         }
1659
1660         /* free the compressed data buffer */
1661         if (chd->compressed != NULL)
1662                 free(chd->compressed);
1663
1664 #ifdef NEED_CACHE_HUNK
1665         /* free the hunk cache and compare data */
1666         if (chd->compare != NULL)
1667                 free(chd->compare);
1668         if (chd->cache != NULL)
1669                 free(chd->cache);
1670 #endif
1671
1672         /* free the hunk map */
1673         if (chd->map != NULL)
1674                 free(chd->map);
1675
1676         /* close the file */
1677         if (chd->owns_file && chd->file != NULL)
1678                 core_fclose(chd->file);
1679
1680 #ifdef NEED_CACHE_HUNK
1681         if (PRINTF_MAX_HUNK) printf("Max hunk = %d/%d\n", chd->maxhunk, chd->header.totalhunks);
1682 #endif
1683         if (chd->file_cache)
1684                 free(chd->file_cache);
1685
1686         if (chd->parent)
1687                 chd_close(chd->parent);
1688
1689         /* free our memory */
1690         free(chd);
1691 }
1692
1693 /*-------------------------------------------------
1694     chd_core_file - return the associated
1695     core_file
1696 -------------------------------------------------*/
1697
1698 CHD_EXPORT core_file *chd_core_file(chd_file *chd)
1699 {
1700         return chd->file;
1701 }
1702
1703 /*-------------------------------------------------
1704     chd_error_string - return an error string for
1705     the given CHD error
1706 -------------------------------------------------*/
1707
1708 CHD_EXPORT const char *chd_error_string(chd_error err)
1709 {
1710         switch (err)
1711         {
1712                 case CHDERR_NONE:                                               return "no error";
1713                 case CHDERR_NO_INTERFACE:                               return "no drive interface";
1714                 case CHDERR_OUT_OF_MEMORY:                              return "out of memory";
1715                 case CHDERR_INVALID_FILE:                               return "invalid file";
1716                 case CHDERR_INVALID_PARAMETER:                  return "invalid parameter";
1717                 case CHDERR_INVALID_DATA:                               return "invalid data";
1718                 case CHDERR_FILE_NOT_FOUND:                             return "file not found";
1719                 case CHDERR_REQUIRES_PARENT:                    return "requires parent";
1720                 case CHDERR_FILE_NOT_WRITEABLE:                 return "file not writeable";
1721                 case CHDERR_READ_ERROR:                                 return "read error";
1722                 case CHDERR_WRITE_ERROR:                                return "write error";
1723                 case CHDERR_CODEC_ERROR:                                return "codec error";
1724                 case CHDERR_INVALID_PARENT:                             return "invalid parent";
1725                 case CHDERR_HUNK_OUT_OF_RANGE:                  return "hunk out of range";
1726                 case CHDERR_DECOMPRESSION_ERROR:                return "decompression error";
1727                 case CHDERR_COMPRESSION_ERROR:                  return "compression error";
1728                 case CHDERR_CANT_CREATE_FILE:                   return "can't create file";
1729                 case CHDERR_CANT_VERIFY:                                return "can't verify file";
1730                 case CHDERR_NOT_SUPPORTED:                              return "operation not supported";
1731                 case CHDERR_METADATA_NOT_FOUND:                 return "can't find metadata";
1732                 case CHDERR_INVALID_METADATA_SIZE:              return "invalid metadata size";
1733                 case CHDERR_UNSUPPORTED_VERSION:                return "unsupported CHD version";
1734                 case CHDERR_VERIFY_INCOMPLETE:                  return "incomplete verify";
1735                 case CHDERR_INVALID_METADATA:                   return "invalid metadata";
1736                 case CHDERR_INVALID_STATE:                              return "invalid state";
1737                 case CHDERR_OPERATION_PENDING:                  return "operation pending";
1738                 case CHDERR_NO_ASYNC_OPERATION:                 return "no async operation in progress";
1739                 case CHDERR_UNSUPPORTED_FORMAT:                 return "unsupported format";
1740                 default:                                                                return "undocumented error";
1741         }
1742 }
1743
1744 /***************************************************************************
1745     CHD HEADER MANAGEMENT
1746 ***************************************************************************/
1747
1748 /*-------------------------------------------------
1749     chd_get_header - return a pointer to the
1750     extracted header data
1751 -------------------------------------------------*/
1752
1753 CHD_EXPORT const chd_header *chd_get_header(chd_file *chd)
1754 {
1755         /* punt if NULL or invalid */
1756         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1757                 return NULL;
1758
1759         return &chd->header;
1760 }
1761
1762 /*-------------------------------------------------
1763     chd_read_header - read CHD header data
1764         from file into the pointed struct
1765 -------------------------------------------------*/
1766 CHD_EXPORT chd_error chd_read_header(const char *filename, chd_header *header)
1767 {
1768         chd_error err = CHDERR_NONE;
1769         chd_file chd;
1770
1771         /* punt if NULL */
1772         if (filename == NULL || header == NULL)
1773                 EARLY_EXIT(err = CHDERR_INVALID_PARAMETER);
1774
1775         /* open the file */
1776         chd.file = core_fopen(filename);
1777         if (chd.file == NULL)
1778                 EARLY_EXIT(err = CHDERR_FILE_NOT_FOUND);
1779
1780         /* attempt to read the header */
1781         err = header_read(&chd, header);
1782         if (err != CHDERR_NONE)
1783                 EARLY_EXIT(err);
1784
1785         /* validate the header */
1786         err = header_validate(header);
1787         if (err != CHDERR_NONE)
1788                 EARLY_EXIT(err);
1789
1790 cleanup:
1791         if (chd.file != NULL)
1792                 core_fclose(chd.file);
1793
1794         return err;
1795 }
1796
1797 /***************************************************************************
1798     CORE DATA READ/WRITE
1799 ***************************************************************************/
1800
1801 /*-------------------------------------------------
1802     chd_read - read a single hunk from the CHD
1803     file
1804 -------------------------------------------------*/
1805
1806 CHD_EXPORT chd_error chd_read(chd_file *chd, UINT32 hunknum, void *buffer)
1807 {
1808         /* punt if NULL or invalid */
1809         if (chd == NULL || chd->cookie != COOKIE_VALUE)
1810                 return CHDERR_INVALID_PARAMETER;
1811
1812         /* if we're past the end, fail */
1813         if (hunknum >= chd->header.totalhunks)
1814                 return CHDERR_HUNK_OUT_OF_RANGE;
1815
1816         /* perform the read */
1817         return hunk_read_into_memory(chd, hunknum, (UINT8 *)buffer);
1818 }
1819
1820 /***************************************************************************
1821     METADATA MANAGEMENT
1822 ***************************************************************************/
1823
1824 /*-------------------------------------------------
1825     chd_get_metadata - get the indexed metadata
1826     of the given type
1827 -------------------------------------------------*/
1828
1829 CHD_EXPORT chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags)
1830 {
1831         metadata_entry metaentry;
1832         chd_error err;
1833         UINT32 count;
1834
1835         /* if we didn't find it, just return */
1836         err = metadata_find_entry(chd, searchtag, searchindex, &metaentry);
1837         if (err != CHDERR_NONE)
1838         {
1839                 /* unless we're an old version and they are requesting hard disk metadata */
1840                 if (chd->header.version < 3 && (searchtag == HARD_DISK_METADATA_TAG || searchtag == CHDMETATAG_WILDCARD) && searchindex == 0)
1841                 {
1842                         char faux_metadata[256];
1843                         UINT32 faux_length;
1844
1845                         /* fill in the faux metadata */
1846                         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);
1847                         faux_length = (UINT32)strlen(faux_metadata) + 1;
1848
1849                         /* copy the metadata itself */
1850                         memcpy(output, faux_metadata, MIN(outputlen, faux_length));
1851
1852                         /* return the length of the data and the tag */
1853                         if (resultlen != NULL)
1854                                 *resultlen = faux_length;
1855                         if (resulttag != NULL)
1856                                 *resulttag = HARD_DISK_METADATA_TAG;
1857                         return CHDERR_NONE;
1858                 }
1859                 return err;
1860         }
1861
1862         /* read the metadata */
1863         outputlen = MIN(outputlen, metaentry.length);
1864         core_fseek(chd->file, metaentry.offset + METADATA_HEADER_SIZE, SEEK_SET);
1865         count = core_fread(chd->file, output, outputlen);
1866         if (count != outputlen)
1867                 return CHDERR_READ_ERROR;
1868
1869         /* return the length of the data and the tag */
1870         if (resultlen != NULL)
1871                 *resultlen = metaentry.length;
1872         if (resulttag != NULL)
1873                 *resulttag = metaentry.metatag;
1874         if (resultflags != NULL)
1875                 *resultflags = metaentry.flags;
1876         return CHDERR_NONE;
1877 }
1878
1879 /***************************************************************************
1880     CODEC INTERFACES
1881 ***************************************************************************/
1882
1883 /*-------------------------------------------------
1884     chd_codec_config - set internal codec
1885     parameters
1886 -------------------------------------------------*/
1887
1888 CHD_EXPORT chd_error chd_codec_config(chd_file *chd, int param, void *config)
1889 {
1890         return CHDERR_INVALID_PARAMETER;
1891 }
1892
1893 /*-------------------------------------------------
1894     chd_get_codec_name - get the name of a
1895     particular codec
1896 -------------------------------------------------*/
1897
1898 CHD_EXPORT const char *chd_get_codec_name(UINT32 codec)
1899 {
1900         return "Unknown";
1901 }
1902
1903 /***************************************************************************
1904     INTERNAL HEADER OPERATIONS
1905 ***************************************************************************/
1906
1907 /*-------------------------------------------------
1908     header_validate - check the validity of a
1909     CHD header
1910 -------------------------------------------------*/
1911
1912 static chd_error header_validate(const chd_header *header)
1913 {
1914         int intfnum;
1915
1916         /* require a valid version */
1917         if (header->version == 0 || header->version > CHD_HEADER_VERSION)
1918                 return CHDERR_UNSUPPORTED_VERSION;
1919
1920         /* require a valid length */
1921         if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
1922                 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
1923                 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
1924                 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
1925                 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
1926                 return CHDERR_INVALID_PARAMETER;
1927
1928         /* Do not validate v5 header */
1929         if (header->version <= 4)
1930         {
1931                 /* require valid flags */
1932                 if (header->flags & CHDFLAGS_UNDEFINED)
1933                         return CHDERR_INVALID_PARAMETER;
1934
1935                 /* require a supported compression mechanism */
1936                 for (intfnum = 0; intfnum < ARRAY_LENGTH(codec_interfaces); intfnum++)
1937                         if (codec_interfaces[intfnum].compression == header->compression[0])
1938                                 break;
1939
1940                 if (intfnum == ARRAY_LENGTH(codec_interfaces))
1941                         return CHDERR_INVALID_PARAMETER;
1942
1943                 /* require a valid hunksize */
1944                 if (header->hunkbytes == 0 || header->hunkbytes >= 65536 * 256)
1945                         return CHDERR_INVALID_PARAMETER;
1946
1947                 /* require a valid hunk count */
1948                 if (header->totalhunks == 0)
1949                         return CHDERR_INVALID_PARAMETER;
1950
1951                 /* require a valid MD5 and/or SHA1 if we're using a parent */
1952                 if ((header->flags & CHDFLAGS_HAS_PARENT) && memcmp(header->parentmd5, nullmd5, sizeof(nullmd5)) == 0 && memcmp(header->parentsha1, nullsha1, sizeof(nullsha1)) == 0)
1953                         return CHDERR_INVALID_PARAMETER;
1954
1955                 /* if we're V3 or later, the obsolete fields must be 0 */
1956                 if (header->version >= 3 &&
1957                         (header->obsolete_cylinders != 0 || header->obsolete_sectors != 0 ||
1958                          header->obsolete_heads != 0 || header->obsolete_hunksize != 0))
1959                         return CHDERR_INVALID_PARAMETER;
1960
1961                 /* if we're pre-V3, the obsolete fields must NOT be 0 */
1962                 if (header->version < 3 &&
1963                         (header->obsolete_cylinders == 0 || header->obsolete_sectors == 0 ||
1964                          header->obsolete_heads == 0 || header->obsolete_hunksize == 0))
1965                         return CHDERR_INVALID_PARAMETER;
1966         }
1967
1968         return CHDERR_NONE;
1969 }
1970
1971 /*-------------------------------------------------
1972     header_guess_unitbytes - for older CHD formats,
1973     guess at the bytes/unit based on metadata
1974 -------------------------------------------------*/
1975
1976 static UINT32 header_guess_unitbytes(chd_file *chd)
1977 {
1978         /* look for hard disk metadata; if found, then the unit size == sector size */
1979         char metadata[512];
1980         int i0, i1, i2, i3;
1981         if (chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE &&
1982                 sscanf(metadata, HARD_DISK_METADATA_FORMAT, &i0, &i1, &i2, &i3) == 4)
1983                 return i3;
1984
1985         /* look for CD-ROM metadata; if found, then the unit size == CD frame size */
1986         if (chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1987                 chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1988                 chd_get_metadata(chd, CDROM_TRACK_METADATA2_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1989                 chd_get_metadata(chd, GDROM_OLD_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE ||
1990                 chd_get_metadata(chd, GDROM_TRACK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL) == CHDERR_NONE)
1991                 return CD_FRAME_SIZE;
1992
1993         /* otherwise, just map 1:1 with the hunk size */
1994         return chd->header.hunkbytes;
1995 }
1996
1997 /*-------------------------------------------------
1998     header_read - read a CHD header into the
1999     internal data structure
2000 -------------------------------------------------*/
2001
2002 static chd_error header_read(chd_file *chd, chd_header *header)
2003 {
2004         UINT8 rawheader[CHD_MAX_HEADER_SIZE];
2005         UINT32 count;
2006
2007         /* punt if NULL */
2008         if (header == NULL)
2009                 return CHDERR_INVALID_PARAMETER;
2010
2011         /* punt if invalid file */
2012         if (chd->file == NULL)
2013                 return CHDERR_INVALID_FILE;
2014
2015         /* seek and read */
2016         core_fseek(chd->file, 0, SEEK_SET);
2017         count = core_fread(chd->file, rawheader, sizeof(rawheader));
2018         if (count != sizeof(rawheader))
2019                 return CHDERR_READ_ERROR;
2020
2021         /* verify the tag */
2022         if (strncmp((char *)rawheader, "MComprHD", 8) != 0)
2023                 return CHDERR_INVALID_DATA;
2024
2025         /* extract the direct data */
2026         memset(header, 0, sizeof(*header));
2027         header->length        = get_bigendian_uint32(&rawheader[8]);
2028         header->version       = get_bigendian_uint32(&rawheader[12]);
2029
2030         /* make sure it's a version we understand */
2031         if (header->version == 0 || header->version > CHD_HEADER_VERSION)
2032                 return CHDERR_UNSUPPORTED_VERSION;
2033
2034         /* make sure the length is expected */
2035         if ((header->version == 1 && header->length != CHD_V1_HEADER_SIZE) ||
2036                 (header->version == 2 && header->length != CHD_V2_HEADER_SIZE) ||
2037                 (header->version == 3 && header->length != CHD_V3_HEADER_SIZE) ||
2038                 (header->version == 4 && header->length != CHD_V4_HEADER_SIZE) ||
2039                 (header->version == 5 && header->length != CHD_V5_HEADER_SIZE))
2040
2041                 return CHDERR_INVALID_DATA;
2042
2043         /* extract the common data */
2044         header->flags           = get_bigendian_uint32(&rawheader[16]);
2045         header->compression[0]  = get_bigendian_uint32(&rawheader[20]);
2046         header->compression[1]  = CHD_CODEC_NONE;
2047         header->compression[2]  = CHD_CODEC_NONE;
2048         header->compression[3]  = CHD_CODEC_NONE;
2049
2050         /* extract the V1/V2-specific data */
2051         if (header->version < 3)
2052         {
2053                 int seclen = (header->version == 1) ? CHD_V1_SECTOR_SIZE : get_bigendian_uint32(&rawheader[76]);
2054                 header->obsolete_hunksize  = get_bigendian_uint32(&rawheader[24]);
2055                 header->totalhunks         = get_bigendian_uint32(&rawheader[28]);
2056                 header->obsolete_cylinders = get_bigendian_uint32(&rawheader[32]);
2057                 header->obsolete_heads     = get_bigendian_uint32(&rawheader[36]);
2058                 header->obsolete_sectors   = get_bigendian_uint32(&rawheader[40]);
2059                 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2060                 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2061                 header->logicalbytes = (UINT64)header->obsolete_cylinders * (UINT64)header->obsolete_heads * (UINT64)header->obsolete_sectors * (UINT64)seclen;
2062                 header->hunkbytes = seclen * header->obsolete_hunksize;
2063                 header->unitbytes          = header_guess_unitbytes(chd);
2064                 header->unitcount          = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2065                 header->metaoffset = 0;
2066         }
2067
2068         /* extract the V3-specific data */
2069         else if (header->version == 3)
2070         {
2071                 header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2072                 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2073                 header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2074                 memcpy(header->md5, &rawheader[44], CHD_MD5_BYTES);
2075                 memcpy(header->parentmd5, &rawheader[60], CHD_MD5_BYTES);
2076                 header->hunkbytes    = get_bigendian_uint32(&rawheader[76]);
2077                 header->unitbytes    = header_guess_unitbytes(chd);
2078                 header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2079                 memcpy(header->sha1, &rawheader[80], CHD_SHA1_BYTES);
2080                 memcpy(header->parentsha1, &rawheader[100], CHD_SHA1_BYTES);
2081         }
2082
2083         /* extract the V4-specific data */
2084         else if (header->version == 4)
2085         {
2086                 header->totalhunks   = get_bigendian_uint32(&rawheader[24]);
2087                 header->logicalbytes = get_bigendian_uint64(&rawheader[28]);
2088                 header->metaoffset   = get_bigendian_uint64(&rawheader[36]);
2089                 header->hunkbytes    = get_bigendian_uint32(&rawheader[44]);
2090                 header->unitbytes    = header_guess_unitbytes(chd);
2091                 header->unitcount    = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2092                 memcpy(header->sha1, &rawheader[48], CHD_SHA1_BYTES);
2093                 memcpy(header->parentsha1, &rawheader[68], CHD_SHA1_BYTES);
2094                 memcpy(header->rawsha1, &rawheader[88], CHD_SHA1_BYTES);
2095         }
2096
2097         /* extract the V5-specific data */
2098         else if (header->version == 5)
2099         {
2100                 /* TODO */
2101                 header->compression[0]  = get_bigendian_uint32(&rawheader[16]);
2102                 header->compression[1]  = get_bigendian_uint32(&rawheader[20]);
2103                 header->compression[2]  = get_bigendian_uint32(&rawheader[24]);
2104                 header->compression[3]  = get_bigendian_uint32(&rawheader[28]);
2105                 header->logicalbytes    = get_bigendian_uint64(&rawheader[32]);
2106                 header->mapoffset       = get_bigendian_uint64(&rawheader[40]);
2107                 header->metaoffset      = get_bigendian_uint64(&rawheader[48]);
2108                 header->hunkbytes       = get_bigendian_uint32(&rawheader[56]);
2109                 header->hunkcount       = (header->logicalbytes + header->hunkbytes - 1) / header->hunkbytes;
2110                 header->unitbytes       = get_bigendian_uint32(&rawheader[60]);
2111                 header->unitcount       = (header->logicalbytes + header->unitbytes - 1) / header->unitbytes;
2112                 memcpy(header->sha1, &rawheader[84], CHD_SHA1_BYTES);
2113                 memcpy(header->parentsha1, &rawheader[104], CHD_SHA1_BYTES);
2114                 memcpy(header->rawsha1, &rawheader[64], CHD_SHA1_BYTES);
2115
2116                 /* determine properties of map entries */
2117                 header->mapentrybytes = chd_compressed(header) ? 12 : 4;
2118
2119                 /* hack */
2120                 header->totalhunks              = header->hunkcount;
2121         }
2122
2123         /* Unknown version */
2124         else
2125         {
2126                 /* TODO */
2127         }
2128
2129         /* guess it worked */
2130         return CHDERR_NONE;
2131 }
2132
2133 /***************************************************************************
2134     INTERNAL HUNK READ/WRITE
2135 ***************************************************************************/
2136
2137 /*-------------------------------------------------
2138     hunk_read_compressed - read a compressed
2139     hunk
2140 -------------------------------------------------*/
2141
2142 static UINT8* hunk_read_compressed(chd_file *chd, UINT64 offset, size_t size)
2143 {
2144 #ifdef _MSC_VER
2145         size_t bytes;
2146 #else
2147         ssize_t bytes;
2148 #endif
2149         if (chd->file_cache != NULL)
2150         {
2151                 return chd->file_cache + offset;
2152         }
2153         else
2154         {
2155                 core_fseek(chd->file, offset, SEEK_SET);
2156                 bytes = core_fread(chd->file, chd->compressed, size);
2157                 if (bytes != size)
2158                         return NULL;
2159                 return chd->compressed;
2160         }
2161 }
2162
2163 /*-------------------------------------------------
2164     hunk_read_uncompressed - read an uncompressed
2165     hunk
2166 -------------------------------------------------*/
2167
2168 static chd_error hunk_read_uncompressed(chd_file *chd, UINT64 offset, size_t size, UINT8 *dest)
2169 {
2170 #ifdef _MSC_VER
2171         size_t bytes;
2172 #else
2173         ssize_t bytes;
2174 #endif
2175         if (chd->file_cache != NULL)
2176         {
2177                 memcpy(dest, chd->file_cache + offset, size);
2178         }
2179         else
2180         {
2181                 core_fseek(chd->file, offset, SEEK_SET);
2182                 bytes = core_fread(chd->file, dest, size);
2183                 if (bytes != size)
2184                         return CHDERR_READ_ERROR;
2185         }
2186         return CHDERR_NONE;
2187 }
2188
2189 #ifdef NEED_CACHE_HUNK
2190 /*-------------------------------------------------
2191     hunk_read_into_cache - read a hunk into
2192     the CHD's hunk cache
2193 -------------------------------------------------*/
2194
2195 static chd_error hunk_read_into_cache(chd_file *chd, UINT32 hunknum)
2196 {
2197         chd_error err;
2198
2199         /* track the max */
2200         if (hunknum > chd->maxhunk)
2201                 chd->maxhunk = hunknum;
2202
2203         /* if we're already in the cache, we're done */
2204         if (chd->cachehunk == hunknum)
2205                 return CHDERR_NONE;
2206         chd->cachehunk = ~0;
2207
2208         /* otherwise, read the data */
2209         err = hunk_read_into_memory(chd, hunknum, chd->cache);
2210         if (err != CHDERR_NONE)
2211                 return err;
2212
2213         /* mark the hunk successfully cached in */
2214         chd->cachehunk = hunknum;
2215         return CHDERR_NONE;
2216 }
2217 #endif
2218
2219 /*-------------------------------------------------
2220     hunk_read_into_memory - read a hunk into
2221     memory at the given location
2222 -------------------------------------------------*/
2223
2224 static chd_error hunk_read_into_memory(chd_file *chd, UINT32 hunknum, UINT8 *dest)
2225 {
2226         chd_error err;
2227
2228         /* punt if no file */
2229         if (chd->file == NULL)
2230                 return CHDERR_INVALID_FILE;
2231
2232         /* return an error if out of range */
2233         if (hunknum >= chd->header.totalhunks)
2234                 return CHDERR_HUNK_OUT_OF_RANGE;
2235
2236         if (dest == NULL)
2237                 return CHDERR_INVALID_PARAMETER;
2238
2239         if (chd->header.version < 5)
2240         {
2241                 map_entry *entry = &chd->map[hunknum];
2242                 UINT32 bytes;
2243                 UINT8* compressed_bytes;
2244
2245                 /* switch off the entry type */
2246                 switch (entry->flags & MAP_ENTRY_FLAG_TYPE_MASK)
2247                 {
2248                         /* compressed data */
2249                         case V34_MAP_ENTRY_TYPE_COMPRESSED:
2250             {
2251                void *codec = NULL;
2252
2253                                 /* read it into the decompression buffer */
2254                                 compressed_bytes = hunk_read_compressed(chd, entry->offset, entry->length);
2255                                 if (compressed_bytes == NULL)
2256                                         return CHDERR_READ_ERROR;
2257
2258                                 /* now decompress using the codec */
2259                                 err = CHDERR_NONE;
2260                                 codec = &chd->zlib_codec_data;
2261                                 if (chd->codecintf[0]->decompress != NULL)
2262                                         err = (*chd->codecintf[0]->decompress)(codec, compressed_bytes, entry->length, dest, chd->header.hunkbytes);
2263                                 if (err != CHDERR_NONE)
2264                                         return err;
2265                                 break;
2266                         }
2267
2268                         /* uncompressed data */
2269                         case V34_MAP_ENTRY_TYPE_UNCOMPRESSED:
2270                                 err = hunk_read_uncompressed(chd, entry->offset, chd->header.hunkbytes, dest);
2271                                 if (err != CHDERR_NONE)
2272                                         return err;
2273                                 break;
2274
2275                         /* mini-compressed data */
2276                         case V34_MAP_ENTRY_TYPE_MINI:
2277                                 put_bigendian_uint64(&dest[0], entry->offset);
2278                                 for (bytes = 8; bytes < chd->header.hunkbytes; bytes++)
2279                                         dest[bytes] = dest[bytes - 8];
2280                                 break;
2281
2282                         /* self-referenced data */
2283                         case V34_MAP_ENTRY_TYPE_SELF_HUNK:
2284 #ifdef NEED_CACHE_HUNK
2285                                 if (chd->cachehunk == entry->offset && dest == chd->cache)
2286                                         break;
2287 #endif
2288                                 return hunk_read_into_memory(chd, entry->offset, dest);
2289
2290                         /* parent-referenced data */
2291                         case V34_MAP_ENTRY_TYPE_PARENT_HUNK:
2292                                 err = hunk_read_into_memory(chd->parent, entry->offset, dest);
2293                                 if (err != CHDERR_NONE)
2294                                         return err;
2295                                 break;
2296                 }
2297                 return CHDERR_NONE;
2298         }
2299         else
2300         {
2301                 void* codec = NULL;
2302                 /* get a pointer to the map entry */
2303                 uint64_t blockoffs;
2304                 uint32_t blocklen;
2305 #ifdef VERIFY_BLOCK_CRC
2306                 uint16_t blockcrc;
2307 #endif
2308                 uint8_t *rawmap = &chd->header.rawmap[chd->header.mapentrybytes * hunknum];
2309                 UINT8* compressed_bytes;
2310
2311                 /* uncompressed case */
2312                 if (!chd_compressed(&chd->header))
2313                 {
2314                         blockoffs = (uint64_t)get_bigendian_uint32(rawmap) * (uint64_t)chd->header.hunkbytes;
2315                         if (blockoffs != 0) {
2316                                 core_fseek(chd->file, blockoffs, SEEK_SET);
2317                                 int result = core_fread(chd->file, dest, chd->header.hunkbytes);
2318                         /* TODO
2319                         else if (m_parent_missing)
2320                                 throw CHDERR_REQUIRES_PARENT; */
2321                         } else if (chd->parent) {
2322                                 err = hunk_read_into_memory(chd->parent, hunknum, dest);
2323                                 if (err != CHDERR_NONE)
2324                                         return err;
2325                         } else {
2326                                 memset(dest, 0, chd->header.hunkbytes);
2327                         }
2328
2329                         return CHDERR_NONE;
2330                 }
2331
2332                 /* compressed case */
2333                 blocklen = get_bigendian_uint24(&rawmap[1]);
2334                 blockoffs = get_bigendian_uint48(&rawmap[4]);
2335 #ifdef VERIFY_BLOCK_CRC
2336                 blockcrc = get_bigendian_uint16(&rawmap[10]);
2337 #endif
2338                 codec = NULL;
2339                 switch (rawmap[0])
2340                 {
2341                         case COMPRESSION_TYPE_0:
2342                         case COMPRESSION_TYPE_1:
2343                         case COMPRESSION_TYPE_2:
2344                         case COMPRESSION_TYPE_3:
2345                                 compressed_bytes = hunk_read_compressed(chd, blockoffs, blocklen);
2346                                 if (compressed_bytes == NULL)
2347                                         return CHDERR_READ_ERROR;
2348                                 switch (chd->codecintf[rawmap[0]]->compression)
2349                                 {
2350                                         case CHD_CODEC_CD_LZMA:
2351                                                 codec = &chd->cdlz_codec_data;
2352                                                 break;
2353
2354                                         case CHD_CODEC_ZLIB:
2355                                                 codec = &chd->zlib_codec_data;
2356                                                 break;
2357
2358                                         case CHD_CODEC_CD_ZLIB:
2359                                                 codec = &chd->cdzl_codec_data;
2360                                                 break;
2361
2362                                         case CHD_CODEC_CD_FLAC:
2363                                                 codec = &chd->cdfl_codec_data;
2364                                                 break;
2365                                 }
2366                                 if (codec==NULL)
2367                                         return CHDERR_CODEC_ERROR;
2368                                 err = chd->codecintf[rawmap[0]]->decompress(codec, compressed_bytes, blocklen, dest, chd->header.hunkbytes);
2369                                 if (err != CHDERR_NONE)
2370                                         return err;
2371 #ifdef VERIFY_BLOCK_CRC
2372                                 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2373                                         return CHDERR_DECOMPRESSION_ERROR;
2374 #endif
2375                                 return CHDERR_NONE;
2376
2377                         case COMPRESSION_NONE:
2378                                 err = hunk_read_uncompressed(chd, blockoffs, blocklen, dest);
2379                                 if (err != CHDERR_NONE)
2380                                         return err;
2381 #ifdef VERIFY_BLOCK_CRC
2382                                 if (crc16(dest, chd->header.hunkbytes) != blockcrc)
2383                                         return CHDERR_DECOMPRESSION_ERROR;
2384 #endif
2385                                 return CHDERR_NONE;
2386
2387                         case COMPRESSION_SELF:
2388                                 return hunk_read_into_memory(chd, blockoffs, dest);
2389
2390                         case COMPRESSION_PARENT:
2391                                 if (chd->parent == NULL)
2392                                         return CHDERR_REQUIRES_PARENT;
2393                                 UINT8 units_in_hunk = chd->header.hunkbytes / chd->header.unitbytes;
2394
2395                                 /* blockoffs is aligned to units_in_hunk */
2396                                 if (blockoffs % units_in_hunk == 0) {
2397                                         return hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, dest);
2398                                 /* blockoffs is not aligned to units_in_hunk */
2399                                 } else {
2400                                         UINT32 unit_in_hunk = blockoffs % units_in_hunk;
2401                                         UINT8 *buf = malloc(chd->header.hunkbytes);
2402                                         /* Read first half of hunk which contains blockoffs */
2403                                         err = hunk_read_into_memory(chd->parent, blockoffs / units_in_hunk, buf);
2404                                         if (err != CHDERR_NONE) {
2405                                                 free(buf);
2406                                                 return err;
2407                                         }
2408                                         memcpy(dest, buf + unit_in_hunk * chd->header.unitbytes, (units_in_hunk - unit_in_hunk) * chd->header.unitbytes);
2409                                         /* Read second half of hunk which contains blockoffs */
2410                                         err = hunk_read_into_memory(chd->parent, (blockoffs / units_in_hunk) + 1, buf);
2411                                         if (err != CHDERR_NONE) {
2412                                                 free(buf);
2413                                                 return err;
2414                                         }
2415                                         memcpy(dest + (units_in_hunk - unit_in_hunk) * chd->header.unitbytes, buf, unit_in_hunk * chd->header.unitbytes);
2416                                         free(buf);
2417                                 }
2418                 }
2419                 return CHDERR_NONE;
2420         }
2421
2422         /* We should not reach this code */
2423         return CHDERR_DECOMPRESSION_ERROR;
2424 }
2425
2426 /***************************************************************************
2427     INTERNAL MAP ACCESS
2428 ***************************************************************************/
2429
2430 /*-------------------------------------------------
2431     map_read - read the initial sector map
2432 -------------------------------------------------*/
2433
2434 static chd_error map_read(chd_file *chd)
2435 {
2436         UINT32 entrysize = (chd->header.version < 3) ? OLD_MAP_ENTRY_SIZE : MAP_ENTRY_SIZE;
2437         UINT8 raw_map_entries[MAP_STACK_ENTRIES * MAP_ENTRY_SIZE];
2438         UINT64 fileoffset, maxoffset = 0;
2439         UINT8 cookie[MAP_ENTRY_SIZE];
2440         UINT32 count;
2441         chd_error err;
2442         int i;
2443
2444         /* first allocate memory */
2445         chd->map = (map_entry *)malloc(sizeof(chd->map[0]) * chd->header.totalhunks);
2446         if (!chd->map)
2447                 return CHDERR_OUT_OF_MEMORY;
2448
2449         /* read the map entries in in chunks and extract to the map list */
2450         fileoffset = chd->header.length;
2451         for (i = 0; i < chd->header.totalhunks; i += MAP_STACK_ENTRIES)
2452         {
2453                 /* compute how many entries this time */
2454                 int entries = chd->header.totalhunks - i, j;
2455                 if (entries > MAP_STACK_ENTRIES)
2456                         entries = MAP_STACK_ENTRIES;
2457
2458                 /* read that many */
2459                 core_fseek(chd->file, fileoffset, SEEK_SET);
2460                 count = core_fread(chd->file, raw_map_entries, entries * entrysize);
2461                 if (count != entries * entrysize)
2462                 {
2463                         err = CHDERR_READ_ERROR;
2464                         goto cleanup;
2465                 }
2466                 fileoffset += entries * entrysize;
2467
2468                 /* process that many */
2469                 if (entrysize == MAP_ENTRY_SIZE)
2470                 {
2471                         for (j = 0; j < entries; j++)
2472                                 map_extract(&raw_map_entries[j * MAP_ENTRY_SIZE], &chd->map[i + j]);
2473                 }
2474                 else
2475                 {
2476                         for (j = 0; j < entries; j++)
2477                                 map_extract_old(&raw_map_entries[j * OLD_MAP_ENTRY_SIZE], &chd->map[i + j], chd->header.hunkbytes);
2478                 }
2479
2480                 /* track the maximum offset */
2481                 for (j = 0; j < entries; j++)
2482                         if ((chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_COMPRESSED ||
2483                                 (chd->map[i + j].flags & MAP_ENTRY_FLAG_TYPE_MASK) == V34_MAP_ENTRY_TYPE_UNCOMPRESSED)
2484                                 maxoffset = MAX(maxoffset, chd->map[i + j].offset + chd->map[i + j].length);
2485         }
2486
2487         /* verify the cookie */
2488         core_fseek(chd->file, fileoffset, SEEK_SET);
2489         count = core_fread(chd->file, &cookie, entrysize);
2490         if (count != entrysize || memcmp(&cookie, END_OF_LIST_COOKIE, entrysize))
2491         {
2492                 err = CHDERR_INVALID_FILE;
2493                 goto cleanup;
2494         }
2495
2496         /* verify the length */
2497         if (maxoffset > core_fsize(chd->file))
2498         {
2499                 err = CHDERR_INVALID_FILE;
2500                 goto cleanup;
2501         }
2502         return CHDERR_NONE;
2503
2504 cleanup:
2505         if (chd->map)
2506                 free(chd->map);
2507         chd->map = NULL;
2508         return err;
2509 }
2510
2511 /***************************************************************************
2512     INTERNAL METADATA ACCESS
2513 ***************************************************************************/
2514
2515 /*-------------------------------------------------
2516     metadata_find_entry - find a metadata entry
2517 -------------------------------------------------*/
2518
2519 static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metaindex, metadata_entry *metaentry)
2520 {
2521         /* start at the beginning */
2522         metaentry->offset = chd->header.metaoffset;
2523         metaentry->prev = 0;
2524
2525         /* loop until we run out of options */
2526         while (metaentry->offset != 0)
2527         {
2528                 UINT8   raw_meta_header[METADATA_HEADER_SIZE];
2529                 UINT32  count;
2530
2531                 /* read the raw header */
2532                 core_fseek(chd->file, metaentry->offset, SEEK_SET);
2533                 count = core_fread(chd->file, raw_meta_header, sizeof(raw_meta_header));
2534                 if (count != sizeof(raw_meta_header))
2535                         break;
2536
2537                 /* extract the data */
2538                 metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]);
2539                 metaentry->length = get_bigendian_uint32(&raw_meta_header[4]);
2540                 metaentry->next = get_bigendian_uint64(&raw_meta_header[8]);
2541
2542                 /* flags are encoded in the high byte of length */
2543                 metaentry->flags = metaentry->length >> 24;
2544                 metaentry->length &= 0x00ffffff;
2545
2546                 /* if we got a match, proceed */
2547                 if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag)
2548                         if (metaindex-- == 0)
2549                                 return CHDERR_NONE;
2550
2551                 /* no match, fetch the next link */
2552                 metaentry->prev = metaentry->offset;
2553                 metaentry->offset = metaentry->next;
2554         }
2555
2556         /* if we get here, we didn't find it */
2557         return CHDERR_METADATA_NOT_FOUND;
2558 }
2559
2560 /***************************************************************************
2561     ZLIB COMPRESSION CODEC
2562 ***************************************************************************/
2563
2564 /*-------------------------------------------------
2565     zlib_codec_init - initialize the ZLIB codec
2566 -------------------------------------------------*/
2567
2568 static chd_error zlib_codec_init(void *codec, uint32_t hunkbytes)
2569 {
2570         int zerr;
2571         chd_error err;
2572         zlib_codec_data *data = (zlib_codec_data*)codec;
2573
2574         /* clear the buffers */
2575         memset(data, 0, sizeof(zlib_codec_data));
2576
2577         /* init the inflater first */
2578         data->inflater.next_in = (Bytef *)data; /* bogus, but that's ok */
2579         data->inflater.avail_in = 0;
2580         data->inflater.zalloc = zlib_fast_alloc;
2581         data->inflater.zfree = zlib_fast_free;
2582         data->inflater.opaque = &data->allocator;
2583         zerr = inflateInit2(&data->inflater, -MAX_WBITS);
2584
2585         /* convert errors */
2586         if (zerr == Z_MEM_ERROR)
2587                 err = CHDERR_OUT_OF_MEMORY;
2588         else if (zerr != Z_OK)
2589                 err = CHDERR_CODEC_ERROR;
2590         else
2591                 err = CHDERR_NONE;
2592
2593         /* handle an error */
2594         if (err != CHDERR_NONE)
2595                 free(data);
2596
2597         return err;
2598 }
2599
2600 /*-------------------------------------------------
2601     zlib_codec_free - free data for the ZLIB
2602     codec
2603 -------------------------------------------------*/
2604
2605 static void zlib_codec_free(void *codec)
2606 {
2607         zlib_codec_data *data = (zlib_codec_data *)codec;
2608
2609         /* deinit the streams */
2610         if (data != NULL)
2611         {
2612                 int i;
2613
2614                 inflateEnd(&data->inflater);
2615
2616                 /* free our fast memory */
2617                 zlib_allocator_free(&data->allocator);
2618         }
2619 }
2620
2621 /*-------------------------------------------------
2622     zlib_codec_decompress - decompress data using
2623     the ZLIB codec
2624 -------------------------------------------------*/
2625
2626 static chd_error zlib_codec_decompress(void *codec, const uint8_t *src, uint32_t complen, uint8_t *dest, uint32_t destlen)
2627 {
2628         zlib_codec_data *data = (zlib_codec_data *)codec;
2629         int zerr;
2630
2631         /* reset the decompressor */
2632         data->inflater.next_in = (Bytef *)src;
2633         data->inflater.avail_in = complen;
2634         data->inflater.total_in = 0;
2635         data->inflater.next_out = (Bytef *)dest;
2636         data->inflater.avail_out = destlen;
2637         data->inflater.total_out = 0;
2638         zerr = inflateReset(&data->inflater);
2639         if (zerr != Z_OK)
2640                 return CHDERR_DECOMPRESSION_ERROR;
2641
2642         /* do it */
2643         zerr = inflate(&data->inflater, Z_FINISH);
2644         if (data->inflater.total_out != destlen)
2645                 return CHDERR_DECOMPRESSION_ERROR;
2646
2647         return CHDERR_NONE;
2648 }
2649
2650 /*-------------------------------------------------
2651     zlib_fast_alloc - fast malloc for ZLIB, which
2652     allocates and frees memory frequently
2653 -------------------------------------------------*/
2654
2655 /* Huge alignment values for possible SIMD optimization by compiler (NEON, SSE, AVX) */
2656 #define ZLIB_MIN_ALIGNMENT_BITS 512
2657 #define ZLIB_MIN_ALIGNMENT_BYTES (ZLIB_MIN_ALIGNMENT_BITS / 8)
2658
2659 static voidpf zlib_fast_alloc(voidpf opaque, uInt items, uInt size)
2660 {
2661         zlib_allocator *alloc = (zlib_allocator *)opaque;
2662         uintptr_t paddr = 0;
2663         UINT32 *ptr;
2664         int i;
2665
2666         /* compute the size, rounding to the nearest 1k */
2667         size = (size * items + 0x3ff) & ~0x3ff;
2668
2669         /* reuse a hunk if we can */
2670         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2671         {
2672                 ptr = alloc->allocptr[i];
2673                 if (ptr && size == *ptr)
2674                 {
2675                         /* set the low bit of the size so we don't match next time */
2676                         *ptr |= 1;
2677
2678                         /* return aligned block address */
2679                         return (voidpf)(alloc->allocptr2[i]);
2680                 }
2681         }
2682
2683         /* alloc a new one */
2684     ptr = (UINT32 *)malloc(size + sizeof(UINT32) + ZLIB_MIN_ALIGNMENT_BYTES);
2685         if (!ptr)
2686                 return NULL;
2687
2688         /* put it into the list */
2689         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2690                 if (!alloc->allocptr[i])
2691                 {
2692                         alloc->allocptr[i] = ptr;
2693                         paddr = (((uintptr_t)ptr) + sizeof(UINT32) + (ZLIB_MIN_ALIGNMENT_BYTES-1)) & (~(ZLIB_MIN_ALIGNMENT_BYTES-1));
2694                         alloc->allocptr2[i] = (uint32_t*)paddr;
2695                         break;
2696                 }
2697
2698         /* set the low bit of the size so we don't match next time */
2699         *ptr = size | 1;
2700
2701         /* return aligned block address */
2702         return (voidpf)paddr;
2703 }
2704
2705 /*-------------------------------------------------
2706     zlib_fast_free - fast free for ZLIB, which
2707     allocates and frees memory frequently
2708 -------------------------------------------------*/
2709
2710 static void zlib_fast_free(voidpf opaque, voidpf address)
2711 {
2712         zlib_allocator *alloc = (zlib_allocator *)opaque;
2713         UINT32 *ptr = (UINT32 *)address;
2714         int i;
2715
2716         /* find the hunk */
2717         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2718                 if (ptr == alloc->allocptr2[i])
2719                 {
2720                         /* clear the low bit of the size to allow matches */
2721                         *(alloc->allocptr[i]) &= ~1;
2722                         return;
2723                 }
2724 }
2725
2726 /*-------------------------------------------------
2727     zlib_allocator_free
2728 -------------------------------------------------*/
2729 static void zlib_allocator_free(voidpf opaque)
2730 {
2731         zlib_allocator *alloc = (zlib_allocator *)opaque;
2732         int i;
2733
2734         for (i = 0; i < MAX_ZLIB_ALLOCS; i++)
2735                 if (alloc->allocptr[i])
2736                         free(alloc->allocptr[i]);
2737 }