diff options
author | 2009-03-05 07:35:24 +0000 | |
---|---|---|
committer | 2009-03-05 07:35:24 +0000 | |
commit | e8c09b35f6217060b4bd3f5f437585270b2faa3f (patch) | |
tree | 9ac04f6b86bacf00d191dfdff5a8a7316dc367a4 | |
parent | 6a0e1fcfe0f298a5ed87c044ece43aadd1429a85 (diff) |
Added flags to the metadata entries, encoded in the top bit. Right now
it is a no-op, but eventually will be used to indicate which bits of
metadata are included in the overall checksum.
-rw-r--r-- | src/emu/machine/ldcore.c | 4 | ||||
-rw-r--r-- | src/lib/util/cdrom.c | 4 | ||||
-rw-r--r-- | src/lib/util/chd.c | 33 | ||||
-rw-r--r-- | src/lib/util/chd.h | 24 | ||||
-rw-r--r-- | src/lib/util/harddisk.c | 2 | ||||
-rw-r--r-- | src/tools/chdman.c | 24 | ||||
-rw-r--r-- | src/tools/ldresample.c | 2 | ||||
-rw-r--r-- | src/tools/ldverify.c | 2 |
8 files changed, 65 insertions, 30 deletions
diff --git a/src/emu/machine/ldcore.c b/src/emu/machine/ldcore.c index 76f6bc1e493..8d1359b2527 100644 --- a/src/emu/machine/ldcore.c +++ b/src/emu/machine/ldcore.c @@ -1331,7 +1331,7 @@ static void init_disc(const device_config *device) fatalerror("Laserdisc video must be compressed with the A/V codec!"); /* read the metadata */ - err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(ldcore->disc, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) fatalerror("Non-A/V CHD file specified"); @@ -1350,7 +1350,7 @@ static void init_disc(const device_config *device) /* allocate memory for the precomputed per-frame metadata */ ldcore->vbidata = auto_malloc(totalhunks * VBI_PACKED_BYTES); - err = chd_get_metadata(ldcore->disc, AV_LD_METADATA_TAG, 0, ldcore->vbidata, totalhunks * VBI_PACKED_BYTES, &vbilength, NULL); + err = chd_get_metadata(ldcore->disc, AV_LD_METADATA_TAG, 0, ldcore->vbidata, totalhunks * VBI_PACKED_BYTES, &vbilength, NULL, NULL); if (err != CHDERR_NONE || vbilength != totalhunks * VBI_PACKED_BYTES) fatalerror("Precomputed VBI metadata missing or incorrect size"); } diff --git a/src/lib/util/cdrom.c b/src/lib/util/cdrom.c index 152c73cea4a..a2aa3629a74 100644 --- a/src/lib/util/cdrom.c +++ b/src/lib/util/cdrom.c @@ -549,7 +549,7 @@ static chd_error parse_metadata(chd_file *chd, cdrom_toc *toc) char type[11], subtype[11]; /* fetch the metadata for this track */ - err = chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, CDROM_TRACK_METADATA_TAG, toc->numtrks, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) break; @@ -583,7 +583,7 @@ static chd_error parse_metadata(chd_file *chd, cdrom_toc *toc) return CHDERR_NONE; /* look for old-style metadata */ - err = chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, oldmetadata, sizeof(oldmetadata), NULL, NULL); + err = chd_get_metadata(chd, CDROM_OLD_METADATA_TAG, 0, oldmetadata, sizeof(oldmetadata), NULL, NULL, NULL); if (err != CHDERR_NONE) return err; diff --git a/src/lib/util/chd.c b/src/lib/util/chd.c index b8881bae8fb..daea5b41623 100644 --- a/src/lib/util/chd.c +++ b/src/lib/util/chd.c @@ -114,6 +114,7 @@ struct _metadata_entry UINT64 prev; /* offset within the file of the previous header */ UINT32 length; /* length of the metadata */ UINT32 metatag; /* metadata tag */ + UINT8 flags; /* flag bits */ }; @@ -1120,7 +1121,7 @@ chd_error chd_async_complete(chd_file *chd) of the given type -------------------------------------------------*/ -chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag) +chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags) { metadata_entry metaentry; chd_error err; @@ -1168,6 +1169,8 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, *resultlen = metaentry.length; if (resulttag != NULL) *resulttag = metaentry.metatag; + if (resultflags != NULL) + *resultflags = metaentry.flags; return CHDERR_NONE; } @@ -1177,7 +1180,7 @@ chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, of the given type -------------------------------------------------*/ -chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen) +chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen, UINT8 flags) { UINT8 raw_meta_header[METADATA_HEADER_SIZE]; metadata_entry metaentry; @@ -1196,6 +1199,10 @@ chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, cons /* must write at least 1 byte */ if (inputlen < 1) return CHDERR_INVALID_PARAMETER; + + /* no more than 16MB */ + if (inputlen >= 16 * 1024 * 1024) + return CHDERR_INVALID_PARAMETER; /* wait for any pending async operations */ wait_for_pending_async(chd); @@ -1232,7 +1239,7 @@ chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, cons /* now build us a new entry */ put_bigendian_uint32(&raw_meta_header[0], metatag); - put_bigendian_uint32(&raw_meta_header[4], inputlen); + put_bigendian_uint32(&raw_meta_header[4], (inputlen & 0x00ffffff) | (flags << 24)); put_bigendian_uint64(&raw_meta_header[8], (err == CHDERR_NONE) ? metaentry.next : 0); /* write out the new header */ @@ -1266,13 +1273,14 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest) { UINT32 metatag, metasize, metaindex; UINT8 metabuffer[1024]; + UINT8 metaflags; chd_error err; /* clone the metadata */ for (metaindex = 0; ; metaindex++) { /* fetch the next piece of metadata */ - err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, metabuffer, sizeof(metabuffer), &metasize, &metatag); + err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, metabuffer, sizeof(metabuffer), &metasize, &metatag, &metaflags); if (err != CHDERR_NONE) { if (err == CHDERR_METADATA_NOT_FOUND) @@ -1284,7 +1292,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest) if (metasize <= sizeof(metabuffer)) { /* write it to the target */ - err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, metabuffer, metasize); + err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, metabuffer, metasize, metaflags); if (err != CHDERR_NONE) break; } @@ -1300,7 +1308,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest) } /* re-read the whole thing */ - err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, allocbuffer, metasize, &metasize, &metatag); + err = chd_get_metadata(source, CHDMETATAG_WILDCARD, metaindex, allocbuffer, metasize, &metasize, &metatag, &metaflags); if (err != CHDERR_NONE) { free(allocbuffer); @@ -1308,7 +1316,7 @@ chd_error chd_clone_metadata(chd_file *source, chd_file *dest) } /* write it to the target */ - err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, allocbuffer, metasize); + err = chd_set_metadata(dest, metatag, CHD_METAINDEX_APPEND, allocbuffer, metasize, metaflags); free(allocbuffer); if (err != CHDERR_NONE) break; @@ -2364,6 +2372,10 @@ static chd_error metadata_find_entry(chd_file *chd, UINT32 metatag, UINT32 metai metaentry->metatag = get_bigendian_uint32(&raw_meta_header[0]); metaentry->length = get_bigendian_uint32(&raw_meta_header[4]); metaentry->next = get_bigendian_uint64(&raw_meta_header[8]); + + /* checksum is encoded as the high bit of length */ + metaentry->flags = metaentry->length >> 24; + metaentry->length &= 0x00ffffff; /* if we got a match, proceed */ if (metatag == CHDMETATAG_WILDCARD || metaentry->metatag == metatag) @@ -2431,6 +2443,7 @@ static chd_error metadata_set_previous_next(chd_file *chd, UINT64 prevoffset, UI static chd_error metadata_set_length(chd_file *chd, UINT64 offset, UINT32 length) { UINT8 raw_meta_header[METADATA_HEADER_SIZE]; + UINT32 oldlength; UINT32 count; /* read the raw header */ @@ -2439,7 +2452,9 @@ static chd_error metadata_set_length(chd_file *chd, UINT64 offset, UINT32 length if (count != sizeof(raw_meta_header)) return CHDERR_READ_ERROR; - /* update the length at offset 4 */ + /* update the length at offset 4, preserving the flags in the upper byte */ + oldlength = get_bigendian_uint32(&raw_meta_header[4]); + length = (length & 0x00ffffff) | (oldlength & 0xff000000); put_bigendian_uint32(&raw_meta_header[4], length); /* write the raw header */ @@ -2867,7 +2882,7 @@ static chd_error av_codec_postinit(chd_file *chd) return CHDERR_OPERATION_PENDING; /* get the metadata */ - err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) return err; diff --git a/src/lib/util/chd.h b/src/lib/util/chd.h index d8c74dca5d9..e204cc74357 100644 --- a/src/lib/util/chd.h +++ b/src/lib/util/chd.h @@ -76,6 +76,23 @@ [100] UINT8 parentsha1[20];// SHA1 checksum of parent file [120] (V3 header length) + Proposed V4 header: + + [ 0] char tag[8]; // 'MComprHD' + [ 8] UINT32 length; // length of header (including tag and length fields) + [ 12] UINT32 version; // drive format version + [ 16] UINT32 flags; // flags (see below) + [ 20] UINT32 compression; // compression type + [ 24] UINT32 totalhunks; // total # of hunks represented + [ 28] UINT64 logicalbytes; // logical size of the data (in bytes) + [ 36] UINT64 metaoffset; // offset to the first blob of metadata + [ 44] UINT32 hunkbytes; // number of bytes per hunk + [ 48] UINT8 sha1[20]; // combined raw+meta SHA1 + [ 68] UINT8 parentsha1[20];// combined raw+meta SHA1 of parent + [ 88] UINT8 rawsha1[20]; // raw data SHA1 + [108] UINT8 metasha1[20]; // metadata SHA1 + [128] (V4 header length) + Flags: 0x00000001 - set if this drive has a parent 0x00000002 - set if this drive allows writes @@ -117,6 +134,9 @@ #define CHDMETATAG_WILDCARD 0 #define CHD_METAINDEX_APPEND ((UINT32)-1) +/* metadata flags */ +#define CHD_MDFLAGS_CHECKSUM 0x01 /* indicates data is checksummed */ + /* standard hard disk metadata */ #define HARD_DISK_METADATA_TAG 0x47444444 /* 'GDDD' */ #define HARD_DISK_METADATA_FORMAT "CYLS:%d,HEADS:%d,SECS:%d,BPS:%d" @@ -271,10 +291,10 @@ chd_error chd_async_complete(chd_file *chd); /* ----- metadata management ----- */ /* get indexed metadata of a particular sort */ -chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag); +chd_error chd_get_metadata(chd_file *chd, UINT32 searchtag, UINT32 searchindex, void *output, UINT32 outputlen, UINT32 *resultlen, UINT32 *resulttag, UINT8 *resultflags); /* set indexed metadata of a particular sort */ -chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen); +chd_error chd_set_metadata(chd_file *chd, UINT32 metatag, UINT32 metaindex, const void *inputbuf, UINT32 inputlen, UINT8 flags); /* clone all of the metadata from one CHD to another */ chd_error chd_clone_metadata(chd_file *source, chd_file *dest); diff --git a/src/lib/util/harddisk.c b/src/lib/util/harddisk.c index 97e18a99929..ed18465b9fc 100644 --- a/src/lib/util/harddisk.c +++ b/src/lib/util/harddisk.c @@ -49,7 +49,7 @@ hard_disk_file *hard_disk_open(chd_file *chd) return NULL; /* read the hard disk metadata */ - err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) return NULL; diff --git a/src/tools/chdman.c b/src/tools/chdman.c index ffc0e63352d..b1662debb6f 100644 --- a/src/tools/chdman.c +++ b/src/tools/chdman.c @@ -309,7 +309,7 @@ static int do_createhd(int argc, char *argv[], int param) /* write the metadata */ sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); - err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1); + err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding hard disk metadata: %s\n", chd_error_string(err)); @@ -480,7 +480,7 @@ static int do_createcd(int argc, char *argv[], int param) sprintf(metadata, CDROM_TRACK_METADATA_FORMAT, i + 1, cdrom_get_type_string(&toc.tracks[i]), cdrom_get_subtype_string(&toc.tracks[i]), toc.tracks[i].frames); - err = chd_set_metadata(chd, CDROM_TRACK_METADATA_TAG, i, metadata, strlen(metadata) + 1); + err = chd_set_metadata(chd, CDROM_TRACK_METADATA_TAG, i, metadata, strlen(metadata) + 1, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding CD-ROM metadata: %s\n", chd_error_string(err)); @@ -902,7 +902,7 @@ static int do_createav(int argc, char *argv[], int param) /* write the metadata */ sprintf(metadata, AV_METADATA_FORMAT, fps_times_1million / 1000000, fps_times_1million % 1000000, width, height, interlaced, channels, rate); - err = chd_set_metadata(chd, AV_METADATA_TAG, 0, metadata, strlen(metadata) + 1); + err = chd_set_metadata(chd, AV_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding AV metadata: %s\n", chd_error_string(err)); @@ -959,7 +959,7 @@ static int do_createav(int argc, char *argv[], int param) /* write the final metadata */ if (ldframedata != NULL) { - err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, ldframedata, numframes * VBI_PACKED_BYTES); + err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, ldframedata, numframes * VBI_PACKED_BYTES, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding AVLD metadata: %s\n", chd_error_string(err)); @@ -1048,7 +1048,7 @@ static int do_createblankhd(int argc, char *argv[], int param) /* write the metadata */ sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); - err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1); + err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding hard disk metadata: %s\n", chd_error_string(err)); @@ -1478,7 +1478,7 @@ static int do_extractav(int argc, char *argv[], int param) header = chd_get_header(chd); /* get the metadata */ - err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) { fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(err)); @@ -1806,7 +1806,7 @@ static int do_fixavdata(int argc, char *argv[], int param) header = *chd_get_header(chd); /* get the metadata */ - err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE) { fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(err)); @@ -1849,7 +1849,7 @@ static int do_fixavdata(int argc, char *argv[], int param) } /* read the metadata */ - err = chd_get_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, &actlength, NULL); + err = chd_get_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, &actlength, NULL, NULL); if (err != CHDERR_NONE) { fprintf(stderr, "Error getting VBI metadata: %s\n", chd_error_string(err)); @@ -1967,7 +1967,7 @@ static int do_fixavdata(int argc, char *argv[], int param) } /* write new metadata */ - err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES); + err = chd_set_metadata(chd, AV_LD_METADATA_TAG, 0, vbidata, header.totalhunks * VBI_PACKED_BYTES, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error adding AVLD metadata: %s\n", chd_error_string(err)); @@ -2071,7 +2071,7 @@ static int do_info(int argc, char *argv[], int param) UINT32 metatag, metasize; /* get the indexed metadata item; stop when we hit an error */ - err = chd_get_metadata(chd, CHDMETATAG_WILDCARD, i, metadata, sizeof(metadata), &metasize, &metatag); + err = chd_get_metadata(chd, CHDMETATAG_WILDCARD, i, metadata, sizeof(metadata), &metasize, &metatag, NULL); if (err != CHDERR_NONE) break; @@ -2484,7 +2484,7 @@ static int do_setchs(int argc, char *argv[], int param) } /* get the hard disk metadata */ - err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + err = chd_get_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (err != CHDERR_NONE || sscanf(metadata, HARD_DISK_METADATA_FORMAT, &oldcyls, &oldhds, &oldsecs, &oldsecsize) != 4) { fprintf(stderr, "CHD file '%s' is not a hard disk!\n", inoutfile); @@ -2494,7 +2494,7 @@ static int do_setchs(int argc, char *argv[], int param) /* write our own */ sprintf(metadata, HARD_DISK_METADATA_FORMAT, cyls, hds, secs, oldsecsize); - err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1); + err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1, 0); if (err != CHDERR_NONE) { fprintf(stderr, "Error writing new metadata to CHD file: %s\n", chd_error_string(err)); diff --git a/src/tools/ldresample.c b/src/tools/ldresample.c index 8950cd7727e..6ec450ca651 100644 --- a/src/tools/ldresample.c +++ b/src/tools/ldresample.c @@ -177,7 +177,7 @@ static chd_file *open_chd(const char *filename, movie_info *info) } /* get the metadata */ - chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (chderr != CHDERR_NONE) { fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr)); diff --git a/src/tools/ldverify.c b/src/tools/ldverify.c index dcf769c6aea..1e52ab53128 100644 --- a/src/tools/ldverify.c +++ b/src/tools/ldverify.c @@ -179,7 +179,7 @@ static void *open_chd(const char *filename, movie_info *info) } /* get the metadata */ - chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL); + chderr = chd_get_metadata(chd, AV_METADATA_TAG, 0, metadata, sizeof(metadata), NULL, NULL, NULL); if (chderr != CHDERR_NONE) { fprintf(stderr, "Error getting A/V metadata: %s\n", chd_error_string(chderr)); |