xref: /reactos/dll/win32/avifil32/extrachunk.c (revision 44836a6e)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Copyright 2002 Michael Günnewig
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
5c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
6c2c66affSColin Finck  * License as published by the Free Software Foundation; either
7c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
8c2c66affSColin Finck  *
9c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
10c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12c2c66affSColin Finck  * Lesser General Public License for more details.
13c2c66affSColin Finck  *
14c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
15c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
16c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17c2c66affSColin Finck  */
18c2c66affSColin Finck 
19*44836a6eSAmine Khaldi #include <assert.h>
20*44836a6eSAmine Khaldi 
21*44836a6eSAmine Khaldi #include "extrachunk.h"
22*44836a6eSAmine Khaldi #include "winbase.h"
23*44836a6eSAmine Khaldi #include "wingdi.h"
24*44836a6eSAmine Khaldi #include "winuser.h"
25*44836a6eSAmine Khaldi #include "vfw.h"
26*44836a6eSAmine Khaldi 
27*44836a6eSAmine Khaldi #include "wine/debug.h"
28*44836a6eSAmine Khaldi 
29*44836a6eSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(avifile);
30c2c66affSColin Finck 
31c2c66affSColin Finck /* reads a chunk out of the extrachunk-structure */
ReadExtraChunk(const EXTRACHUNKS * extra,FOURCC ckid,LPVOID lpData,LPLONG size)32c2c66affSColin Finck HRESULT ReadExtraChunk(const EXTRACHUNKS *extra,FOURCC ckid,LPVOID lpData,LPLONG size)
33c2c66affSColin Finck {
34c2c66affSColin Finck   LPBYTE lp;
35c2c66affSColin Finck   DWORD  cb;
36c2c66affSColin Finck 
37c2c66affSColin Finck   /* pre-conditions */
38c2c66affSColin Finck   assert(extra != NULL);
39c2c66affSColin Finck   assert(size != NULL);
40c2c66affSColin Finck 
41c2c66affSColin Finck   lp = extra->lp;
42c2c66affSColin Finck   cb = extra->cb;
43c2c66affSColin Finck 
44c2c66affSColin Finck   if (lp != NULL) {
45c2c66affSColin Finck     while (cb > 0) {
46c2c66affSColin Finck       if (((FOURCC*)lp)[0] == ckid) {
47c2c66affSColin Finck 	/* found correct chunk */
48c2c66affSColin Finck 	if (lpData != NULL && *size > 0)
49c2c66affSColin Finck 	  memcpy(lpData, lp + 2 * sizeof(DWORD),
50c2c66affSColin Finck 		 min(((LPDWORD)lp)[1], *(LPDWORD)size));
51c2c66affSColin Finck 
52c2c66affSColin Finck 	*(LPDWORD)size = ((LPDWORD)lp)[1];
53c2c66affSColin Finck 
54c2c66affSColin Finck 	return AVIERR_OK;
55c2c66affSColin Finck       } else {
56c2c66affSColin Finck 	/* skip to next chunk */
57c2c66affSColin Finck 	cb -= ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
58c2c66affSColin Finck 	lp += ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
59c2c66affSColin Finck       }
60c2c66affSColin Finck     }
61c2c66affSColin Finck   }
62c2c66affSColin Finck 
63c2c66affSColin Finck   /* wanted chunk doesn't exist */
64c2c66affSColin Finck   *size = 0;
65c2c66affSColin Finck 
66c2c66affSColin Finck   return AVIERR_NODATA;
67c2c66affSColin Finck }
68c2c66affSColin Finck 
69c2c66affSColin Finck /* writes a chunk into the extrachunk-structure */
WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPCVOID lpData,LONG size)70c2c66affSColin Finck HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPCVOID lpData, LONG size)
71c2c66affSColin Finck {
72c2c66affSColin Finck   LPDWORD lp;
73c2c66affSColin Finck 
74c2c66affSColin Finck   /* pre-conditions */
75c2c66affSColin Finck   assert(extra != NULL);
76c2c66affSColin Finck   assert(lpData != NULL);
77c2c66affSColin Finck   assert(size > 0);
78c2c66affSColin Finck 
79c2c66affSColin Finck   if (extra->lp)
80c2c66affSColin Finck     lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + size + 2 * sizeof(DWORD));
81c2c66affSColin Finck   else
82c2c66affSColin Finck     lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 2 * sizeof(DWORD));
83c2c66affSColin Finck 
84c2c66affSColin Finck   if (lp == NULL)
85c2c66affSColin Finck     return AVIERR_MEMORY;
86c2c66affSColin Finck 
87c2c66affSColin Finck   extra->lp  = lp;
88c2c66affSColin Finck   lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
89c2c66affSColin Finck   extra->cb += size + 2 * sizeof(DWORD);
90c2c66affSColin Finck 
91c2c66affSColin Finck   /* insert chunk-header in block */
92c2c66affSColin Finck   lp[0] = ckid;
93c2c66affSColin Finck   lp[1] = size;
94c2c66affSColin Finck 
95c2c66affSColin Finck   if (lpData != NULL && size > 0)
96c2c66affSColin Finck     memcpy(lp + 2, lpData, size);
97c2c66affSColin Finck 
98c2c66affSColin Finck   return AVIERR_OK;
99c2c66affSColin Finck }
100c2c66affSColin Finck 
101c2c66affSColin Finck /* reads a chunk from the HMMIO into the extrachunk-structure */
ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,const MMCKINFO * lpck)102c2c66affSColin Finck HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,const MMCKINFO *lpck)
103c2c66affSColin Finck {
104c2c66affSColin Finck   LPDWORD lp;
105c2c66affSColin Finck   DWORD   cb;
106c2c66affSColin Finck 
107c2c66affSColin Finck   /* pre-conditions */
108c2c66affSColin Finck   assert(extra != NULL);
109c2c66affSColin Finck   assert(hmmio != NULL);
110c2c66affSColin Finck   assert(lpck  != NULL);
111c2c66affSColin Finck 
112c2c66affSColin Finck   cb  = lpck->cksize + 2 * sizeof(DWORD);
113c2c66affSColin Finck   cb += (cb & 1);
114c2c66affSColin Finck 
115c2c66affSColin Finck   if (extra->lp != NULL)
116c2c66affSColin Finck     lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + cb);
117c2c66affSColin Finck   else
118c2c66affSColin Finck     lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cb);
119c2c66affSColin Finck 
120c2c66affSColin Finck   if (lp == NULL)
121c2c66affSColin Finck     return AVIERR_MEMORY;
122c2c66affSColin Finck 
123c2c66affSColin Finck   extra->lp  = lp;
124c2c66affSColin Finck   lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
125c2c66affSColin Finck   extra->cb += cb;
126c2c66affSColin Finck 
127c2c66affSColin Finck   /* insert chunk-header in block */
128c2c66affSColin Finck   lp[0] = lpck->ckid;
129c2c66affSColin Finck   lp[1] = lpck->cksize;
130c2c66affSColin Finck 
131c2c66affSColin Finck   if (lpck->cksize > 0) {
132c2c66affSColin Finck     if (mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET) == -1)
133c2c66affSColin Finck       return AVIERR_FILEREAD;
134c2c66affSColin Finck     if (mmioRead(hmmio, (HPSTR)&lp[2], lpck->cksize) != (LONG)lpck->cksize)
135c2c66affSColin Finck       return AVIERR_FILEREAD;
136c2c66affSColin Finck   }
137c2c66affSColin Finck 
138c2c66affSColin Finck   return AVIERR_OK;
139c2c66affSColin Finck }
140c2c66affSColin Finck 
141c2c66affSColin Finck /* reads all non-junk chunks into the extrachunk-structure until it finds
142c2c66affSColin Finck  * the given chunk or the optional parent-chunk is at the end */
FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO * lpck,MMCKINFO * lpckParent,UINT flags)143c2c66affSColin Finck HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck,
144c2c66affSColin Finck 			       MMCKINFO *lpckParent,UINT flags)
145c2c66affSColin Finck {
146c2c66affSColin Finck   FOURCC  ckid;
147c2c66affSColin Finck   FOURCC  fccType;
148c2c66affSColin Finck   MMRESULT mmr;
149c2c66affSColin Finck 
150c2c66affSColin Finck   /* pre-conditions */
151c2c66affSColin Finck   assert(extra != NULL);
152c2c66affSColin Finck   assert(hmmio != NULL);
153c2c66affSColin Finck   assert(lpck  != NULL);
154c2c66affSColin Finck 
155c2c66affSColin Finck   TRACE("({%p,%u},%p,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck,
156c2c66affSColin Finck 	lpckParent, flags);
157c2c66affSColin Finck 
158c2c66affSColin Finck   /* what chunk id and form/list type should we search? */
159c2c66affSColin Finck   if (flags & MMIO_FINDCHUNK) {
160c2c66affSColin Finck     ckid    = lpck->ckid;
161c2c66affSColin Finck     fccType = 0;
162c2c66affSColin Finck   } else if (flags & MMIO_FINDLIST) {
163c2c66affSColin Finck     ckid    = FOURCC_LIST;
164c2c66affSColin Finck     fccType = lpck->fccType;
165c2c66affSColin Finck   } else if (flags & MMIO_FINDRIFF) {
166c2c66affSColin Finck     ckid    = FOURCC_RIFF;
167c2c66affSColin Finck     fccType = lpck->fccType;
168c2c66affSColin Finck   } else
169c2c66affSColin Finck     ckid = fccType = (FOURCC)-1; /* collect everything into extra! */
170c2c66affSColin Finck 
171c2c66affSColin Finck   TRACE(": find ckid=0x%08X fccType=0x%08X\n", ckid, fccType);
172c2c66affSColin Finck 
173c2c66affSColin Finck   for (;;) {
174c2c66affSColin Finck     mmr = mmioDescend(hmmio, lpck, lpckParent, 0);
175c2c66affSColin Finck     if (mmr != MMSYSERR_NOERROR) {
176c2c66affSColin Finck       /* No extra chunks in front of desired chunk? */
177c2c66affSColin Finck       if (flags == 0 && mmr == MMIOERR_CHUNKNOTFOUND)
178c2c66affSColin Finck 	return AVIERR_OK;
179c2c66affSColin Finck       else
180c2c66affSColin Finck         return AVIERR_FILEREAD;
181c2c66affSColin Finck     }
182c2c66affSColin Finck 
183c2c66affSColin Finck     /* Have we found what we search for? */
184c2c66affSColin Finck     if ((lpck->ckid == ckid) &&
185c2c66affSColin Finck 	(fccType == 0 || lpck->fccType == fccType))
186c2c66affSColin Finck       return AVIERR_OK;
187c2c66affSColin Finck 
188c2c66affSColin Finck     /* Skip padding chunks, the others put into the extrachunk-structure */
189c2c66affSColin Finck     if (lpck->ckid == ckidAVIPADDING ||
190c2c66affSColin Finck 	lpck->ckid == mmioFOURCC('p','a','d','d'))
191c2c66affSColin Finck     {
192c2c66affSColin Finck       mmr = mmioAscend(hmmio, lpck, 0);
193c2c66affSColin Finck       if (mmr != MMSYSERR_NOERROR) return AVIERR_FILEREAD;
194c2c66affSColin Finck     }
195c2c66affSColin Finck     else
196c2c66affSColin Finck     {
197c2c66affSColin Finck       HRESULT hr = ReadChunkIntoExtra(extra, hmmio, lpck);
198c2c66affSColin Finck       if (FAILED(hr))
199c2c66affSColin Finck         return hr;
200c2c66affSColin Finck     }
201c2c66affSColin Finck   }
202c2c66affSColin Finck }
203