151 lines
3.6 KiB
C++
151 lines
3.6 KiB
C++
#include <win32.h>
|
|
#include "avifile.h"
|
|
#include "extra.h"
|
|
#include "debug.h"
|
|
|
|
HRESULT ReadExtra(LPEXTRA extra,
|
|
DWORD ckid,
|
|
LPVOID lpData,
|
|
LONG FAR *lpcbData)
|
|
{
|
|
#define lpdw ((DWORD FAR *) lp)
|
|
LPBYTE lp = (LPBYTE) extra->lp;
|
|
LONG cb = extra->cb;
|
|
LONG cbData;
|
|
|
|
while (cb >= 2 * sizeof(DWORD)) {
|
|
cbData = (LONG) lpdw[1];
|
|
if (lpdw[0] == ckid) {
|
|
if (lpData) {
|
|
hmemcpy(lpData, lp + 2 * sizeof(DWORD), min(cbData, *lpcbData));
|
|
}
|
|
|
|
*lpcbData = cbData;
|
|
|
|
return ResultFromScode(AVIERR_OK);
|
|
}
|
|
|
|
if (cbData & 1)
|
|
cbData++;
|
|
|
|
cb -= cbData + sizeof(DWORD) * 2;
|
|
lp += cbData + sizeof(DWORD) * 2;
|
|
}
|
|
#undef lpdw
|
|
*lpcbData = 0;
|
|
return ResultFromScode(AVIERR_NODATA);
|
|
}
|
|
|
|
HRESULT WriteExtra(LPEXTRA extra,
|
|
DWORD ckid,
|
|
LPVOID lpData,
|
|
LONG cbData)
|
|
{
|
|
LPBYTE lp;
|
|
|
|
cbData += sizeof(DWORD) * 2;
|
|
if (extra->lp) {
|
|
lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE);
|
|
} else {
|
|
lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE, cbData);
|
|
}
|
|
|
|
if (!lp)
|
|
return ResultFromScode(AVIERR_MEMORY);
|
|
|
|
// !!! Should go and get rid of other chunks with same type!
|
|
|
|
// build RIFF chunk in block
|
|
((DWORD FAR *) (lp + extra->cb))[0] = ckid;
|
|
((DWORD FAR *) (lp + extra->cb))[1] = cbData - sizeof(DWORD) * 2;
|
|
|
|
hmemcpy(lp + extra->cb + sizeof(DWORD) * 2,
|
|
lpData,
|
|
cbData - sizeof(DWORD) * 2);
|
|
|
|
if (cbData & 1)
|
|
cbData++;
|
|
|
|
extra->lp = lp;
|
|
extra->cb += cbData;
|
|
|
|
return ResultFromScode(AVIERR_OK);
|
|
}
|
|
|
|
HRESULT ReadIntoExtra(LPEXTRA extra,
|
|
HSHFILE hshfile,
|
|
MMCKINFO FAR * lpck)
|
|
{
|
|
LPBYTE lp;
|
|
LONG cbData = lpck->cksize + sizeof(DWORD) * 2;
|
|
|
|
DPF("ReadIntoExtra: now %ld bytes.\n", extra->cb + cbData);
|
|
if (extra->lp) {
|
|
lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE);
|
|
} else {
|
|
lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE, cbData);
|
|
}
|
|
|
|
if (!lp)
|
|
return ResultFromScode(AVIERR_MEMORY);
|
|
|
|
extra->lp = lp;
|
|
|
|
// build RIFF chunk in block
|
|
((DWORD FAR *) (lp + extra->cb))[0] = lpck->ckid;
|
|
((DWORD FAR *) (lp + extra->cb))[1] = lpck->cksize;
|
|
|
|
cbData += (cbData & 1);
|
|
|
|
shfileSeek(hshfile, lpck->dwDataOffset, SEEK_SET);
|
|
if (shfileRead(hshfile, (HPSTR) lp + extra->cb + sizeof(DWORD) * 2, lpck->cksize) !=
|
|
(LONG) lpck->cksize)
|
|
return ResultFromScode(AVIERR_FILEREAD);
|
|
|
|
extra->cb += cbData;
|
|
|
|
return ResultFromScode(AVIERR_OK);
|
|
}
|
|
|
|
|
|
LONG FindChunkAndKeepExtras(LPEXTRA extra, HSHFILE hshfile,
|
|
MMCKINFO FAR* lpck, MMCKINFO FAR* lpckParent,
|
|
UINT uFlags)
|
|
{
|
|
FOURCC ckidFind; // chunk ID to find (or NULL)
|
|
FOURCC fccTypeFind; // form/list type to find (or NULL)
|
|
LONG lRet;
|
|
|
|
/* figure out what chunk id and form/list type to search for */
|
|
if (uFlags & MMIO_FINDCHUNK)
|
|
ckidFind = lpck->ckid, fccTypeFind = NULL;
|
|
else if (uFlags & MMIO_FINDRIFF)
|
|
ckidFind = FOURCC_RIFF, fccTypeFind = lpck->fccType;
|
|
else if (uFlags & MMIO_FINDLIST)
|
|
ckidFind = FOURCC_LIST, fccTypeFind = lpck->fccType;
|
|
else
|
|
ckidFind = fccTypeFind = (FOURCC) -1; // keep looking indefinitely
|
|
|
|
for (;;) {
|
|
lRet = shfileDescend(hshfile, lpck, lpckParent, 0);
|
|
if (lRet) {
|
|
if (uFlags == 0 && lRet == MMIOERR_CHUNKNOTFOUND)
|
|
lRet = 0;
|
|
return lRet;
|
|
}
|
|
|
|
if ((!ckidFind || lpck->ckid == ckidFind) &&
|
|
(!fccTypeFind || lpck->fccType == fccTypeFind))
|
|
return 0;
|
|
|
|
if (lpck->ckid != mmioFOURCC('J', 'U', 'N', 'K')) {
|
|
lRet = (LONG) ReadIntoExtra(extra, hshfile, lpck);
|
|
if (lRet != AVIERR_OK)
|
|
return lRet;
|
|
}
|
|
|
|
shfileAscend(hshfile, lpck, 0);
|
|
}
|
|
}
|
|
|