2 * Copyright 2002 Michael Günnewig
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "extrachunk.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
31 /* reads a chunk outof the extrachunk-structure */
32 HRESULT ReadExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
39 assert(extra != NULL);
47 if (((FOURCC*)lp)[0] == ckid) {
48 /* found correct chunk */
49 if (lpData != NULL && *size > 0)
50 memcpy(lpData, lp + 2 * sizeof(DWORD),
51 min(((LPDWORD)lp)[1], *(LPDWORD)size));
53 *(LPDWORD)size = ((LPDWORD)lp)[1];
57 /* skip to next chunk */
58 cb -= ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
59 lp += ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
64 /* wanted chunk doesn't exist */
70 /* writes a chunk into the extrachunk-structure */
71 HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
77 assert(extra != NULL);
78 assert(lpData != NULL);
82 lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + size + 2 * sizeof(DWORD));
84 lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 2 * sizeof(DWORD));
90 lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
91 extra->cb += size + 2 * sizeof(DWORD);
93 /* insert chunk-header in block */
97 if (lpData != NULL && size > 0)
98 memcpy(lp + 2, lpData, size);
103 /* reads a chunk fomr the HMMIO into the extrachunk-structure */
104 HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck)
110 assert(extra != NULL);
111 assert(hmmio != NULL);
112 assert(lpck != NULL);
114 cb = lpck->cksize + 2 * sizeof(DWORD);
117 if (extra->lp != NULL)
118 lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + cb);
120 lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
123 return AVIERR_MEMORY;
126 lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
129 /* insert chunk-header in block */
131 lp[1] = lpck->cksize;
133 if (lpck->cksize > 0) {
134 if (mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET) == -1)
135 return AVIERR_FILEREAD;
136 if (mmioRead(hmmio, (HPSTR)&lp[2], lpck->cksize) != (LONG)lpck->cksize)
137 return AVIERR_FILEREAD;
143 /* reads all non-junk chunks into the extrachunk-structure until it finds
144 * the given chunk or the optional parent-chunk is at the end */
145 HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck,
146 MMCKINFO *lpckParent,UINT flags)
153 assert(extra != NULL);
154 assert(hmmio != NULL);
155 assert(lpck != NULL);
157 TRACE("({%p,%u},%p,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck,
160 /* what chunk id and form/list type should we search? */
161 if (flags & MMIO_FINDCHUNK) {
164 } else if (flags & MMIO_FINDLIST) {
166 fccType = lpck->fccType;
167 } else if (flags & MMIO_FINDRIFF) {
169 fccType = lpck->fccType;
171 ckid = fccType = (FOURCC)-1; /* collect everything into extra! */
173 TRACE(": find ckid=0x%08X fccType=0x%08X\n", ckid, fccType);
176 hr = mmioDescend(hmmio, lpck, lpckParent, 0);
178 /* No extra chunks in front of desired chunk? */
179 if (flags == 0 && hr == MMIOERR_CHUNKNOTFOUND)
184 /* Have we found what we search for? */
185 if ((lpck->ckid == ckid) &&
186 (fccType == (FOURCC)0 || lpck->fccType == fccType))
189 /* Skip padding chunks, the others put into the extrachunk-structure */
190 if (lpck->ckid == ckidAVIPADDING ||
191 lpck->ckid == mmioFOURCC('p','a','d','d'))
192 hr = mmioAscend(hmmio, lpck, 0);
194 hr = ReadChunkIntoExtra(extra, hmmio, lpck);