summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2009-03-05 07:35:24 +0000
committer Aaron Giles <aaron@aarongiles.com>2009-03-05 07:35:24 +0000
commite8c09b35f6217060b4bd3f5f437585270b2faa3f (patch)
tree9ac04f6b86bacf00d191dfdff5a8a7316dc367a4 /src
parent6a0e1fcfe0f298a5ed87c044ece43aadd1429a85 (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.
Diffstat (limited to 'src')
-rw-r--r--src/emu/machine/ldcore.c4
-rw-r--r--src/lib/util/cdrom.c4
-rw-r--r--src/lib/util/chd.c33
-rw-r--r--src/lib/util/chd.h24
-rw-r--r--src/lib/util/harddisk.c2
-rw-r--r--src/tools/chdman.c24
-rw-r--r--src/tools/ldresample.c2
-rw-r--r--src/tools/ldverify.c2
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));