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
19 #include "avifile_private.h"
21 /* reads a chunk out of the extrachunk-structure */
22 HRESULT
ReadExtraChunk(const EXTRACHUNKS
*extra
,FOURCC ckid
,LPVOID lpData
,LPLONG size
)
28 assert(extra
!= NULL
);
36 if (((FOURCC
*)lp
)[0] == ckid
) {
37 /* found correct chunk */
38 if (lpData
!= NULL
&& *size
> 0)
39 memcpy(lpData
, lp
+ 2 * sizeof(DWORD
),
40 min(((LPDWORD
)lp
)[1], *(LPDWORD
)size
));
42 *(LPDWORD
)size
= ((LPDWORD
)lp
)[1];
46 /* skip to next chunk */
47 cb
-= ((LPDWORD
)lp
)[1] + 2 * sizeof(DWORD
);
48 lp
+= ((LPDWORD
)lp
)[1] + 2 * sizeof(DWORD
);
53 /* wanted chunk doesn't exist */
59 /* writes a chunk into the extrachunk-structure */
60 HRESULT
WriteExtraChunk(LPEXTRACHUNKS extra
,FOURCC ckid
,LPCVOID lpData
, LONG size
)
65 assert(extra
!= NULL
);
66 assert(lpData
!= NULL
);
70 lp
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, extra
->lp
, extra
->cb
+ size
+ 2 * sizeof(DWORD
));
72 lp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
+ 2 * sizeof(DWORD
));
78 lp
= (LPDWORD
) ((LPBYTE
)lp
+ extra
->cb
);
79 extra
->cb
+= size
+ 2 * sizeof(DWORD
);
81 /* insert chunk-header in block */
85 if (lpData
!= NULL
&& size
> 0)
86 memcpy(lp
+ 2, lpData
, size
);
91 /* reads a chunk from the HMMIO into the extrachunk-structure */
92 HRESULT
ReadChunkIntoExtra(LPEXTRACHUNKS extra
,HMMIO hmmio
,const MMCKINFO
*lpck
)
98 assert(extra
!= NULL
);
99 assert(hmmio
!= NULL
);
100 assert(lpck
!= NULL
);
102 cb
= lpck
->cksize
+ 2 * sizeof(DWORD
);
105 if (extra
->lp
!= NULL
)
106 lp
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, extra
->lp
, extra
->cb
+ cb
);
108 lp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cb
);
111 return AVIERR_MEMORY
;
114 lp
= (LPDWORD
) ((LPBYTE
)lp
+ extra
->cb
);
117 /* insert chunk-header in block */
119 lp
[1] = lpck
->cksize
;
121 if (lpck
->cksize
> 0) {
122 if (mmioSeek(hmmio
, lpck
->dwDataOffset
, SEEK_SET
) == -1)
123 return AVIERR_FILEREAD
;
124 if (mmioRead(hmmio
, (HPSTR
)&lp
[2], lpck
->cksize
) != (LONG
)lpck
->cksize
)
125 return AVIERR_FILEREAD
;
131 /* reads all non-junk chunks into the extrachunk-structure until it finds
132 * the given chunk or the optional parent-chunk is at the end */
133 HRESULT
FindChunkAndKeepExtras(LPEXTRACHUNKS extra
,HMMIO hmmio
,MMCKINFO
*lpck
,
134 MMCKINFO
*lpckParent
,UINT flags
)
141 assert(extra
!= NULL
);
142 assert(hmmio
!= NULL
);
143 assert(lpck
!= NULL
);
145 TRACE("({%p,%u},%p,%p,%p,0x%X)\n", extra
->lp
, extra
->cb
, hmmio
, lpck
,
148 /* what chunk id and form/list type should we search? */
149 if (flags
& MMIO_FINDCHUNK
) {
152 } else if (flags
& MMIO_FINDLIST
) {
154 fccType
= lpck
->fccType
;
155 } else if (flags
& MMIO_FINDRIFF
) {
157 fccType
= lpck
->fccType
;
159 ckid
= fccType
= (FOURCC
)-1; /* collect everything into extra! */
161 TRACE(": find ckid=0x%08X fccType=0x%08X\n", ckid
, fccType
);
164 mmr
= mmioDescend(hmmio
, lpck
, lpckParent
, 0);
165 if (mmr
!= MMSYSERR_NOERROR
) {
166 /* No extra chunks in front of desired chunk? */
167 if (flags
== 0 && mmr
== MMIOERR_CHUNKNOTFOUND
)
170 return AVIERR_FILEREAD
;
173 /* Have we found what we search for? */
174 if ((lpck
->ckid
== ckid
) &&
175 (fccType
== 0 || lpck
->fccType
== fccType
))
178 /* Skip padding chunks, the others put into the extrachunk-structure */
179 if (lpck
->ckid
== ckidAVIPADDING
||
180 lpck
->ckid
== mmioFOURCC('p','a','d','d'))
182 mmr
= mmioAscend(hmmio
, lpck
, 0);
183 if (mmr
!= MMSYSERR_NOERROR
) return AVIERR_FILEREAD
;
187 HRESULT hr
= ReadChunkIntoExtra(extra
, hmmio
, lpck
);