Commit 866d4998 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmusic: Rewrite collection INFO list parsing.

parent af79bf4f
......@@ -44,7 +44,6 @@ struct collection
LONG ref;
IStream *pStm; /* stream from which we load collection and later instruments */
CHAR *szCopyright; /* FIXME: should probably be placed somewhere else */
DLSHEADER *pHeader;
struct pool *pool;
......@@ -277,9 +276,10 @@ static const IDirectMusicObjectVtbl collection_object_vtbl =
static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
IStream *stream)
{
struct chunk_entry dls_chunk = {0};
struct collection *This = impl_from_IPersistStream(iface);
DMUS_PRIVATE_CHUNK chunk;
DWORD StreamSize, StreamCount, ListSize[2], ListCount[2];
DWORD StreamSize, StreamCount;
LARGE_INTEGER liMove; /* used when skipping chunks */
IStream_AddRef(stream); /* add count for later references */
......@@ -307,6 +307,21 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
return E_FAIL;
}
dls_chunk.id = FOURCC_RIFF;
dls_chunk.size = chunk.dwSize;
dls_chunk.type = chunk.fccID;
liMove.QuadPart = 0;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dls_chunk.offset);
dls_chunk.offset.QuadPart -= 12;
if (FAILED(dmobj_parsedescriptor(stream, &dls_chunk, &This->dmobj.desc,
DMUS_OBJ_NAME_INFO|DMUS_OBJ_VERSION|DMUS_OBJ_OBJECT|DMUS_OBJ_GUID_DLID)))
{
liMove.QuadPart = StreamSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
return E_FAIL;
}
stream_reset_chunk_data(stream, &dls_chunk);
TRACE_(dmfile)(": collection form\n");
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
......@@ -319,18 +334,6 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
IStream_Read(stream, This->pHeader, chunk.dwSize, NULL);
break;
}
case FOURCC_DLID: {
TRACE_(dmfile)(": DLID (GUID) chunk\n");
This->dmobj.desc.dwValidData |= DMUS_OBJ_OBJECT;
IStream_Read(stream, &This->dmobj.desc.guidObject, chunk.dwSize, NULL);
break;
}
case FOURCC_VERS: {
TRACE_(dmfile)(": version chunk\n");
This->dmobj.desc.dwValidData |= DMUS_OBJ_VERSION;
IStream_Read(stream, &This->dmobj.desc.vVersion, chunk.dwSize, NULL);
break;
}
case FOURCC_PTBL: {
struct chunk_entry ptbl_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID};
TRACE_(dmfile)(": pool table chunk\n");
......@@ -344,85 +347,7 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
case FOURCC_LIST: {
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
ListSize[0] = chunk.dwSize - sizeof(FOURCC);
ListCount[0] = 0;
switch (chunk.fccID) {
case DMUS_FOURCC_INFO_LIST: {
TRACE_(dmfile)(": INFO list\n");
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = %#04lx)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
switch (chunk.fccID) {
case mmioFOURCC('I','N','A','M'): {
CHAR szName[DMUS_MAX_NAME];
TRACE_(dmfile)(": name chunk\n");
This->dmobj.desc.dwValidData |= DMUS_OBJ_NAME;
IStream_Read(stream, szName, chunk.dwSize, NULL);
MultiByteToWideChar(CP_ACP, 0, szName, -1, This->dmobj.desc.wszName, DMUS_MAX_NAME);
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
liMove.QuadPart = 1;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','A','R','T'): {
TRACE_(dmfile)(": artist chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','O','P'): {
TRACE_(dmfile)(": copyright chunk\n");
This->szCopyright = calloc(1, chunk.dwSize);
IStream_Read(stream, This->szCopyright, chunk.dwSize, NULL);
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
liMove.QuadPart = 1;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','S','B','J'): {
TRACE_(dmfile)(": subject chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','M','T'): {
TRACE_(dmfile)(": comment chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
break;
}
case FOURCC_WVPL: {
TRACE_(dmfile)(": wave pool list (mark & skip)\n");
liMove.QuadPart = chunk.dwSize - sizeof(FOURCC);
......
......@@ -587,7 +587,14 @@ HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff,
desc->wszFileName, sizeof(desc->wszFileName)) == S_OK)
desc->dwValidData |= DMUS_OBJ_FILENAME;
break;
case FOURCC_DLID:
if (!(supported & DMUS_OBJ_GUID_DLID)) break;
if ((supported & DMUS_OBJ_OBJECT) && stream_chunk_get_data(stream, &chunk,
&desc->guidObject, sizeof(desc->guidObject)) == S_OK)
desc->dwValidData |= DMUS_OBJ_OBJECT;
break;
case DMUS_FOURCC_GUID_CHUNK:
if ((supported & DMUS_OBJ_GUID_DLID)) break;
if ((supported & DMUS_OBJ_OBJECT) && stream_chunk_get_data(stream, &chunk,
&desc->guidObject, sizeof(desc->guidObject)) == S_OK)
desc->dwValidData |= DMUS_OBJ_OBJECT;
......
......@@ -92,6 +92,7 @@ HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff,
DMUS_OBJ_NAME is 'UNAM' chunk in UNFO list */
#define DMUS_OBJ_NAME_INAM 0x1000 /* 'INAM' chunk in UNFO list */
#define DMUS_OBJ_NAME_INFO 0x2000 /* 'INAM' chunk in INFO list */
#define DMUS_OBJ_GUID_DLID 0x4000 /* 'dlid' chunk instead of 'guid' */
/* 'DMRF' (reference list) helper */
HRESULT dmobj_parsereference(IStream *stream, const struct chunk_entry *list,
......
......@@ -165,11 +165,6 @@ void Patch2MIDILOCALE (DWORD dwPatch, LPMIDILOCALE pLocale) {
pLocale->ulBank |= (dwPatch & F_INSTRUMENT_DRUMS); /* get drum bit */
}
/* check whether the given DWORD is even (return 0) or odd (return 1) */
int even_or_odd (DWORD number) {
return (number & 0x1); /* basically, check if bit 0 is set ;) */
}
/* generic flag-dumping function */
static const char* debugstr_flags (DWORD flags, const flag_info* names, size_t num_names){
char buffer[128] = "", *ptr = &buffer[0];
......
......@@ -211,8 +211,6 @@ extern DWORD MIDILOCALE2Patch (const MIDILOCALE *pLocale);
/* MIDILOCALE from dwPatch */
extern void Patch2MIDILOCALE (DWORD dwPatch, LPMIDILOCALE pLocale);
/* check whether the given DWORD is even (return 0) or odd (return 1) */
extern int even_or_odd (DWORD number);
/* Dump whole DMUS_PORTPARAMS struct */
extern void dump_DMUS_PORTPARAMS(LPDMUS_PORTPARAMS params);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment