#include #include #include "extra.h" #include "debug.h" #ifndef HPBYTE #define HPBYTE BYTE huge * #endif HRESULT ReadExtra(LPEXTRA extra, DWORD ckid, LPVOID lpData, LONG FAR *lpcbData) { #define lpdw ((DWORD UNALIGNED HUGE *) lp) HPBYTE lp = (HPBYTE) 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) { HPBYTE lp; cbData += sizeof(DWORD) * 2; if (extra->lp) { lp = (HPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE); DPF("Extra cb is now %ld\n", extra->cb + cbData); } else { lp = (HPBYTE) 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 UNALIGNED HUGE *) (lp + extra->cb))[0] = ckid; ((DWORD UNALIGNED HUGE *) (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) { HPBYTE lp; LONG cbData = lpck->cksize + sizeof(DWORD) * 2; DPF("ReadIntoExtra: now %ld bytes.\n", extra->cb + cbData); if (extra->lp) { lp = (HPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE); } else { lp = (HPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE, cbData); } if (!lp) return ResultFromScode(AVIERR_MEMORY); extra->lp = lp; // build RIFF chunk in block ((DWORD UNALIGNED HUGE *) (lp + extra->cb))[0] = lpck->ckid; ((DWORD UNALIGNED HUGE *) (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); } }