ReactOS 0.4.15-dev-7942-gd23573b
extrachunk.c
Go to the documentation of this file.
1/*
2 * Copyright 2002 Michael Günnewig
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <assert.h>
20
21#include "extrachunk.h"
22#include "winbase.h"
23#include "wingdi.h"
24#include "winuser.h"
25#include "vfw.h"
26
27#include "wine/debug.h"
28
30
31/* reads a chunk out of the extrachunk-structure */
33{
34 LPBYTE lp;
35 DWORD cb;
36
37 /* pre-conditions */
38 assert(extra != NULL);
39 assert(size != NULL);
40
41 lp = extra->lp;
42 cb = extra->cb;
43
44 if (lp != NULL) {
45 while (cb > 0) {
46 if (((FOURCC*)lp)[0] == ckid) {
47 /* found correct chunk */
48 if (lpData != NULL && *size > 0)
49 memcpy(lpData, lp + 2 * sizeof(DWORD),
50 min(((LPDWORD)lp)[1], *(LPDWORD)size));
51
52 *(LPDWORD)size = ((LPDWORD)lp)[1];
53
54 return AVIERR_OK;
55 } else {
56 /* skip to next chunk */
57 cb -= ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
58 lp += ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
59 }
60 }
61 }
62
63 /* wanted chunk doesn't exist */
64 *size = 0;
65
66 return AVIERR_NODATA;
67}
68
69/* writes a chunk into the extrachunk-structure */
71{
72 LPDWORD lp;
73
74 /* pre-conditions */
75 assert(extra != NULL);
76 assert(lpData != NULL);
77 assert(size > 0);
78
79 if (extra->lp)
80 lp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, extra->lp, extra->cb + size + 2 * sizeof(DWORD));
81 else
82 lp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + 2 * sizeof(DWORD));
83
84 if (lp == NULL)
85 return AVIERR_MEMORY;
86
87 extra->lp = lp;
88 lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
89 extra->cb += size + 2 * sizeof(DWORD);
90
91 /* insert chunk-header in block */
92 lp[0] = ckid;
93 lp[1] = size;
94
95 if (lpData != NULL && size > 0)
96 memcpy(lp + 2, lpData, size);
97
98 return AVIERR_OK;
99}
100
101/* reads a chunk from the HMMIO into the extrachunk-structure */
103{
104 LPDWORD lp;
105 DWORD cb;
106
107 /* pre-conditions */
108 assert(extra != NULL);
109 assert(hmmio != NULL);
110 assert(lpck != NULL);
111
112 cb = lpck->cksize + 2 * sizeof(DWORD);
113 cb += (cb & 1);
114
115 if (extra->lp != NULL)
117 else
119
120 if (lp == NULL)
121 return AVIERR_MEMORY;
122
123 extra->lp = lp;
124 lp = (LPDWORD) ((LPBYTE)lp + extra->cb);
125 extra->cb += cb;
126
127 /* insert chunk-header in block */
128 lp[0] = lpck->ckid;
129 lp[1] = lpck->cksize;
130
131 if (lpck->cksize > 0) {
132 if (mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET) == -1)
133 return AVIERR_FILEREAD;
134 if (mmioRead(hmmio, (HPSTR)&lp[2], lpck->cksize) != (LONG)lpck->cksize)
135 return AVIERR_FILEREAD;
136 }
137
138 return AVIERR_OK;
139}
140
141/* reads all non-junk chunks into the extrachunk-structure until it finds
142 * the given chunk or the optional parent-chunk is at the end */
144 MMCKINFO *lpckParent,UINT flags)
145{
146 FOURCC ckid;
147 FOURCC fccType;
148 MMRESULT mmr;
149
150 /* pre-conditions */
151 assert(extra != NULL);
152 assert(hmmio != NULL);
153 assert(lpck != NULL);
154
155 TRACE("({%p,%u},%p,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck,
156 lpckParent, flags);
157
158 /* what chunk id and form/list type should we search? */
159 if (flags & MMIO_FINDCHUNK) {
160 ckid = lpck->ckid;
161 fccType = 0;
162 } else if (flags & MMIO_FINDLIST) {
163 ckid = FOURCC_LIST;
164 fccType = lpck->fccType;
165 } else if (flags & MMIO_FINDRIFF) {
166 ckid = FOURCC_RIFF;
167 fccType = lpck->fccType;
168 } else
169 ckid = fccType = (FOURCC)-1; /* collect everything into extra! */
170
171 TRACE(": find ckid=0x%08X fccType=0x%08X\n", ckid, fccType);
172
173 for (;;) {
174 mmr = mmioDescend(hmmio, lpck, lpckParent, 0);
175 if (mmr != MMSYSERR_NOERROR) {
176 /* No extra chunks in front of desired chunk? */
177 if (flags == 0 && mmr == MMIOERR_CHUNKNOTFOUND)
178 return AVIERR_OK;
179 else
180 return AVIERR_FILEREAD;
181 }
182
183 /* Have we found what we search for? */
184 if ((lpck->ckid == ckid) &&
185 (fccType == 0 || lpck->fccType == fccType))
186 return AVIERR_OK;
187
188 /* Skip padding chunks, the others put into the extrachunk-structure */
189 if (lpck->ckid == ckidAVIPADDING ||
190 lpck->ckid == mmioFOURCC('p','a','d','d'))
191 {
192 mmr = mmioAscend(hmmio, lpck, 0);
193 if (mmr != MMSYSERR_NOERROR) return AVIERR_FILEREAD;
194 }
195 else
196 {
197 HRESULT hr = ReadChunkIntoExtra(extra, hmmio, lpck);
198 if (FAILED(hr))
199 return hr;
200 }
201 }
202}
static const WCHAR avifile[]
Definition: avisplitter.c:273
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
MMRESULT WINAPI mmioAscend(HMMIO hmmio, LPMMCKINFO lpck, UINT uFlags)
Definition: mmio.c:1205
LONG WINAPI mmioSeek(HMMIO hmmio, LONG lOffset, INT iOrigin)
Definition: mmio.c:836
MMRESULT WINAPI mmioDescend(HMMIO hmmio, LPMMCKINFO lpck, const MMCKINFO *lpckParent, UINT uFlags)
Definition: mmio.c:1107
LONG WINAPI mmioRead(HMMIO hmmio, HPSTR pch, LONG cch)
Definition: mmio.c:733
#define assert(x)
Definition: debug.h:53
DWORD FOURCC
Definition: dmdls.h:25
HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra, HMMIO hmmio, MMCKINFO *lpck, MMCKINFO *lpckParent, UINT flags)
Definition: extrachunk.c:143
HRESULT WriteExtraChunk(LPEXTRACHUNKS extra, FOURCC ckid, LPCVOID lpData, LONG size)
Definition: extrachunk.c:70
HRESULT ReadExtraChunk(const EXTRACHUNKS *extra, FOURCC ckid, LPVOID lpData, LPLONG size)
Definition: extrachunk.c:32
HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra, HMMIO hmmio, const MMCKINFO *lpck)
Definition: extrachunk.c:102
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLbitfield flags
Definition: glext.h:7161
@ extra
Definition: id3.c:95
#define FAILED(hr)
Definition: intsafe.h:51
#define SEEK_SET
Definition: jmemansi.c:26
#define FOURCC(a, b, c, d)
Definition: memtrack.h:4
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define MMIO_FINDRIFF
Definition: mmsystem.h:552
#define FOURCC_RIFF
Definition: mmsystem.h:564
#define MMIOERR_CHUNKNOTFOUND
Definition: mmsystem.h:517
UINT MMRESULT
Definition: mmsystem.h:962
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define FOURCC_LIST
Definition: mmsystem.h:565
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
char * HPSTR
Definition: mmsystem.h:1477
#define MMIO_FINDLIST
Definition: mmsystem.h:553
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define LPDWORD
Definition: nt_native.h:46
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
FOURCC fccType
Definition: mmsystem.h:1509
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t * LPLONG
Definition: typedefs.h:58
uint32_t * LPDWORD
Definition: typedefs.h:59
#define AVIERR_FILEREAD
Definition: vfw.h:1751
#define ckidAVIPADDING
Definition: vfw.h:916
#define AVIERR_OK
Definition: vfw.h:1740
#define AVIERR_MEMORY
Definition: vfw.h:1745
#define AVIERR_NODATA
Definition: vfw.h:1757
CONST void * LPCVOID
Definition: windef.h:191