Commit 8e596f4d authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmstyle: Rewrite style part list parsing.

parent 7996bc2c
...@@ -34,6 +34,33 @@ struct style_partref_item { ...@@ -34,6 +34,33 @@ struct style_partref_item {
DMUS_IO_PARTREF part_ref; DMUS_IO_PARTREF part_ref;
}; };
struct style_part
{
struct list entry;
DMUS_OBJECTDESC desc;
DMUS_IO_STYLEPART header;
DMUS_IO_STYLENOTE *notes;
UINT notes_count;
DMUS_IO_STYLECURVE *curves;
UINT curves_count;
DMUS_IO_STYLEMARKER *markers;
UINT markers_count;
DMUS_IO_STYLERESOLUTION *resolutions;
UINT resolutions_count;
DMUS_IO_STYLE_ANTICIPATION *anticipations;
UINT anticipations_count;
};
static void style_part_destroy(struct style_part *part)
{
free(part->notes);
free(part->curves);
free(part->markers);
free(part->resolutions);
free(part->anticipations);
free(part);
}
struct style_motif { struct style_motif {
struct list entry; struct list entry;
DWORD dwRhythm; DWORD dwRhythm;
...@@ -53,6 +80,7 @@ struct style ...@@ -53,6 +80,7 @@ struct style
DMUS_IO_STYLE style; DMUS_IO_STYLE style;
struct list motifs; struct list motifs;
struct list bands; struct list bands;
struct list parts;
}; };
static inline struct style *impl_from_IDirectMusicStyle8(IDirectMusicStyle8 *iface) static inline struct style *impl_from_IDirectMusicStyle8(IDirectMusicStyle8 *iface)
...@@ -106,6 +134,8 @@ static ULONG WINAPI style_Release(IDirectMusicStyle8 *iface) ...@@ -106,6 +134,8 @@ static ULONG WINAPI style_Release(IDirectMusicStyle8 *iface)
struct style_band *band, *band2; struct style_band *band, *band2;
struct style_motif *motif, *motif2; struct style_motif *motif, *motif2;
struct style_partref_item *item, *item2; struct style_partref_item *item, *item2;
struct style_part *part;
void *next;
LIST_FOR_EACH_ENTRY_SAFE(band, band2, &This->bands, struct style_band, entry) { LIST_FOR_EACH_ENTRY_SAFE(band, band2, &This->bands, struct style_band, entry) {
list_remove(&band->entry); list_remove(&band->entry);
...@@ -121,6 +151,13 @@ static ULONG WINAPI style_Release(IDirectMusicStyle8 *iface) ...@@ -121,6 +151,13 @@ static ULONG WINAPI style_Release(IDirectMusicStyle8 *iface)
} }
free(motif); free(motif);
} }
LIST_FOR_EACH_ENTRY_SAFE(part, next, &This->parts, struct style_part, entry)
{
list_remove(&part->entry);
style_part_destroy(part);
}
free(This); free(This);
} }
...@@ -460,136 +497,69 @@ static HRESULT parse_part_ref_list(DMUS_PRIVATE_CHUNK *pChunk, IStream *pStm, ...@@ -460,136 +497,69 @@ static HRESULT parse_part_ref_list(DMUS_PRIVATE_CHUNK *pChunk, IStream *pStm,
return S_OK; return S_OK;
} }
static HRESULT parse_part_list(DMUS_PRIVATE_CHUNK *pChunk, IStream *pStm) static HRESULT parse_part_list(struct style *This, IStream *stream, struct chunk_entry *parent)
{ {
HRESULT hr = E_FAIL; struct chunk_entry chunk = {.parent = parent};
DMUS_PRIVATE_CHUNK Chunk; struct style_part *part;
DWORD ListSize[3], ListCount[3]; DMUS_OBJECTDESC desc;
LARGE_INTEGER liMove; /* used when skipping chunks */ HRESULT hr;
DMUS_OBJECTDESC desc; if (FAILED(hr = dmobj_parsedescriptor(stream, parent, &desc, DMUS_OBJ_NAME))
DWORD dwSize = 0; || FAILED(hr = stream_reset_chunk_data(stream, parent)))
DWORD cnt = 0; return hr;
if (pChunk->fccID != DMUS_FOURCC_PART_LIST) { if (!(part = calloc(1, sizeof(*part)))) return E_OUTOFMEMORY;
ERR_(dmfile)(": %s chunk should be a PART list\n", debugstr_fourcc (pChunk->fccID)); part->desc = desc;
return E_FAIL;
}
ListSize[0] = pChunk->dwSize - sizeof(FOURCC); while ((hr = stream_next_chunk(stream, &chunk)) == S_OK)
ListCount[0] = 0; {
switch (MAKE_IDTYPE(chunk.id, chunk.type))
{
case DMUS_FOURCC_PART_CHUNK:
hr = stream_chunk_get_data(stream, &chunk, &part->header, sizeof(part->header));
break;
do { case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_UNFO_LIST):
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); /* already parsed by dmobj_parsedescriptor */
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; break;
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) { case DMUS_FOURCC_NOTE_CHUNK:
case DMUS_FOURCC_PART_CHUNK: { hr = stream_chunk_get_array(stream, &chunk, (void **)&part->notes,
TRACE_(dmfile)(": Part chunk (skipping for now)\n" ); &part->notes_count, sizeof(*part->notes));
liMove.QuadPart = Chunk.dwSize; break;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break; case DMUS_FOURCC_CURVE_CHUNK:
} hr = stream_chunk_get_array(stream, &chunk, (void **)&part->curves,
case DMUS_FOURCC_NOTE_CHUNK: { &part->curves_count, sizeof(*part->curves));
TRACE_(dmfile)(": Note chunk (skipping for now)\n"); break;
IStream_Read (pStm, &dwSize, sizeof(DWORD), NULL);
cnt = (Chunk.dwSize - sizeof(DWORD)); case DMUS_FOURCC_MARKER_CHUNK:
TRACE_(dmfile)(" - dwSize: %lu\n", dwSize); hr = stream_chunk_get_array(stream, &chunk, (void **)&part->markers,
TRACE_(dmfile)(" - cnt: %lu (%lu / %lu)\n", cnt / dwSize, cnt, dwSize); &part->markers_count, sizeof(*part->markers));
if (cnt % dwSize != 0) { break;
ERR("Invalid Array Size\n");
return E_FAIL; case DMUS_FOURCC_RESOLUTION_CHUNK:
} hr = stream_chunk_get_array(stream, &chunk, (void **)&part->resolutions,
cnt /= dwSize; &part->resolutions_count, sizeof(*part->resolutions));
/** skip for now */ break;
liMove.QuadPart = cnt * dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); case DMUS_FOURCC_ANTICIPATION_CHUNK:
break; hr = stream_chunk_get_array(stream, &chunk, (void **)&part->anticipations,
} &part->anticipations_count, sizeof(*part->anticipations));
case DMUS_FOURCC_CURVE_CHUNK: { break;
TRACE_(dmfile)(": Curve chunk (skipping for now)\n");
IStream_Read (pStm, &dwSize, sizeof(DWORD), NULL); default:
cnt = (Chunk.dwSize - sizeof(DWORD)); FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type));
TRACE_(dmfile)(" - dwSize: %lu\n", dwSize); break;
TRACE_(dmfile)(" - cnt: %lu (%lu / %lu)\n", cnt / dwSize, cnt, dwSize); }
if (cnt % dwSize != 0) {
ERR("Invalid Array Size\n"); if (FAILED(hr)) break;
return E_FAIL;
}
cnt /= dwSize;
/** skip for now */
liMove.QuadPart = cnt * dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case DMUS_FOURCC_MARKER_CHUNK: {
TRACE_(dmfile)(": Marker chunk (skipping for now)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case DMUS_FOURCC_RESOLUTION_CHUNK: {
TRACE_(dmfile)(": Resolution chunk (skipping for now)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case DMUS_FOURCC_ANTICIPATION_CHUNK: {
TRACE_(dmfile)(": Anticipation chunk (skipping for now)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case FOURCC_LIST: {
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
ListCount[1] = 0;
switch (Chunk.fccID) {
case DMUS_FOURCC_UNFO_LIST: {
TRACE_(dmfile)(": UNFO list\n");
do {
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
if (FAILED(hr)) return hr;
if (hr == S_FALSE) {
switch (Chunk.fccID) {
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
}
TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
} while (ListCount[1] < ListSize[1]);
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
} }
TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
return S_OK; if (FAILED(hr)) style_part_destroy(part);
else list_add_tail(&This->parts, &part->entry);
return hr;
} }
static HRESULT parse_pattern_list(struct style *This, DMUS_PRIVATE_CHUNK *pChunk, IStream *pStm) static HRESULT parse_pattern_list(struct style *This, DMUS_PRIVATE_CHUNK *pChunk, IStream *pStm)
...@@ -861,8 +831,12 @@ static HRESULT parse_style_form(struct style *This, DMUS_PRIVATE_CHUNK *pChunk, ...@@ -861,8 +831,12 @@ static HRESULT parse_style_form(struct style *This, DMUS_PRIVATE_CHUNK *pChunk,
break; break;
} }
case DMUS_FOURCC_PART_LIST: { case DMUS_FOURCC_PART_LIST: {
static const LARGE_INTEGER zero = {0};
struct chunk_entry chunk = {FOURCC_LIST, .size = Chunk.dwSize, .type = Chunk.fccID};
TRACE_(dmfile)(": PART list\n"); TRACE_(dmfile)(": PART list\n");
hr = parse_part_list(&Chunk, pStm); IStream_Seek(pStm, zero, STREAM_SEEK_CUR, &chunk.offset);
chunk.offset.QuadPart -= 12;
hr = parse_part_list(This, pStm, &chunk);
if (FAILED(hr)) return hr; if (FAILED(hr)) return hr;
break; break;
} }
...@@ -961,6 +935,7 @@ HRESULT create_dmstyle(REFIID lpcGUID, void **ppobj) ...@@ -961,6 +935,7 @@ HRESULT create_dmstyle(REFIID lpcGUID, void **ppobj)
dmobject_init(&obj->dmobj, &CLSID_DirectMusicStyle, (IUnknown *)&obj->IDirectMusicStyle8_iface); dmobject_init(&obj->dmobj, &CLSID_DirectMusicStyle, (IUnknown *)&obj->IDirectMusicStyle8_iface);
obj->dmobj.IDirectMusicObject_iface.lpVtbl = &dmobject_vtbl; obj->dmobj.IDirectMusicObject_iface.lpVtbl = &dmobject_vtbl;
obj->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl; obj->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
list_init(&obj->parts);
list_init(&obj->bands); list_init(&obj->bands);
list_init(&obj->motifs); list_init(&obj->motifs);
......
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