ReactOS 0.4.15-dev-8100-g1887773
avifile.c File Reference
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "winerror.h"
#include "mmsystem.h"
#include "vfw.h"
#include "avifile_private.h"
#include "extrachunk.h"
#include "wine/debug.h"
Include dependency graph for avifile.c:

Go to the source code of this file.

Classes

struct  _IAVIStreamImpl
 
struct  _IAVIFileImpl
 

Macros

#define COBJMACROS
 
#define IDX_PER_BLOCK   2730
 

Typedefs

typedef struct _IAVIFileImpl IAVIFileImpl
 
typedef struct _IAVIStreamImpl IAVIStreamImpl
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (avifile)
 
static IAVIStreamImplimpl_from_IAVIStream (IAVIStream *iface)
 
static IAVIFileImplimpl_from_IUnknown (IUnknown *iface)
 
static IAVIFileImplimpl_from_IAVIFile (IAVIFile *iface)
 
static IAVIFileImplimpl_from_IPersistFile (IPersistFile *iface)
 
static HRESULT AVIFILE_AddFrame (IAVIStreamImpl *This, DWORD ckid, DWORD size, DWORD offset, DWORD flags)
 
static HRESULT AVIFILE_AddRecord (IAVIFileImpl *This)
 
static DWORD AVIFILE_ComputeMoviStart (IAVIFileImpl *This)
 
static void AVIFILE_ConstructAVIStream (IAVIFileImpl *paf, DWORD nr, const AVISTREAMINFOW *asi)
 
static void AVIFILE_DestructAVIStream (IAVIStreamImpl *This)
 
static HRESULT AVIFILE_LoadFile (IAVIFileImpl *This)
 
static HRESULT AVIFILE_LoadIndex (const IAVIFileImpl *This, DWORD size, DWORD offset)
 
static HRESULT AVIFILE_ParseIndex (const IAVIFileImpl *This, AVIINDEXENTRY *lp, LONG count, DWORD pos, BOOL *bAbsolute)
 
static HRESULT AVIFILE_ReadBlock (IAVIStreamImpl *This, DWORD start, LPVOID buffer, DWORD size)
 
static void AVIFILE_SamplesToBlock (const IAVIStreamImpl *This, LPLONG pos, LPLONG offset)
 
static HRESULT AVIFILE_SaveFile (IAVIFileImpl *This)
 
static HRESULT AVIFILE_SaveIndex (const IAVIFileImpl *This)
 
static ULONG AVIFILE_SearchStream (const IAVIFileImpl *This, DWORD fccType, LONG lSkip)
 
static void AVIFILE_UpdateInfo (IAVIFileImpl *This)
 
static HRESULT AVIFILE_WriteBlock (IAVIStreamImpl *This, DWORD block, FOURCC ckid, DWORD flags, LPCVOID buffer, LONG size)
 
static HRESULT WINAPI IUnknown_fnQueryInterface (IUnknown *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI IUnknown_fnAddRef (IUnknown *iface)
 
static ULONG WINAPI IUnknown_fnRelease (IUnknown *iface)
 
static HRESULT WINAPI IAVIFile_fnQueryInterface (IAVIFile *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI IAVIFile_fnAddRef (IAVIFile *iface)
 
static ULONG WINAPI IAVIFile_fnRelease (IAVIFile *iface)
 
static HRESULT WINAPI IAVIFile_fnInfo (IAVIFile *iface, AVIFILEINFOW *afi, LONG size)
 
static HRESULT WINAPI IAVIFile_fnGetStream (IAVIFile *iface, IAVIStream **avis, DWORD fccType, LONG lParam)
 
static HRESULT WINAPI IAVIFile_fnCreateStream (IAVIFile *iface, IAVIStream **avis, AVISTREAMINFOW *asi)
 
static HRESULT WINAPI IAVIFile_fnWriteData (IAVIFile *iface, DWORD ckid, void *lpData, LONG size)
 
static HRESULT WINAPI IAVIFile_fnReadData (IAVIFile *iface, DWORD ckid, void *lpData, LONG *size)
 
static HRESULT WINAPI IAVIFile_fnEndRecord (IAVIFile *iface)
 
static HRESULT WINAPI IAVIFile_fnDeleteStream (IAVIFile *iface, DWORD fccType, LONG lParam)
 
static HRESULT WINAPI IPersistFile_fnQueryInterface (IPersistFile *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI IPersistFile_fnAddRef (IPersistFile *iface)
 
static ULONG WINAPI IPersistFile_fnRelease (IPersistFile *iface)
 
static HRESULT WINAPI IPersistFile_fnGetClassID (IPersistFile *iface, LPCLSID pClassID)
 
static HRESULT WINAPI IPersistFile_fnIsDirty (IPersistFile *iface)
 
static HRESULT WINAPI IPersistFile_fnLoad (IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
 
static HRESULT WINAPI IPersistFile_fnSave (IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
 
static HRESULT WINAPI IPersistFile_fnSaveCompleted (IPersistFile *iface, LPCOLESTR pszFileName)
 
static HRESULT WINAPI IPersistFile_fnGetCurFile (IPersistFile *iface, LPOLESTR *ppszFileName)
 
HRESULT AVIFILE_CreateAVIFile (IUnknown *pUnkOuter, REFIID riid, void **ppv)
 
static HRESULT WINAPI IAVIStream_fnQueryInterface (IAVIStream *iface, REFIID riid, void **ppv)
 
static ULONG WINAPI IAVIStream_fnAddRef (IAVIStream *iface)
 
static ULONG WINAPI IAVIStream_fnRelease (IAVIStream *iface)
 
static HRESULT WINAPI IAVIStream_fnCreate (IAVIStream *iface, LPARAM lParam1, LPARAM lParam2)
 
static HRESULT WINAPI IAVIStream_fnInfo (IAVIStream *iface, AVISTREAMINFOW *psi, LONG size)
 
static LONG WINAPI IAVIStream_fnFindSample (IAVIStream *iface, LONG pos, LONG flags)
 
static HRESULT WINAPI IAVIStream_fnReadFormat (IAVIStream *iface, LONG pos, void *format, LONG *formatsize)
 
static HRESULT WINAPI IAVIStream_fnSetFormat (IAVIStream *iface, LONG pos, void *format, LONG formatsize)
 
static HRESULT WINAPI IAVIStream_fnRead (IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, LONG *bytesread, LONG *samplesread)
 
static HRESULT WINAPI IAVIStream_fnWrite (IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten)
 
static HRESULT WINAPI IAVIStream_fnDelete (IAVIStream *iface, LONG start, LONG samples)
 
static HRESULT WINAPI IAVIStream_fnReadData (IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread)
 
static HRESULT WINAPI IAVIStream_fnWriteData (IAVIStream *iface, DWORD fcc, void *lp, LONG size)
 
static HRESULT WINAPI IAVIStream_fnSetInfo (IAVIStream *iface, AVISTREAMINFOW *info, LONG infolen)
 

Variables

static const IUnknownVtbl unk_vtbl
 
static const struct IAVIFileVtbl avif_vt
 
static const struct IPersistFileVtbl pf_vt
 
static const struct IAVIStreamVtbl avist_vt
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 33 of file avifile.c.

◆ IDX_PER_BLOCK

#define IDX_PER_BLOCK   2730

Definition at line 54 of file avifile.c.

Typedef Documentation

◆ IAVIFileImpl

Definition at line 57 of file avifile.c.

◆ IAVIStreamImpl

Function Documentation

◆ AVIFILE_AddFrame()

static HRESULT AVIFILE_AddFrame ( IAVIStreamImpl This,
DWORD  ckid,
DWORD  size,
DWORD  offset,
DWORD  flags 
)
static

Definition at line 1334 of file avifile.c.

1335{
1336 UINT n;
1337
1338 /* pre-conditions */
1339 assert(This != NULL);
1340
1341 switch (TWOCCFromFOURCC(ckid)) {
1342 case cktypeDIBbits:
1343 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1345 break;
1347 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1348 flags &= ~AVIIF_KEYFRAME;
1349 break;
1350 case cktypePALchange:
1351 if (This->sInfo.fccType != streamtypeVIDEO) {
1352 ERR(": found palette change in non-video stream!\n");
1353 return AVIERR_BADFORMAT;
1354 }
1355
1356 if (This->idxFmtChanges == NULL || This->nIdxFmtChanges <= This->sInfo.dwFormatChangeCount) {
1357 DWORD new_count = This->nIdxFmtChanges + 16;
1358 void *new_buffer;
1359
1360 if (This->idxFmtChanges == NULL) {
1361 This->idxFmtChanges =
1362 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(AVIINDEXENTRY));
1363 if (!This->idxFmtChanges) return AVIERR_MEMORY;
1364 } else {
1365 new_buffer = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFmtChanges,
1366 new_count * sizeof(AVIINDEXENTRY));
1367 if (!new_buffer) return AVIERR_MEMORY;
1368 This->idxFmtChanges = new_buffer;
1369 }
1370 This->nIdxFmtChanges = new_count;
1371 }
1372
1373 This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
1374 n = ++This->sInfo.dwFormatChangeCount;
1375 This->idxFmtChanges[n].ckid = This->lLastFrame;
1376 This->idxFmtChanges[n].dwFlags = 0;
1377 This->idxFmtChanges[n].dwChunkOffset = offset;
1378 This->idxFmtChanges[n].dwChunkLength = size;
1379
1380 return AVIERR_OK;
1381 case cktypeWAVEbytes:
1382 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1384 break;
1385 default:
1386 WARN(": unknown TWOCC 0x%04X found\n", TWOCCFromFOURCC(ckid));
1387 break;
1388 };
1389
1390 /* first frame is always a keyframe */
1391 if (This->lLastFrame == -1)
1393
1394 if (This->sInfo.dwSuggestedBufferSize < size)
1395 This->sInfo.dwSuggestedBufferSize = size;
1396
1397 /* get memory for index */
1398 if (This->idxFrames == NULL || This->lLastFrame + 1 >= This->nIdxFrames) {
1399 This->nIdxFrames += 512;
1400 if (This->idxFrames == NULL)
1401 This->idxFrames = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->nIdxFrames * sizeof(AVIINDEXENTRY));
1402 else
1403 This->idxFrames = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxFrames,
1404 This->nIdxFrames * sizeof(AVIINDEXENTRY));
1405 if (This->idxFrames == NULL)
1406 return AVIERR_MEMORY;
1407 }
1408
1409 This->lLastFrame++;
1410 This->idxFrames[This->lLastFrame].ckid = ckid;
1411 This->idxFrames[This->lLastFrame].dwFlags = flags;
1412 This->idxFrames[This->lLastFrame].dwChunkOffset = offset;
1413 This->idxFrames[This->lLastFrame].dwChunkLength = size;
1414
1415 /* update AVISTREAMINFO structure if necessary */
1416 if (This->sInfo.dwLength <= This->lLastFrame)
1417 This->sInfo.dwLength = This->lLastFrame + 1;
1418
1419 return AVIERR_OK;
1420}
#define AVIIF_KEYFRAME
Definition: aviriff.h:131
#define streamtypeVIDEO
Definition: aviriff.h:92
#define TWOCCFromFOURCC(fcc)
Definition: avisplit.c:49
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
#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
#define assert(x)
Definition: debug.h:53
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLbitfield flags
Definition: glext.h:7161
GLintptr offset
Definition: glext.h:5920
unsigned int UINT
Definition: ndis.h:50
#define cktypePALchange
Definition: vfw.h:912
#define AVISTREAMINFO_FORMATCHANGES
Definition: vfw.h:1049
#define cktypeDIBcompressed
Definition: vfw.h:911
#define AVIERR_BADFORMAT
Definition: vfw.h:1744
#define cktypeWAVEbytes
Definition: vfw.h:913
#define AVIERR_OK
Definition: vfw.h:1740
#define AVIFILEINFO_TRUSTCKTYPE
Definition: vfw.h:1055
#define AVIERR_MEMORY
Definition: vfw.h:1745
#define cktypeDIBbits
Definition: vfw.h:910

Referenced by AVIFILE_LoadFile(), AVIFILE_ParseIndex(), AVIFILE_WriteBlock(), and IAVIStream_fnSetFormat().

◆ AVIFILE_AddRecord()

static HRESULT AVIFILE_AddRecord ( IAVIFileImpl This)
static

Definition at line 1422 of file avifile.c.

1423{
1424 /* pre-conditions */
1425 assert(This != NULL && This->ppStreams[0] != NULL);
1426
1427 if (This->idxRecords == NULL || This->cbIdxRecords / sizeof(AVIINDEXENTRY) <= This->nIdxRecords) {
1428 DWORD new_count = This->cbIdxRecords + 1024 * sizeof(AVIINDEXENTRY);
1429 void *mem;
1430 if (!This->idxRecords)
1432 else
1433 mem = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->idxRecords, new_count);
1434 if (mem) {
1435 This->cbIdxRecords = new_count;
1436 This->idxRecords = mem;
1437 } else {
1438 HeapFree(GetProcessHeap(), 0, This->idxRecords);
1439 This->idxRecords = NULL;
1440 return AVIERR_MEMORY;
1441 }
1442 }
1443
1444 assert(This->nIdxRecords < This->cbIdxRecords/sizeof(AVIINDEXENTRY));
1445
1446 This->idxRecords[This->nIdxRecords].ckid = listtypeAVIRECORD;
1447 This->idxRecords[This->nIdxRecords].dwFlags = AVIIF_LIST;
1448 This->idxRecords[This->nIdxRecords].dwChunkOffset =
1449 This->ckLastRecord.dwDataOffset - 2 * sizeof(DWORD);
1450 This->idxRecords[This->nIdxRecords].dwChunkLength =
1451 This->ckLastRecord.cksize;
1452 This->nIdxRecords++;
1453
1454 return AVIERR_OK;
1455}
#define AVIIF_LIST
Definition: aviriff.h:130
#define HeapFree(x, y, z)
Definition: compat.h:735
#define DWORD
Definition: nt_native.h:44
Definition: mem.c:156
#define listtypeAVIRECORD
Definition: vfw.h:899
struct _AVIINDEXENTRY AVIINDEXENTRY

Referenced by IAVIFile_fnEndRecord().

◆ AVIFILE_ComputeMoviStart()

static DWORD AVIFILE_ComputeMoviStart ( IAVIFileImpl This)
static

Definition at line 1457 of file avifile.c.

1458{
1459 DWORD dwPos;
1460 DWORD nStream;
1461
1462 /* RIFF,hdrl,movi,avih => (3 * 3 + 2) * sizeof(DWORD) = 11 * sizeof(DWORD) */
1463 dwPos = 11 * sizeof(DWORD) + sizeof(MainAVIHeader);
1464
1465 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
1466 IAVIStreamImpl *pStream = This->ppStreams[nStream];
1467
1468 /* strl,strh,strf => (3 + 2 * 2) * sizeof(DWORD) = 7 * sizeof(DWORD) */
1469 dwPos += 7 * sizeof(DWORD) + sizeof(AVIStreamHeader);
1470 dwPos += ((pStream->cbFormat + 1) & ~1U);
1471 if (pStream->lpHandlerData != NULL && pStream->cbHandlerData > 0)
1472 dwPos += 2 * sizeof(DWORD) + ((pStream->cbHandlerData + 1) & ~1U);
1473 if (pStream->sInfo.szName[0])
1474 dwPos += 2 * sizeof(DWORD) + ((lstrlenW(pStream->sInfo.szName) + 1) & ~1U);
1475 }
1476
1477 if (This->dwMoviChunkPos == 0) {
1478 This->dwNextFramePos = dwPos;
1479
1480 /* pad to multiple of AVI_HEADERSIZE only if we are more than 8 bytes away from it */
1481 if (((dwPos + AVI_HEADERSIZE) & ~(AVI_HEADERSIZE - 1)) - dwPos > 2 * sizeof(DWORD))
1482 This->dwNextFramePos = (dwPos + AVI_HEADERSIZE) & ~(AVI_HEADERSIZE - 1);
1483
1484 This->dwMoviChunkPos = This->dwNextFramePos - sizeof(DWORD);
1485 }
1486
1487 return dwPos;
1488}
#define lstrlenW
Definition: compat.h:750
WCHAR szName[64]
Definition: avifil32.idl:46
DWORD cbFormat
Definition: avifile.c:68
AVISTREAMINFOW sInfo
Definition: acmstream.c:46
DWORD cbHandlerData
Definition: avifile.c:71
LPVOID lpHandlerData
Definition: avifile.c:70
#define AVI_HEADERSIZE
Definition: vfw.h:935

Referenced by AVIFILE_SaveFile(), AVIFILE_WriteBlock(), IAVIFile_fnEndRecord(), and IAVIStream_fnWriteData().

◆ AVIFILE_ConstructAVIStream()

static void AVIFILE_ConstructAVIStream ( IAVIFileImpl paf,
DWORD  nr,
const AVISTREAMINFOW asi 
)
static

Definition at line 1490 of file avifile.c.

1491{
1492 IAVIStreamImpl *pstream;
1493
1494 /* pre-conditions */
1495 assert(paf != NULL);
1497 assert(paf->ppStreams[nr] != NULL);
1498
1499 pstream = paf->ppStreams[nr];
1500
1501 pstream->IAVIStream_iface.lpVtbl = &avist_vt;
1502 pstream->ref = 0;
1503 pstream->paf = paf;
1504 pstream->nStream = nr;
1505 pstream->dwCurrentFrame = (DWORD)-1;
1506 pstream->lLastFrame = -1;
1507
1508 if (asi != NULL) {
1509 memcpy(&pstream->sInfo, asi, sizeof(pstream->sInfo));
1510
1511 if (asi->dwLength > 0) {
1512 /* pre-allocate mem for frame-index structure */
1513 pstream->idxFrames =
1515 if (pstream->idxFrames != NULL)
1516 pstream->nIdxFrames = asi->dwLength;
1517 }
1518 if (asi->dwFormatChangeCount > 0) {
1519 /* pre-allocate mem for formatchange-index structure */
1520 pstream->idxFmtChanges =
1522 if (pstream->idxFmtChanges != NULL)
1523 pstream->nIdxFmtChanges = asi->dwFormatChangeCount;
1524 }
1525
1526 /* These values will be computed */
1527 pstream->sInfo.dwLength = 0;
1528 pstream->sInfo.dwSuggestedBufferSize = 0;
1529 pstream->sInfo.dwFormatChangeCount = 0;
1530 pstream->sInfo.dwEditCount = 1;
1531 if (pstream->sInfo.dwSampleSize > 0)
1532 SetRectEmpty(&pstream->sInfo.rcFrame);
1533 }
1534
1536}
static const struct IAVIStreamVtbl avist_vt
Definition: avifile.c:1316
#define MAX_AVISTREAMS
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG nr
Definition: thread.c:7
DWORD dwSuggestedBufferSize
Definition: avifil32.idl:40
DWORD dwEditCount
Definition: avifil32.idl:44
DWORD dwFormatChangeCount
Definition: avifil32.idl:45
DWORD dwSampleSize
Definition: avifil32.idl:42
IAVIStreamImpl * ppStreams[MAX_AVISTREAMS]
Definition: avifile.c:99
DWORD nStream
Definition: avifile.c:64
AVIINDEXENTRY * idxFrames
Definition: avifile.c:80
DWORD dwCurrentFrame
Definition: avifile.c:77
IAVIFileImpl * paf
Definition: avifile.c:63
IAVIStream IAVIStream_iface
Definition: acmstream.c:41
AVIINDEXENTRY * idxFmtChanges
Definition: avifile.c:82
DWORD nIdxFrames
Definition: avifile.c:81
DWORD nIdxFmtChanges
Definition: avifile.c:83
LONG lLastFrame
Definition: avifile.c:79
#define AVIFILECAPS_CANWRITE
Definition: vfw.h:1061
#define AVIFILECAPS_CANREAD
Definition: vfw.h:1060
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)

Referenced by AVIFILE_LoadFile(), and IAVIFile_fnCreateStream().

◆ AVIFILE_CreateAVIFile()

HRESULT AVIFILE_CreateAVIFile ( IUnknown pUnkOuter,
REFIID  riid,
void **  ppv 
)

Definition at line 645 of file avifile.c.

646{
648 HRESULT hr;
649
650 *ppv = NULL;
652 if (!obj)
653 return AVIERR_MEMORY;
654
655 obj->IUnknown_inner.lpVtbl = &unk_vtbl;
656 obj->IAVIFile_iface.lpVtbl = &avif_vt;
657 obj->IPersistFile_iface.lpVtbl = &pf_vt;
658 obj->ref = 1;
659 if (pUnkOuter)
660 obj->outer_unk = pUnkOuter;
661 else
662 obj->outer_unk = &obj->IUnknown_inner;
663
664 hr = IUnknown_QueryInterface(&obj->IUnknown_inner, riid, ppv);
665 IUnknown_Release(&obj->IUnknown_inner);
666
667 return hr;
668}
static const struct IAVIFileVtbl avif_vt
Definition: avifile.c:482
static const IUnknownVtbl unk_vtbl
Definition: avifile.c:247
static const struct IPersistFileVtbl pf_vt
Definition: avifile.c:633
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT hr
Definition: shlfolder.c:183

Referenced by IClassFactory_fnCreateInstance().

◆ AVIFILE_DestructAVIStream()

static void AVIFILE_DestructAVIStream ( IAVIStreamImpl This)
static

Definition at line 1538 of file avifile.c.

1539{
1540 /* pre-conditions */
1541 assert(This != NULL);
1542
1543 This->dwCurrentFrame = (DWORD)-1;
1544 This->lLastFrame = -1;
1545 This->paf = NULL;
1546 if (This->idxFrames != NULL) {
1547 HeapFree(GetProcessHeap(), 0, This->idxFrames);
1548 This->idxFrames = NULL;
1549 This->nIdxFrames = 0;
1550 }
1551 HeapFree(GetProcessHeap(), 0, This->idxFmtChanges);
1552 This->idxFmtChanges = NULL;
1553 if (This->lpBuffer != NULL) {
1554 HeapFree(GetProcessHeap(), 0, This->lpBuffer);
1555 This->lpBuffer = NULL;
1556 This->cbBuffer = 0;
1557 }
1558 if (This->lpHandlerData != NULL) {
1559 HeapFree(GetProcessHeap(), 0, This->lpHandlerData);
1560 This->lpHandlerData = NULL;
1561 This->cbHandlerData = 0;
1562 }
1563 if (This->extra.lp != NULL) {
1564 HeapFree(GetProcessHeap(), 0, This->extra.lp);
1565 This->extra.lp = NULL;
1566 This->extra.cb = 0;
1567 }
1568 if (This->lpFormat != NULL) {
1569 HeapFree(GetProcessHeap(), 0, This->lpFormat);
1570 This->lpFormat = NULL;
1571 This->cbFormat = 0;
1572 }
1573}

Referenced by IUnknown_fnRelease().

◆ AVIFILE_LoadFile()

static HRESULT AVIFILE_LoadFile ( IAVIFileImpl This)
static

Definition at line 1575 of file avifile.c.

1576{
1577 MainAVIHeader MainAVIHdr;
1578 MMCKINFO ckRIFF;
1579 MMCKINFO ckLIST1;
1580 MMCKINFO ckLIST2;
1581 MMCKINFO ck;
1582 IAVIStreamImpl *pStream;
1583 DWORD nStream;
1584 HRESULT hr;
1585
1586 if (This->hmmio == NULL)
1587 return AVIERR_FILEOPEN;
1588
1589 /* initialize stream ptr's */
1590 memset(This->ppStreams, 0, sizeof(This->ppStreams));
1591
1592 /* try to get "RIFF" chunk -- must not be at beginning of file! */
1593 ckRIFF.fccType = formtypeAVI;
1594 if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
1595 ERR(": not an AVI!\n");
1596 return AVIERR_FILEREAD;
1597 }
1598
1599 /* get "LIST" "hdrl" */
1600 ckLIST1.fccType = listtypeAVIHEADER;
1601 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF, MMIO_FINDLIST);
1602 if (FAILED(hr))
1603 return hr;
1604
1605 /* get "avih" chunk */
1606 ck.ckid = ckidAVIMAINHDR;
1607 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, MMIO_FINDCHUNK);
1608 if (FAILED(hr))
1609 return hr;
1610
1611 if (ck.cksize != sizeof(MainAVIHdr)) {
1612 ERR(": invalid size of %d for MainAVIHeader!\n", ck.cksize);
1613 return AVIERR_BADFORMAT;
1614 }
1615 if (mmioRead(This->hmmio, (HPSTR)&MainAVIHdr, ck.cksize) != ck.cksize)
1616 return AVIERR_FILEREAD;
1617
1618 /* check for MAX_AVISTREAMS limit */
1619 if (MainAVIHdr.dwStreams > MAX_AVISTREAMS) {
1620 WARN("file contains %u streams, but only supports %d -- change MAX_AVISTREAMS!\n", MainAVIHdr.dwStreams, MAX_AVISTREAMS);
1621 return AVIERR_UNSUPPORTED;
1622 }
1623
1624 /* adjust permissions if copyrighted material in file */
1625 if (MainAVIHdr.dwFlags & AVIFILEINFO_COPYRIGHTED) {
1626 This->uMode &= ~MMIO_RWMODE;
1627 This->uMode |= MMIO_READ;
1628 }
1629
1630 /* convert MainAVIHeader into AVIFILINFOW */
1631 memset(&This->fInfo, 0, sizeof(This->fInfo));
1632 This->fInfo.dwRate = MainAVIHdr.dwMicroSecPerFrame;
1633 This->fInfo.dwScale = 1000000;
1634 This->fInfo.dwMaxBytesPerSec = MainAVIHdr.dwMaxBytesPerSec;
1635 This->fInfo.dwFlags = MainAVIHdr.dwFlags;
1637 This->fInfo.dwLength = MainAVIHdr.dwTotalFrames;
1638 This->fInfo.dwStreams = MainAVIHdr.dwStreams;
1639 This->fInfo.dwSuggestedBufferSize = 0;
1640 This->fInfo.dwWidth = MainAVIHdr.dwWidth;
1641 This->fInfo.dwHeight = MainAVIHdr.dwHeight;
1642 LoadStringW(AVIFILE_hModule, IDS_AVIFILETYPE, This->fInfo.szFileType,
1643 ARRAY_SIZE(This->fInfo.szFileType));
1644
1645 /* go back to into header list */
1646 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
1647 return AVIERR_FILEREAD;
1648
1649 /* foreach stream exists a "LIST","strl" chunk */
1650 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
1651 /* get next nested chunk in this "LIST","strl" */
1652 if (mmioDescend(This->hmmio, &ckLIST2, &ckLIST1, 0) != S_OK)
1653 return AVIERR_FILEREAD;
1654
1655 /* nested chunk must be of type "LIST","strl" -- when not normally JUNK */
1656 if (ckLIST2.ckid == FOURCC_LIST &&
1657 ckLIST2.fccType == listtypeSTREAMHEADER) {
1658 pStream = This->ppStreams[nStream] =
1660 if (pStream == NULL)
1661 return AVIERR_MEMORY;
1663
1664 ck.ckid = 0;
1665 while (mmioDescend(This->hmmio, &ck, &ckLIST2, 0) == S_OK) {
1666 switch (ck.ckid) {
1668 if (pStream->lpHandlerData != NULL)
1669 return AVIERR_BADFORMAT;
1670 pStream->lpHandlerData = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
1671 if (pStream->lpHandlerData == NULL)
1672 return AVIERR_MEMORY;
1673 pStream->cbHandlerData = ck.cksize;
1674
1675 if (mmioRead(This->hmmio, pStream->lpHandlerData, ck.cksize) != ck.cksize)
1676 return AVIERR_FILEREAD;
1677 break;
1678 case ckidSTREAMFORMAT:
1679 if (pStream->lpFormat != NULL)
1680 return AVIERR_BADFORMAT;
1681 if (ck.cksize == 0)
1682 break;
1683
1684 pStream->lpFormat = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
1685 if (pStream->lpFormat == NULL)
1686 return AVIERR_MEMORY;
1687 pStream->cbFormat = ck.cksize;
1688
1689 if (mmioRead(This->hmmio, pStream->lpFormat, ck.cksize) != ck.cksize)
1690 return AVIERR_FILEREAD;
1691
1692 if (pStream->sInfo.fccType == streamtypeVIDEO) {
1693 LPBITMAPINFOHEADER lpbi = pStream->lpFormat;
1694
1695 /* some corrections to the video format */
1696 if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8)
1697 lpbi->biClrUsed = 1u << lpbi->biBitCount;
1698 if (lpbi->biCompression == BI_RGB && lpbi->biSizeImage == 0)
1699 lpbi->biSizeImage = DIBWIDTHBYTES(*lpbi) * lpbi->biHeight;
1700 if (lpbi->biCompression != BI_RGB && lpbi->biBitCount == 8) {
1701 if (pStream->sInfo.fccHandler == mmioFOURCC('R','L','E','0') ||
1702 pStream->sInfo.fccHandler == mmioFOURCC('R','L','E',' '))
1703 lpbi->biCompression = BI_RLE8;
1704 }
1705 if (lpbi->biCompression == BI_RGB &&
1706 (pStream->sInfo.fccHandler == 0 ||
1707 pStream->sInfo.fccHandler == mmioFOURCC('N','O','N','E')))
1708 pStream->sInfo.fccHandler = comptypeDIB;
1709
1710 /* init rcFrame if it's empty */
1711 if (IsRectEmpty(&pStream->sInfo.rcFrame))
1712 SetRect(&pStream->sInfo.rcFrame, 0, 0, lpbi->biWidth, lpbi->biHeight);
1713 }
1714 break;
1715 case ckidSTREAMHEADER:
1716 {
1717 static const WCHAR streamTypeFmt[] = {'%','4','.','4','h','s',0};
1718 static const WCHAR streamNameFmt[] = {'%','s',' ','%','s',' ','#','%','d',0};
1719
1720 AVIStreamHeader streamHdr;
1721 WCHAR szType[25];
1722 UINT count;
1723 LONG n = ck.cksize;
1724
1725 if (ck.cksize > sizeof(streamHdr))
1726 n = sizeof(streamHdr);
1727
1728 if (mmioRead(This->hmmio, (HPSTR)&streamHdr, n) != n)
1729 return AVIERR_FILEREAD;
1730
1731 pStream->sInfo.fccType = streamHdr.fccType;
1732 pStream->sInfo.fccHandler = streamHdr.fccHandler;
1733 pStream->sInfo.dwFlags = streamHdr.dwFlags;
1734 pStream->sInfo.wPriority = streamHdr.wPriority;
1735 pStream->sInfo.wLanguage = streamHdr.wLanguage;
1736 pStream->sInfo.dwInitialFrames = streamHdr.dwInitialFrames;
1737 pStream->sInfo.dwScale = streamHdr.dwScale;
1738 pStream->sInfo.dwRate = streamHdr.dwRate;
1739 pStream->sInfo.dwStart = streamHdr.dwStart;
1740 pStream->sInfo.dwLength = streamHdr.dwLength;
1741 pStream->sInfo.dwSuggestedBufferSize = 0;
1742 pStream->sInfo.dwQuality = streamHdr.dwQuality;
1743 pStream->sInfo.dwSampleSize = streamHdr.dwSampleSize;
1744 pStream->sInfo.rcFrame.left = streamHdr.rcFrame.left;
1745 pStream->sInfo.rcFrame.top = streamHdr.rcFrame.top;
1746 pStream->sInfo.rcFrame.right = streamHdr.rcFrame.right;
1747 pStream->sInfo.rcFrame.bottom = streamHdr.rcFrame.bottom;
1748 pStream->sInfo.dwEditCount = 0;
1749 pStream->sInfo.dwFormatChangeCount = 0;
1750
1751 /* generate description for stream like "filename.avi Type #n" */
1752 if (streamHdr.fccType == streamtypeVIDEO)
1754 else if (streamHdr.fccType == streamtypeAUDIO)
1756 else
1757 wsprintfW(szType, streamTypeFmt, (char*)&streamHdr.fccType);
1758
1759 /* get count of this streamtype up to this stream */
1760 count = 0;
1761 for (n = nStream; 0 <= n; n--) {
1762 if (This->ppStreams[n]->sInfo.fccHandler == streamHdr.fccType)
1763 count++;
1764 }
1765
1766 memset(pStream->sInfo.szName, 0, sizeof(pStream->sInfo.szName));
1767
1768 /* FIXME: avoid overflow -- better use wsnprintfW, which doesn't exists ! */
1769 wsprintfW(pStream->sInfo.szName, streamNameFmt,
1770 AVIFILE_BasenameW(This->szFileName), szType, count);
1771 }
1772 break;
1773 case ckidSTREAMNAME:
1774 { /* streamname will be saved as ASCII string */
1776 if (str == NULL)
1777 return AVIERR_MEMORY;
1778
1779 if (mmioRead(This->hmmio, str, ck.cksize) != ck.cksize)
1780 {
1782 return AVIERR_FILEREAD;
1783 }
1784
1785 MultiByteToWideChar(CP_ACP, 0, str, -1, pStream->sInfo.szName,
1786 ARRAY_SIZE(pStream->sInfo.szName));
1787
1789 }
1790 break;
1791 case ckidAVIPADDING:
1792 case mmioFOURCC('p','a','d','d'):
1793 break;
1794 default:
1795 WARN(": found extra chunk 0x%08X\n", ck.ckid);
1796 hr = ReadChunkIntoExtra(&pStream->extra, This->hmmio, &ck);
1797 if (FAILED(hr))
1798 return hr;
1799 };
1800 if (pStream->lpFormat != NULL && pStream->sInfo.fccType == streamtypeAUDIO)
1801 {
1802 WAVEFORMATEX *wfx = pStream->lpFormat; /* wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8; could be added */
1803 pStream->sInfo.dwSampleSize = wfx->nBlockAlign; /* to deal with corrupt wfx->nBlockAlign but Windows doesn't do this */
1804 TRACE("Block size reset to %u, chan=%u bpp=%u\n", wfx->nBlockAlign, wfx->nChannels, wfx->wBitsPerSample);
1805 pStream->sInfo.dwScale = 1;
1806 pStream->sInfo.dwRate = wfx->nSamplesPerSec;
1807 }
1808 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
1809 return AVIERR_FILEREAD;
1810 }
1811 } else {
1812 /* nested chunks in "LIST","hdrl" which are not of type "LIST","strl" */
1813 hr = ReadChunkIntoExtra(&This->fileextra, This->hmmio, &ckLIST2);
1814 if (FAILED(hr))
1815 return hr;
1816 }
1817 if (mmioAscend(This->hmmio, &ckLIST2, 0) != S_OK)
1818 return AVIERR_FILEREAD;
1819 }
1820
1821 /* read any extra headers in "LIST","hdrl" */
1822 FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, 0);
1823 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
1824 return AVIERR_FILEREAD;
1825
1826 /* search "LIST","movi" chunk in "RIFF","AVI " */
1827 ckLIST1.fccType = listtypeAVIMOVIE;
1828 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF,
1830 if (FAILED(hr))
1831 return hr;
1832
1833 This->dwMoviChunkPos = ckLIST1.dwDataOffset;
1834 This->dwIdxChunkPos = ckLIST1.cksize + ckLIST1.dwDataOffset;
1835 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
1836 return AVIERR_FILEREAD;
1837
1838 /* try to find an index */
1839 ck.ckid = ckidAVINEWINDEX;
1840 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio,
1841 &ck, &ckRIFF, MMIO_FINDCHUNK);
1842 if (SUCCEEDED(hr) && ck.cksize > 0) {
1843 if (FAILED(AVIFILE_LoadIndex(This, ck.cksize, ckLIST1.dwDataOffset)))
1844 This->fInfo.dwFlags &= ~AVIFILEINFO_HASINDEX;
1845 }
1846
1847 /* when we haven't found an index or it's bad, then build one
1848 * by parsing 'movi' chunk */
1849 if ((This->fInfo.dwFlags & AVIFILEINFO_HASINDEX) == 0) {
1850 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
1851 This->ppStreams[nStream]->lLastFrame = -1;
1852
1853 if (mmioSeek(This->hmmio, ckLIST1.dwDataOffset + sizeof(DWORD), SEEK_SET) == -1) {
1854 ERR(": Oops, can't seek back to 'movi' chunk!\n");
1855 return AVIERR_FILEREAD;
1856 }
1857
1858 /* seek through the 'movi' list until end */
1859 while (mmioDescend(This->hmmio, &ck, &ckLIST1, 0) == S_OK) {
1860 if (ck.ckid != FOURCC_LIST) {
1861 if (mmioAscend(This->hmmio, &ck, 0) == S_OK) {
1862 nStream = StreamFromFOURCC(ck.ckid);
1863
1864 if (nStream > This->fInfo.dwStreams)
1865 return AVIERR_BADFORMAT;
1866
1867 AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
1868 ck.dwDataOffset - 2 * sizeof(DWORD), 0);
1869 } else {
1870 nStream = StreamFromFOURCC(ck.ckid);
1871 WARN(": file seems to be truncated!\n");
1872 if (nStream <= This->fInfo.dwStreams &&
1873 This->ppStreams[nStream]->sInfo.dwSampleSize > 0) {
1874 ck.cksize = mmioSeek(This->hmmio, 0, SEEK_END);
1875 if (ck.cksize != -1) {
1876 ck.cksize -= ck.dwDataOffset;
1877 ck.cksize &= ~(This->ppStreams[nStream]->sInfo.dwSampleSize - 1);
1878
1879 AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
1880 ck.dwDataOffset - 2 * sizeof(DWORD), 0);
1881 }
1882 }
1883 }
1884 }
1885 }
1886 }
1887
1888 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
1889 {
1890 DWORD sugbuf = This->ppStreams[nStream]->sInfo.dwSuggestedBufferSize;
1891 if (This->fInfo.dwSuggestedBufferSize < sugbuf)
1892 This->fInfo.dwSuggestedBufferSize = sugbuf;
1893 }
1894
1895 /* find other chunks */
1896 FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckRIFF, 0);
1897
1898 return AVIERR_OK;
1899}
HMODULE AVIFILE_hModule
Definition: factory.c:39
static void AVIFILE_ConstructAVIStream(IAVIFileImpl *paf, DWORD nr, const AVISTREAMINFOW *asi)
Definition: avifile.c:1490
static HRESULT AVIFILE_LoadIndex(const IAVIFileImpl *This, DWORD size, DWORD offset)
Definition: avifile.c:1901
static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DWORD offset, DWORD flags)
Definition: avifile.c:1334
LPCWSTR AVIFILE_BasenameW(LPCWSTR szFileName) DECLSPEC_HIDDEN
Definition: factory.c:162
#define IDS_VIDEO
#define DIBWIDTHBYTES(bi)
#define IDS_AVIFILETYPE
#define IDS_AUDIO
#define streamtypeAUDIO
Definition: aviriff.h:93
#define ckidSTREAMHEADER
Definition: aviriff.h:88
#define ckidSTREAMFORMAT
Definition: aviriff.h:125
#define ARRAY_SIZE(A)
Definition: main.h:33
#define SEEK_END
Definition: cabinet.c:29
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
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 BI_RGB
Definition: precomp.h:56
HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra, HMMIO hmmio, MMCKINFO *lpck, MMCKINFO *lpckParent, UINT flags)
Definition: extrachunk.c:143
HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra, HMMIO hmmio, const MMCKINFO *lpck)
Definition: extrachunk.c:102
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define SEEK_SET
Definition: jmemansi.c:26
if(dx< 0)
Definition: linetemp.h:194
#define MMIO_FINDRIFF
Definition: mmsystem.h:552
#define MMIO_FINDCHUNK
Definition: mmsystem.h:551
#define FOURCC_LIST
Definition: mmsystem.h:565
#define mmioFOURCC(c0, c1, c2, c3)
Definition: mmsystem.h:38
#define MMIO_READ
Definition: mmsystem.h:535
char * HPSTR
Definition: mmsystem.h:1477
#define MMIO_FINDLIST
Definition: mmsystem.h:553
long LONG
Definition: pedump.c:60
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
DWORD biCompression
Definition: amvideo.idl:35
DWORD biSizeImage
Definition: amvideo.idl:36
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
DWORD dwInitialFrames
Definition: avifil32.idl:39
DWORD fccHandler
Definition: avifil32.idl:30
LPVOID lpFormat
Definition: avifile.c:67
EXTRACHUNKS extra
Definition: avifile.c:73
FOURCC ckid
Definition: mmsystem.h:1507
DWORD cksize
Definition: mmsystem.h:1508
DWORD dwDataOffset
Definition: mmsystem.h:1510
FOURCC fccType
Definition: mmsystem.h:1509
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define comptypeDIB
Definition: vfw.h:147
#define listtypeAVIMOVIE
Definition: vfw.h:898
#define listtypeSTREAMHEADER
Definition: vfw.h:892
#define AVIERR_UNSUPPORTED
Definition: vfw.h:1743
#define AVIERR_FILEOPEN
Definition: vfw.h:1753
#define AVIERR_FILEREAD
Definition: vfw.h:1751
#define listtypeAVIHEADER
Definition: vfw.h:890
#define ckidAVIPADDING
Definition: vfw.h:916
#define ckidSTREAMNAME
Definition: vfw.h:896
#define ckidAVIMAINHDR
Definition: vfw.h:891
#define ckidSTREAMHANDLERDATA
Definition: vfw.h:895
#define AVIFILEINFO_HASINDEX
Definition: vfw.h:1052
#define formtypeAVI
Definition: vfw.h:889
#define ckidAVINEWINDEX
Definition: vfw.h:901
#define AVIFILEINFO_COPYRIGHTED
Definition: vfw.h:1057
#define StreamFromFOURCC(fcc)
Definition: vfw.h:919
#define BI_RLE8
Definition: wingdi.h:35
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by IPersistFile_fnLoad().

◆ AVIFILE_LoadIndex()

static HRESULT AVIFILE_LoadIndex ( const IAVIFileImpl This,
DWORD  size,
DWORD  offset 
)
static

Definition at line 1901 of file avifile.c.

1902{
1903 AVIINDEXENTRY *lp;
1904 DWORD pos, n;
1906 BOOL bAbsolute = TRUE;
1907
1909 if (lp == NULL)
1910 return AVIERR_MEMORY;
1911
1912 /* adjust limits for index tables, so that inserting will be faster */
1913 for (n = 0; n < This->fInfo.dwStreams; n++) {
1914 IAVIStreamImpl *pStream = This->ppStreams[n];
1915
1916 pStream->lLastFrame = -1;
1917
1918 if (pStream->idxFrames != NULL) {
1919 HeapFree(GetProcessHeap(), 0, pStream->idxFrames);
1920 pStream->idxFrames = NULL;
1921 pStream->nIdxFrames = 0;
1922 }
1923
1924 if (pStream->sInfo.dwSampleSize != 0) {
1925 if (n > 0 && This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) {
1926 pStream->nIdxFrames = This->ppStreams[0]->nIdxFrames;
1927 } else if (pStream->sInfo.dwSuggestedBufferSize) {
1928 pStream->nIdxFrames =
1929 pStream->sInfo.dwLength / pStream->sInfo.dwSuggestedBufferSize;
1930 }
1931 } else
1932 pStream->nIdxFrames = pStream->sInfo.dwLength;
1933
1934 pStream->idxFrames =
1936 if (pStream->idxFrames == NULL && pStream->nIdxFrames > 0) {
1937 pStream->nIdxFrames = 0;
1938 HeapFree(GetProcessHeap(), 0, lp);
1939 return AVIERR_MEMORY;
1940 }
1941 }
1942
1943 pos = (DWORD)-1;
1944 while (size != 0) {
1946
1947 if (mmioRead(This->hmmio, (HPSTR)lp, read) != read) {
1949 break;
1950 }
1951 size -= read;
1952
1953 if (pos == (DWORD)-1)
1954 pos = offset - lp->dwChunkOffset + sizeof(DWORD);
1955
1957 pos, &bAbsolute);
1958 }
1959
1960 HeapFree(GetProcessHeap(), 0, lp);
1961
1962 /* checking ... */
1963 for (n = 0; n < This->fInfo.dwStreams; n++) {
1964 IAVIStreamImpl *pStream = This->ppStreams[n];
1965
1966 if (pStream->sInfo.dwSampleSize == 0 &&
1967 pStream->sInfo.dwLength != pStream->lLastFrame+1)
1968 ERR("stream %u length mismatch: dwLength=%u found=%d\n",
1969 n, pStream->sInfo.dwLength, pStream->lLastFrame);
1970 }
1971
1972 return hr;
1973}
#define read
Definition: acwin.h:96
#define IDX_PER_BLOCK
Definition: avifile.c:54
static HRESULT AVIFILE_ParseIndex(const IAVIFileImpl *This, AVIINDEXENTRY *lp, LONG count, DWORD pos, BOOL *bAbsolute)
Definition: avifile.c:1975
#define TRUE
Definition: types.h:120
unsigned int BOOL
Definition: ntddk_ex.h:94
#define min(a, b)
Definition: monoChain.cc:55
#define AVIFILEINFO_ISINTERLEAVED
Definition: vfw.h:1054

Referenced by AVIFILE_LoadFile().

◆ AVIFILE_ParseIndex()

static HRESULT AVIFILE_ParseIndex ( const IAVIFileImpl This,
AVIINDEXENTRY lp,
LONG  count,
DWORD  pos,
BOOL bAbsolute 
)
static

Definition at line 1975 of file avifile.c.

1977{
1978 if (lp == NULL)
1979 return AVIERR_BADPARAM;
1980
1981 for (; count > 0; count--, lp++) {
1982 WORD nStream = StreamFromFOURCC(lp->ckid);
1983
1984 if (lp->ckid == listtypeAVIRECORD || nStream == 0x7F)
1985 continue; /* skip these */
1986
1987 if (nStream > This->fInfo.dwStreams)
1988 return AVIERR_BADFORMAT;
1989
1990 /* Video frames can be either indexed in a relative position to the
1991 * "movi" chunk or in a absolute position in the file. If the index
1992 * is relative the frame offset will always be so small that it will
1993 * virtually never reach the "movi" offset so we can detect if the
1994 * video is relative very fast.
1995 */
1996 if (*bAbsolute && lp->dwChunkOffset < This->dwMoviChunkPos)
1997 *bAbsolute = FALSE;
1998
1999 if (!*bAbsolute)
2000 lp->dwChunkOffset += pos; /* make the offset absolute */
2001
2002 if (FAILED(AVIFILE_AddFrame(This->ppStreams[nStream], lp->ckid, lp->dwChunkLength, lp->dwChunkOffset, lp->dwFlags)))
2003 return AVIERR_MEMORY;
2004 }
2005
2006 return AVIERR_OK;
2007}
#define FALSE
Definition: types.h:117
unsigned short WORD
Definition: ntddk_ex.h:93
DWORD dwChunkLength
Definition: vfw.h:989
DWORD dwChunkOffset
Definition: vfw.h:988
DWORD ckid
Definition: vfw.h:986
DWORD dwFlags
Definition: vfw.h:987
#define AVIERR_BADPARAM
Definition: vfw.h:1748

Referenced by AVIFILE_LoadIndex().

◆ AVIFILE_ReadBlock()

static HRESULT AVIFILE_ReadBlock ( IAVIStreamImpl This,
DWORD  start,
LPVOID  buffer,
DWORD  size 
)
static

Definition at line 2009 of file avifile.c.

2011{
2012 /* pre-conditions */
2013 assert(This != NULL);
2014 assert(This->paf != NULL);
2015 assert(This->paf->hmmio != NULL);
2016 assert(This->sInfo.dwStart <= pos && pos < This->sInfo.dwLength);
2017 assert(pos <= This->lLastFrame);
2018
2019 /* should we read as much as block gives us? */
2020 if (size == 0 || size > This->idxFrames[pos].dwChunkLength)
2021 size = This->idxFrames[pos].dwChunkLength;
2022
2023 /* read into out own buffer or given one? */
2024 if (buffer == NULL) {
2025 /* we also read the chunk */
2026 size += 2 * sizeof(DWORD);
2027
2028 /* check that buffer is big enough -- don't trust dwSuggestedBufferSize */
2029 if (This->lpBuffer == NULL || This->cbBuffer < size) {
2030 DWORD maxSize = max(size, This->sInfo.dwSuggestedBufferSize);
2031
2032 if (This->lpBuffer == NULL) {
2033 This->lpBuffer = HeapAlloc(GetProcessHeap(), 0, maxSize);
2034 if (!This->lpBuffer) return AVIERR_MEMORY;
2035 } else {
2036 void *new_buffer = HeapReAlloc(GetProcessHeap(), 0, This->lpBuffer, maxSize);
2037 if (!new_buffer) return AVIERR_MEMORY;
2038 This->lpBuffer = new_buffer;
2039 }
2040 This->cbBuffer = maxSize;
2041 }
2042
2043 /* now read the complete chunk into our buffer */
2044 if (mmioSeek(This->paf->hmmio, This->idxFrames[pos].dwChunkOffset, SEEK_SET) == -1)
2045 return AVIERR_FILEREAD;
2046 if (mmioRead(This->paf->hmmio, (HPSTR)This->lpBuffer, size) != size)
2047 return AVIERR_FILEREAD;
2048
2049 /* check if it was the correct block which we have read */
2050 if (This->lpBuffer[0] != This->idxFrames[pos].ckid ||
2051 This->lpBuffer[1] != This->idxFrames[pos].dwChunkLength) {
2052 ERR(": block %d not found at 0x%08X\n", pos, This->idxFrames[pos].dwChunkOffset);
2053 ERR(": Index says: '%4.4s'(0x%08X) size 0x%08X\n",
2054 (char*)&This->idxFrames[pos].ckid, This->idxFrames[pos].ckid,
2055 This->idxFrames[pos].dwChunkLength);
2056 ERR(": Data says: '%4.4s'(0x%08X) size 0x%08X\n",
2057 (char*)&This->lpBuffer[0], This->lpBuffer[0], This->lpBuffer[1]);
2058 return AVIERR_FILEREAD;
2059 }
2060 } else {
2061 if (mmioSeek(This->paf->hmmio, This->idxFrames[pos].dwChunkOffset + 2 * sizeof(DWORD), SEEK_SET) == -1)
2062 return AVIERR_FILEREAD;
2063 if (mmioRead(This->paf->hmmio, buffer, size) != size)
2064 return AVIERR_FILEREAD;
2065 }
2066
2067 return AVIERR_OK;
2068}
GLuint buffer
Definition: glext.h:5915
#define max(a, b)
Definition: svc.c:63

Referenced by IAVIStream_fnRead().

◆ AVIFILE_SamplesToBlock()

static void AVIFILE_SamplesToBlock ( const IAVIStreamImpl This,
LPLONG  pos,
LPLONG  offset 
)
static

Definition at line 2070 of file avifile.c.

2071{
2072 LONG block;
2073
2074 /* pre-conditions */
2075 assert(This != NULL);
2076 assert(pos != NULL);
2077 assert(offset != NULL);
2078 assert(This->sInfo.dwSampleSize != 0);
2079 assert(*pos >= This->sInfo.dwStart);
2080
2081 /* convert start sample to start bytes */
2082 (*offset) = (*pos) - This->sInfo.dwStart;
2083 (*offset) *= This->sInfo.dwSampleSize;
2084
2085 /* convert bytes to block number */
2086 for (block = 0; block <= This->lLastFrame; block++) {
2087 if (This->idxFrames[block].dwChunkLength <= *offset)
2088 (*offset) -= This->idxFrames[block].dwChunkLength;
2089 else
2090 break;
2091 }
2092
2093 *pos = block;
2094}
static unsigned int block
Definition: xmlmemory.c:101

Referenced by IAVIStream_fnFindSample(), and IAVIStream_fnRead().

◆ AVIFILE_SaveFile()

static HRESULT AVIFILE_SaveFile ( IAVIFileImpl This)
static

Definition at line 2096 of file avifile.c.

2097{
2098 MainAVIHeader MainAVIHdr;
2099 IAVIStreamImpl* pStream;
2100 MMCKINFO ckRIFF;
2101 MMCKINFO ckLIST1;
2102 MMCKINFO ckLIST2;
2103 MMCKINFO ck;
2104 DWORD nStream;
2105 DWORD dwPos;
2106 HRESULT hr;
2107
2108 /* initialize some things */
2109 if (This->dwMoviChunkPos == 0)
2111
2112 /* written one record too much? */
2113 if (This->ckLastRecord.dwFlags & MMIO_DIRTY) {
2114 This->dwNextFramePos -= 3 * sizeof(DWORD);
2115 if (This->nIdxRecords > 0)
2116 This->nIdxRecords--;
2117 }
2118
2120
2121 assert(This->fInfo.dwScale != 0);
2122
2123 memset(&MainAVIHdr, 0, sizeof(MainAVIHdr));
2124 MainAVIHdr.dwMicroSecPerFrame = MulDiv(This->fInfo.dwRate, 1000000,
2125 This->fInfo.dwScale);
2126 MainAVIHdr.dwMaxBytesPerSec = This->fInfo.dwMaxBytesPerSec;
2128 MainAVIHdr.dwFlags = This->fInfo.dwFlags;
2129 MainAVIHdr.dwTotalFrames = This->fInfo.dwLength;
2130 MainAVIHdr.dwInitialFrames = 0;
2131 MainAVIHdr.dwStreams = This->fInfo.dwStreams;
2132 MainAVIHdr.dwSuggestedBufferSize = This->fInfo.dwSuggestedBufferSize;
2133 MainAVIHdr.dwWidth = This->fInfo.dwWidth;
2134 MainAVIHdr.dwHeight = This->fInfo.dwHeight;
2135 MainAVIHdr.dwInitialFrames = This->dwInitialFrames;
2136
2137 /* now begin writing ... */
2138 mmioSeek(This->hmmio, 0, SEEK_SET);
2139
2140 /* RIFF chunk */
2141 ckRIFF.cksize = 0;
2142 ckRIFF.fccType = formtypeAVI;
2143 if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
2144 return AVIERR_FILEWRITE;
2145
2146 /* AVI headerlist */
2147 ckLIST1.cksize = 0;
2148 ckLIST1.fccType = listtypeAVIHEADER;
2149 if (mmioCreateChunk(This->hmmio, &ckLIST1, MMIO_CREATELIST) != S_OK)
2150 return AVIERR_FILEWRITE;
2151
2152 /* MainAVIHeader */
2153 ck.ckid = ckidAVIMAINHDR;
2154 ck.cksize = sizeof(MainAVIHdr);
2155 ck.fccType = 0;
2156 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2157 return AVIERR_FILEWRITE;
2158 if (mmioWrite(This->hmmio, (HPSTR)&MainAVIHdr, ck.cksize) != ck.cksize)
2159 return AVIERR_FILEWRITE;
2160 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2161 return AVIERR_FILEWRITE;
2162
2163 /* write the headers of each stream into a separate streamheader list */
2164 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2165 AVIStreamHeader strHdr;
2166
2167 pStream = This->ppStreams[nStream];
2168
2169 /* begin the new streamheader list */
2170 ckLIST2.cksize = 0;
2171 ckLIST2.fccType = listtypeSTREAMHEADER;
2172 if (mmioCreateChunk(This->hmmio, &ckLIST2, MMIO_CREATELIST) != S_OK)
2173 return AVIERR_FILEWRITE;
2174
2175 /* create an AVIStreamHeader from the AVSTREAMINFO */
2176 strHdr.fccType = pStream->sInfo.fccType;
2177 strHdr.fccHandler = pStream->sInfo.fccHandler;
2178 strHdr.dwFlags = pStream->sInfo.dwFlags;
2179 strHdr.wPriority = pStream->sInfo.wPriority;
2180 strHdr.wLanguage = pStream->sInfo.wLanguage;
2181 strHdr.dwInitialFrames = pStream->sInfo.dwInitialFrames;
2182 strHdr.dwScale = pStream->sInfo.dwScale;
2183 strHdr.dwRate = pStream->sInfo.dwRate;
2184 strHdr.dwStart = pStream->sInfo.dwStart;
2185 strHdr.dwLength = pStream->sInfo.dwLength;
2187 strHdr.dwQuality = pStream->sInfo.dwQuality;
2188 strHdr.dwSampleSize = pStream->sInfo.dwSampleSize;
2189 strHdr.rcFrame.left = pStream->sInfo.rcFrame.left;
2190 strHdr.rcFrame.top = pStream->sInfo.rcFrame.top;
2191 strHdr.rcFrame.right = pStream->sInfo.rcFrame.right;
2192 strHdr.rcFrame.bottom = pStream->sInfo.rcFrame.bottom;
2193
2194 /* now write the AVIStreamHeader */
2196 ck.cksize = sizeof(strHdr);
2197 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2198 return AVIERR_FILEWRITE;
2199 if (mmioWrite(This->hmmio, (HPSTR)&strHdr, ck.cksize) != ck.cksize)
2200 return AVIERR_FILEWRITE;
2201 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2202 return AVIERR_FILEWRITE;
2203
2204 /* ... the hopefully ever present streamformat ... */
2206 ck.cksize = pStream->cbFormat;
2207 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2208 return AVIERR_FILEWRITE;
2209 if (pStream->lpFormat != NULL && ck.cksize > 0) {
2210 if (mmioWrite(This->hmmio, pStream->lpFormat, ck.cksize) != ck.cksize)
2211 return AVIERR_FILEWRITE;
2212 }
2213 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2214 return AVIERR_FILEWRITE;
2215
2216 /* ... some optional existing handler data ... */
2217 if (pStream->lpHandlerData != NULL && pStream->cbHandlerData > 0) {
2219 ck.cksize = pStream->cbHandlerData;
2220 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2221 return AVIERR_FILEWRITE;
2222 if (mmioWrite(This->hmmio, pStream->lpHandlerData, ck.cksize) != ck.cksize)
2223 return AVIERR_FILEWRITE;
2224 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2225 return AVIERR_FILEWRITE;
2226 }
2227
2228 /* ... some optional additional extra chunk for this stream ... */
2229 if (pStream->extra.lp != NULL && pStream->extra.cb > 0) {
2230 /* the chunk header(s) are already in the structure */
2231 if (mmioWrite(This->hmmio, pStream->extra.lp, pStream->extra.cb) != pStream->extra.cb)
2232 return AVIERR_FILEWRITE;
2233 }
2234
2235 /* ... an optional name for this stream ... */
2236 if (pStream->sInfo.szName[0]) {
2237 LPSTR str;
2238
2239 ck.ckid = ckidSTREAMNAME;
2240 ck.cksize = lstrlenW(pStream->sInfo.szName) + 1;
2241 if (ck.cksize & 1) /* align */
2242 ck.cksize++;
2243 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2244 return AVIERR_FILEWRITE;
2245
2246 /* the streamname must be saved in ASCII not Unicode */
2247 str = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
2248 if (str == NULL)
2249 return AVIERR_MEMORY;
2250 WideCharToMultiByte(CP_ACP, 0, pStream->sInfo.szName, -1, str,
2251 ck.cksize, NULL, NULL);
2252
2253 if (mmioWrite(This->hmmio, str, ck.cksize) != ck.cksize) {
2254 HeapFree(GetProcessHeap(), 0, str);
2255 return AVIERR_FILEWRITE;
2256 }
2257
2259 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2260 return AVIERR_FILEWRITE;
2261 }
2262
2263 /* close streamheader list for this stream */
2264 if (mmioAscend(This->hmmio, &ckLIST2, 0) != S_OK)
2265 return AVIERR_FILEWRITE;
2266 } /* for (0 <= nStream < MainAVIHdr.dwStreams) */
2267
2268 /* close the aviheader list */
2269 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
2270 return AVIERR_FILEWRITE;
2271
2272 /* check for padding to pre-guessed 'movi'-chunk position */
2273 dwPos = ckLIST1.dwDataOffset + ckLIST1.cksize;
2274 if (This->dwMoviChunkPos - 2 * sizeof(DWORD) > dwPos) {
2275 ck.ckid = ckidAVIPADDING;
2276 ck.cksize = This->dwMoviChunkPos - dwPos - 4 * sizeof(DWORD);
2277 assert((LONG)ck.cksize >= 0);
2278
2279 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2280 return AVIERR_FILEWRITE;
2281 if (mmioSeek(This->hmmio, ck.cksize, SEEK_CUR) == -1)
2282 return AVIERR_FILEWRITE;
2283 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2284 return AVIERR_FILEWRITE;
2285 }
2286
2287 /* now write the 'movi' chunk */
2288 mmioSeek(This->hmmio, This->dwMoviChunkPos - 2 * sizeof(DWORD), SEEK_SET);
2289 ckLIST1.cksize = 0;
2290 ckLIST1.fccType = listtypeAVIMOVIE;
2291 if (mmioCreateChunk(This->hmmio, &ckLIST1, MMIO_CREATELIST) != S_OK)
2292 return AVIERR_FILEWRITE;
2293 if (mmioSeek(This->hmmio, This->dwNextFramePos, SEEK_SET) == -1)
2294 return AVIERR_FILEWRITE;
2295 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
2296 return AVIERR_FILEWRITE;
2297
2298 /* write 'idx1' chunk */
2300 if (FAILED(hr))
2301 return hr;
2302
2303 /* write optional extra file chunks */
2304 if (This->fileextra.lp != NULL && This->fileextra.cb > 0) {
2305 /* as for the streams, are the chunk header(s) in the structure */
2306 if (mmioWrite(This->hmmio, This->fileextra.lp, This->fileextra.cb) != This->fileextra.cb)
2307 return AVIERR_FILEWRITE;
2308 }
2309
2310 /* close RIFF chunk */
2311 if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
2312 return AVIERR_FILEWRITE;
2313
2314 /* add some JUNK at end for bad parsers */
2315 memset(&ckRIFF, 0, sizeof(ckRIFF));
2316 mmioWrite(This->hmmio, (HPSTR)&ckRIFF, sizeof(ckRIFF));
2317 mmioFlush(This->hmmio, 0);
2318
2319 return AVIERR_OK;
2320}
static DWORD AVIFILE_ComputeMoviStart(IAVIFileImpl *This)
Definition: avifile.c:1457
static HRESULT AVIFILE_SaveIndex(const IAVIFileImpl *This)
Definition: avifile.c:2322
static void AVIFILE_UpdateInfo(IAVIFileImpl *This)
Definition: avifile.c:2480
#define WideCharToMultiByte
Definition: compat.h:111
MMRESULT WINAPI mmioFlush(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:961
LONG WINAPI mmioWrite(HMMIO hmmio, HPCSTR pch, LONG cch)
Definition: mmio.c:782
MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, MMCKINFO *lpck, UINT uFlags)
Definition: mmio.c:1239
#define MMIO_CREATELIST
Definition: mmsystem.h:555
#define MMIO_DIRTY
Definition: mmsystem.h:534
#define MMIO_CREATERIFF
Definition: mmsystem.h:554
#define SEEK_CUR
Definition: util.h:63
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
DWORD dwInitialFrames
Definition: vfw.h:964
DWORD dwStart
Definition: vfw.h:967
DWORD dwQuality
Definition: vfw.h:970
WORD wLanguage
Definition: vfw.h:963
DWORD dwSampleSize
Definition: vfw.h:971
FOURCC fccHandler
Definition: vfw.h:960
DWORD dwScale
Definition: vfw.h:965
FOURCC fccType
Definition: vfw.h:959
DWORD dwFlags
Definition: vfw.h:961
struct AVIStreamHeader::@3279 rcFrame
DWORD dwLength
Definition: vfw.h:968
DWORD dwSuggestedBufferSize
Definition: vfw.h:969
DWORD dwRate
Definition: vfw.h:966
WORD wPriority
Definition: vfw.h:962
LPVOID lp
Definition: extrachunk.h:33
DWORD dwWidth
Definition: vfw.h:949
DWORD dwSuggestedBufferSize
Definition: vfw.h:948
DWORD dwHeight
Definition: vfw.h:950
DWORD dwPaddingGranularity
Definition: vfw.h:943
DWORD dwStreams
Definition: vfw.h:947
DWORD dwMaxBytesPerSec
Definition: vfw.h:942
DWORD dwInitialFrames
Definition: vfw.h:946
DWORD dwFlags
Definition: vfw.h:944
DWORD dwMicroSecPerFrame
Definition: vfw.h:941
DWORD dwTotalFrames
Definition: vfw.h:945
#define AVIERR_FILEWRITE
Definition: vfw.h:1752

Referenced by IUnknown_fnRelease().

◆ AVIFILE_SaveIndex()

static HRESULT AVIFILE_SaveIndex ( const IAVIFileImpl This)
static

Definition at line 2322 of file avifile.c.

2323{
2324 IAVIStreamImpl *pStream;
2326 MMCKINFO ck;
2327 DWORD nStream;
2328 LONG n;
2329
2330 ck.ckid = ckidAVINEWINDEX;
2331 ck.cksize = 0;
2332 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2333 return AVIERR_FILEWRITE;
2334
2335 if (This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) {
2336 /* is interleaved -- write block of corresponding frames */
2337 LONG lInitialFrames = 0;
2338 LONG stepsize;
2339 LONG i;
2340
2341 if (This->ppStreams[0]->sInfo.dwSampleSize == 0)
2342 stepsize = 1;
2343 else
2344 stepsize = AVIStreamTimeToSample(&This->ppStreams[0]->IAVIStream_iface, 1000000);
2345
2346 assert(stepsize > 0);
2347
2348 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2349 if (lInitialFrames < This->ppStreams[nStream]->sInfo.dwInitialFrames)
2350 lInitialFrames = This->ppStreams[nStream]->sInfo.dwInitialFrames;
2351 }
2352
2353 for (i = -lInitialFrames; i < (LONG)This->fInfo.dwLength - lInitialFrames;
2354 i += stepsize) {
2355 DWORD nFrame = lInitialFrames + i;
2356
2357 assert(nFrame < This->nIdxRecords);
2358
2359 idx.ckid = listtypeAVIRECORD;
2360 idx.dwFlags = AVIIF_LIST;
2361 idx.dwChunkLength = This->idxRecords[nFrame].dwChunkLength;
2362 idx.dwChunkOffset = This->idxRecords[nFrame].dwChunkOffset
2363 - This->dwMoviChunkPos;
2364 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2365 return AVIERR_FILEWRITE;
2366
2367 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2368 pStream = This->ppStreams[nStream];
2369
2370 /* heave we reached start of this stream? */
2371 if (-(LONG)pStream->sInfo.dwInitialFrames > i)
2372 continue;
2373
2374 if (pStream->sInfo.dwInitialFrames < lInitialFrames)
2375 nFrame -= (lInitialFrames - pStream->sInfo.dwInitialFrames);
2376
2377 /* reached end of this stream? */
2378 if (pStream->lLastFrame <= nFrame)
2379 continue;
2380
2381 if ((pStream->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
2382 pStream->sInfo.dwFormatChangeCount != 0 &&
2383 pStream->idxFmtChanges != NULL) {
2384 DWORD pos;
2385
2386 for (pos = 0; pos < pStream->sInfo.dwFormatChangeCount; pos++) {
2387 if (pStream->idxFmtChanges[pos].ckid == nFrame) {
2388 idx.dwFlags = AVIIF_NOTIME;
2389 idx.ckid = MAKEAVICKID(cktypePALchange, pStream->nStream);
2390 idx.dwChunkLength = pStream->idxFmtChanges[pos].dwChunkLength;
2391 idx.dwChunkOffset = pStream->idxFmtChanges[pos].dwChunkOffset
2392 - This->dwMoviChunkPos;
2393
2394 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2395 return AVIERR_FILEWRITE;
2396 break;
2397 }
2398 }
2399 } /* if have formatchanges */
2400
2401 idx.ckid = pStream->idxFrames[nFrame].ckid;
2402 idx.dwFlags = pStream->idxFrames[nFrame].dwFlags;
2403 idx.dwChunkLength = pStream->idxFrames[nFrame].dwChunkLength;
2404 idx.dwChunkOffset = pStream->idxFrames[nFrame].dwChunkOffset
2405 - This->dwMoviChunkPos;
2406 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2407 return AVIERR_FILEWRITE;
2408 }
2409 }
2410 } else {
2411 /* not interleaved -- write index for each stream at once */
2412 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2413 pStream = This->ppStreams[nStream];
2414
2415 for (n = 0; n <= pStream->lLastFrame; n++) {
2416 if ((pStream->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
2417 (pStream->sInfo.dwFormatChangeCount != 0)) {
2418 DWORD pos;
2419
2420 for (pos = 0; pos < pStream->sInfo.dwFormatChangeCount; pos++) {
2421 if (pStream->idxFmtChanges[pos].ckid == n) {
2422 idx.dwFlags = AVIIF_NOTIME;
2423 idx.ckid = MAKEAVICKID(cktypePALchange, pStream->nStream);
2424 idx.dwChunkLength = pStream->idxFmtChanges[pos].dwChunkLength;
2425 idx.dwChunkOffset =
2426 pStream->idxFmtChanges[pos].dwChunkOffset - This->dwMoviChunkPos;
2427 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2428 return AVIERR_FILEWRITE;
2429 break;
2430 }
2431 }
2432 } /* if have formatchanges */
2433
2434 idx.ckid = pStream->idxFrames[n].ckid;
2435 idx.dwFlags = pStream->idxFrames[n].dwFlags;
2436 idx.dwChunkLength = pStream->idxFrames[n].dwChunkLength;
2437 idx.dwChunkOffset = pStream->idxFrames[n].dwChunkOffset
2438 - This->dwMoviChunkPos;
2439
2440 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2441 return AVIERR_FILEWRITE;
2442 }
2443 }
2444 } /* if not interleaved */
2445
2446 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2447 return AVIERR_FILEWRITE;
2448
2449 return AVIERR_OK;
2450}
unsigned int idx
Definition: utils.c:41
LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
Definition: api.c:927
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define AVIIF_NOTIME
Definition: vfw.h:982
#define MAKEAVICKID(tcc, stream)
Definition: vfw.h:923

Referenced by AVIFILE_SaveFile().

◆ AVIFILE_SearchStream()

static ULONG AVIFILE_SearchStream ( const IAVIFileImpl This,
DWORD  fccType,
LONG  lSkip 
)
static

Definition at line 2452 of file avifile.c.

2453{
2454 UINT i;
2455 UINT nStream;
2456
2457 /* pre-condition */
2458 assert(lSkip >= 0);
2459
2460 if (fcc != 0) {
2461 /* search the number of the specified stream */
2462 nStream = (ULONG)-1;
2463 for (i = 0; i < This->fInfo.dwStreams; i++) {
2464 assert(This->ppStreams[i] != NULL);
2465
2466 if (This->ppStreams[i]->sInfo.fccType == fcc) {
2467 if (lSkip == 0) {
2468 nStream = i;
2469 break;
2470 } else
2471 lSkip--;
2472 }
2473 }
2474 } else
2475 nStream = lSkip;
2476
2477 return nStream;
2478}
uint32_t ULONG
Definition: typedefs.h:59

Referenced by IAVIFile_fnDeleteStream(), and IAVIFile_fnGetStream().

◆ AVIFILE_UpdateInfo()

static void AVIFILE_UpdateInfo ( IAVIFileImpl This)
static

Definition at line 2480 of file avifile.c.

2481{
2482 UINT i;
2483
2484 /* pre-conditions */
2485 assert(This != NULL);
2486
2487 This->fInfo.dwMaxBytesPerSec = 0;
2489 This->fInfo.dwSuggestedBufferSize = 0;
2490 This->fInfo.dwWidth = 0;
2491 This->fInfo.dwHeight = 0;
2492 This->fInfo.dwScale = 0;
2493 This->fInfo.dwRate = 0;
2494 This->fInfo.dwLength = 0;
2495 This->dwInitialFrames = 0;
2496
2497 for (i = 0; i < This->fInfo.dwStreams; i++) {
2498 AVISTREAMINFOW *psi;
2499 DWORD n;
2500
2501 /* pre-conditions */
2502 assert(This->ppStreams[i] != NULL);
2503
2504 psi = &This->ppStreams[i]->sInfo;
2505 assert(psi->dwScale != 0);
2506 assert(psi->dwRate != 0);
2507
2508 if (i == 0) {
2509 /* use first stream timings as base */
2510 This->fInfo.dwScale = psi->dwScale;
2511 This->fInfo.dwRate = psi->dwRate;
2512 This->fInfo.dwLength = psi->dwLength;
2513 } else {
2514 n = AVIStreamSampleToSample(&This->ppStreams[0]->IAVIStream_iface,
2515 &This->ppStreams[i]->IAVIStream_iface, psi->dwLength);
2516 if (This->fInfo.dwLength < n)
2517 This->fInfo.dwLength = n;
2518 }
2519
2520 if (This->dwInitialFrames < psi->dwInitialFrames)
2521 This->dwInitialFrames = psi->dwInitialFrames;
2522
2523 if (This->fInfo.dwSuggestedBufferSize < psi->dwSuggestedBufferSize)
2524 This->fInfo.dwSuggestedBufferSize = psi->dwSuggestedBufferSize;
2525
2526 if (psi->dwSampleSize != 0) {
2527 /* fixed sample size -- exact computation */
2528 This->fInfo.dwMaxBytesPerSec += MulDiv(psi->dwSampleSize, psi->dwRate,
2529 psi->dwScale);
2530 } else {
2531 /* variable sample size -- only upper limit */
2532 This->fInfo.dwMaxBytesPerSec += MulDiv(psi->dwSuggestedBufferSize,
2533 psi->dwRate, psi->dwScale);
2534
2535 /* update dimensions */
2536 n = psi->rcFrame.right - psi->rcFrame.left;
2537 if (This->fInfo.dwWidth < n)
2538 This->fInfo.dwWidth = n;
2539 n = psi->rcFrame.bottom - psi->rcFrame.top;
2540 if (This->fInfo.dwHeight < n)
2541 This->fInfo.dwHeight = n;
2542 }
2543 }
2544}
#define AVIStreamSampleToSample(pavi1, pavi2, samp2)
Definition: vfw.h:1442

Referenced by AVIFILE_SaveFile(), IAVIFile_fnCreateStream(), and IAVIFile_fnInfo().

◆ AVIFILE_WriteBlock()

static HRESULT AVIFILE_WriteBlock ( IAVIStreamImpl This,
DWORD  block,
FOURCC  ckid,
DWORD  flags,
LPCVOID  buffer,
LONG  size 
)
static

Definition at line 2546 of file avifile.c.

2549{
2550 MMCKINFO ck;
2551
2552 ck.ckid = ckid;
2553 ck.cksize = size;
2554 ck.fccType = 0;
2555
2556 /* if no frame/block is already written, we must compute start of movi chunk */
2557 if (This->paf->dwMoviChunkPos == 0)
2559
2560 if (mmioSeek(This->paf->hmmio, This->paf->dwNextFramePos, SEEK_SET) == -1)
2561 return AVIERR_FILEWRITE;
2562
2563 if (mmioCreateChunk(This->paf->hmmio, &ck, 0) != S_OK)
2564 return AVIERR_FILEWRITE;
2565 if (buffer != NULL && size > 0) {
2566 if (mmioWrite(This->paf->hmmio, buffer, size) != size)
2567 return AVIERR_FILEWRITE;
2568 }
2569 if (mmioAscend(This->paf->hmmio, &ck, 0) != S_OK)
2570 return AVIERR_FILEWRITE;
2571
2572 This->paf->fDirty = TRUE;
2573 This->paf->dwNextFramePos = mmioSeek(This->paf->hmmio, 0, SEEK_CUR);
2574
2575 return AVIFILE_AddFrame(This, ckid, size,
2576 ck.dwDataOffset - 2 * sizeof(DWORD), flags);
2577}

Referenced by IAVIStream_fnWrite().

◆ IAVIFile_fnAddRef()

static ULONG WINAPI IAVIFile_fnAddRef ( IAVIFile iface)
static

Definition at line 261 of file avifile.c.

262{
264
265 return IUnknown_AddRef(This->outer_unk);
266}
static IAVIFileImpl * impl_from_IAVIFile(IAVIFile *iface)
Definition: avifile.c:125

◆ IAVIFile_fnCreateStream()

static HRESULT WINAPI IAVIFile_fnCreateStream ( IAVIFile iface,
IAVIStream **  avis,
AVISTREAMINFOW asi 
)
static

Definition at line 322 of file avifile.c.

324{
326 DWORD n;
327
328 TRACE("(%p,%p,%p)\n", iface, avis, asi);
329
330 /* check parameters */
331 if (avis == NULL || asi == NULL)
332 return AVIERR_BADPARAM;
333
334 *avis = NULL;
335
336 /* Does the user have write permission? */
337 if ((This->uMode & MMIO_RWMODE) == 0)
338 return AVIERR_READONLY;
339
340 /* Can we add another stream? */
341 n = This->fInfo.dwStreams;
342 if (n >= MAX_AVISTREAMS || This->dwMoviChunkPos != 0) {
343 /* already reached max nr of streams
344 * or have already written frames to disk */
345 return AVIERR_UNSUPPORTED;
346 }
347
348 /* check AVISTREAMINFO for some really needed things */
349 if (asi->fccType == 0 || asi->dwScale == 0 || asi->dwRate == 0)
350 return AVIERR_BADFORMAT;
351
352 /* now it seems to be save to add the stream */
353 assert(This->ppStreams[n] == NULL);
355 sizeof(IAVIStreamImpl));
356 if (This->ppStreams[n] == NULL)
357 return AVIERR_MEMORY;
358
359 /* initialize the new allocated stream */
361
362 This->fInfo.dwStreams++;
363 This->fDirty = TRUE;
364
365 /* update our AVIFILEINFO structure */
367
368 /* return it */
369 *avis = &This->ppStreams[n]->IAVIStream_iface;
370 IAVIStream_AddRef(*avis);
371
372 return AVIERR_OK;
373}
#define MMIO_RWMODE
Definition: mmsystem.h:526
#define IAVIStream_AddRef(p)
Definition: vfw.h:1176
#define AVIERR_READONLY
Definition: vfw.h:1756

◆ IAVIFile_fnDeleteStream()

static HRESULT WINAPI IAVIFile_fnDeleteStream ( IAVIFile iface,
DWORD  fccType,
LONG  lParam 
)
static

Definition at line 446 of file avifile.c.

447{
449 ULONG nStream;
450
451 TRACE("(%p,0x%08X,%d)\n", iface, fccType, lParam);
452
453 /* check parameter */
454 if (lParam < 0)
455 return AVIERR_BADPARAM;
456
457 /* Have user write permissions? */
458 if ((This->uMode & MMIO_RWMODE) == 0)
459 return AVIERR_READONLY;
460
461 nStream = AVIFILE_SearchStream(This, fccType, lParam);
462
463 /* Does the requested stream exist? */
464 if (nStream < This->fInfo.dwStreams &&
465 This->ppStreams[nStream] != NULL) {
466 /* ... so delete it now */
467 HeapFree(GetProcessHeap(), 0, This->ppStreams[nStream]);
468 This->fInfo.dwStreams--;
469 if (nStream < This->fInfo.dwStreams)
470 memmove(&This->ppStreams[nStream], &This->ppStreams[nStream + 1],
471 (This->fInfo.dwStreams - nStream) * sizeof(This->ppStreams[0]));
472
473 This->ppStreams[This->fInfo.dwStreams] = NULL;
474 This->fDirty = TRUE;
475
476 /* This->fInfo will be updated further when asked for */
477 return AVIERR_OK;
478 } else
479 return AVIERR_NODATA;
480}
static ULONG AVIFILE_SearchStream(const IAVIFileImpl *This, DWORD fccType, LONG lSkip)
Definition: avifile.c:2452
LPARAM lParam
Definition: combotst.c:139
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define AVIERR_NODATA
Definition: vfw.h:1757

◆ IAVIFile_fnEndRecord()

static HRESULT WINAPI IAVIFile_fnEndRecord ( IAVIFile iface)
static

Definition at line 405 of file avifile.c.

406{
408
409 TRACE("(%p)\n",iface);
410
411 if ((This->uMode & MMIO_RWMODE) == 0)
412 return AVIERR_READONLY;
413
414 This->fDirty = TRUE;
415
416 /* no frames written to any stream? -- compute start of 'movi'-chunk */
417 if (This->dwMoviChunkPos == 0)
419
420 This->fInfo.dwFlags |= AVIFILEINFO_ISINTERLEAVED;
421
422 /* already written frames to any stream, ... */
423 if (This->ckLastRecord.dwFlags & MMIO_DIRTY) {
424 /* close last record */
425 if (mmioAscend(This->hmmio, &This->ckLastRecord, 0) != 0)
426 return AVIERR_FILEWRITE;
427
429
430 if (This->fInfo.dwSuggestedBufferSize < This->ckLastRecord.cksize + 3 * sizeof(DWORD))
431 This->fInfo.dwSuggestedBufferSize = This->ckLastRecord.cksize + 3 * sizeof(DWORD);
432 }
433
434 /* write out a new record into file, but don't close it */
435 This->ckLastRecord.cksize = 0;
436 This->ckLastRecord.fccType = listtypeAVIRECORD;
437 if (mmioSeek(This->hmmio, This->dwNextFramePos, SEEK_SET) == -1)
438 return AVIERR_FILEWRITE;
439 if (mmioCreateChunk(This->hmmio, &This->ckLastRecord, MMIO_CREATELIST) != 0)
440 return AVIERR_FILEWRITE;
441 This->dwNextFramePos += 3 * sizeof(DWORD);
442
443 return AVIERR_OK;
444}
static HRESULT AVIFILE_AddRecord(IAVIFileImpl *This)
Definition: avifile.c:1422

◆ IAVIFile_fnGetStream()

static HRESULT WINAPI IAVIFile_fnGetStream ( IAVIFile iface,
IAVIStream **  avis,
DWORD  fccType,
LONG  lParam 
)
static

Definition at line 295 of file avifile.c.

297{
299 ULONG nStream;
300
301 TRACE("(%p,%p,0x%08X,%d)\n", iface, avis, fccType, lParam);
302
303 if (avis == NULL || lParam < 0)
304 return AVIERR_BADPARAM;
305
306 nStream = AVIFILE_SearchStream(This, fccType, lParam);
307
308 /* Does the requested stream exist? */
309 if (nStream < This->fInfo.dwStreams &&
310 This->ppStreams[nStream] != NULL) {
311 *avis = &This->ppStreams[nStream]->IAVIStream_iface;
312 IAVIStream_AddRef(*avis);
313
314 return AVIERR_OK;
315 }
316
317 /* Sorry, but the specified stream doesn't exist */
318 *avis = NULL;
319 return AVIERR_NODATA;
320}

◆ IAVIFile_fnInfo()

static HRESULT WINAPI IAVIFile_fnInfo ( IAVIFile iface,
AVIFILEINFOW afi,
LONG  size 
)
static

Definition at line 275 of file avifile.c.

276{
278
279 TRACE("(%p,%p,%d)\n",iface,afi,size);
280
281 if (afi == NULL)
282 return AVIERR_BADPARAM;
283 if (size < 0)
284 return AVIERR_BADSIZE;
285
287
288 memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));
289
290 if ((DWORD)size < sizeof(This->fInfo))
292 return AVIERR_OK;
293}
#define AVIERR_BADSIZE
Definition: vfw.h:1749
#define AVIERR_BUFFERTOOSMALL
Definition: vfw.h:1758

◆ IAVIFile_fnQueryInterface()

static HRESULT WINAPI IAVIFile_fnQueryInterface ( IAVIFile iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 254 of file avifile.c.

255{
257
258 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
259}

◆ IAVIFile_fnReadData()

static HRESULT WINAPI IAVIFile_fnReadData ( IAVIFile iface,
DWORD  ckid,
void lpData,
LONG size 
)
static

Definition at line 396 of file avifile.c.

397{
399
400 TRACE("(%p,0x%08X,%p,%p)\n", iface, ckid, lpData, size);
401
402 return ReadExtraChunk(&This->fileextra, ckid, lpData, size);
403}
HRESULT ReadExtraChunk(const EXTRACHUNKS *extra, FOURCC ckid, LPVOID lpData, LPLONG size)
Definition: extrachunk.c:32

◆ IAVIFile_fnRelease()

static ULONG WINAPI IAVIFile_fnRelease ( IAVIFile iface)
static

Definition at line 268 of file avifile.c.

269{
271
272 return IUnknown_Release(This->outer_unk);
273}

◆ IAVIFile_fnWriteData()

static HRESULT WINAPI IAVIFile_fnWriteData ( IAVIFile iface,
DWORD  ckid,
void lpData,
LONG  size 
)
static

Definition at line 375 of file avifile.c.

376{
378
379 TRACE("(%p,0x%08X,%p,%d)\n", iface, ckid, lpData, size);
380
381 /* check parameters */
382 if (lpData == NULL)
383 return AVIERR_BADPARAM;
384 if (size < 0)
385 return AVIERR_BADSIZE;
386
387 /* Do we have write permission? */
388 if ((This->uMode & MMIO_RWMODE) == 0)
389 return AVIERR_READONLY;
390
391 This->fDirty = TRUE;
392
393 return WriteExtraChunk(&This->fileextra, ckid, lpData, size);
394}
HRESULT WriteExtraChunk(LPEXTRACHUNKS extra, FOURCC ckid, LPCVOID lpData, LONG size)
Definition: extrachunk.c:70

◆ IAVIStream_fnAddRef()

static ULONG WINAPI IAVIStream_fnAddRef ( IAVIStream iface)
static

Definition at line 694 of file avifile.c.

695{
698
699 TRACE("(%p) ref=%d\n", This, ref);
700
701 /* also add ref to parent, so that it doesn't kill us */
702 if (This->paf != NULL)
703 IAVIFile_AddRef(&This->paf->IAVIFile_iface);
704
705 return ref;
706}
#define InterlockedIncrement
Definition: armddk.h:53
static IAVIStreamImpl * impl_from_IAVIStream(IAVIStream *iface)
Definition: avifile.c:86
Definition: send.c:48
#define IAVIFile_AddRef(p)
Definition: vfw.h:1603

◆ IAVIStream_fnCreate()

static HRESULT WINAPI IAVIStream_fnCreate ( IAVIStream iface,
LPARAM  lParam1,
LPARAM  lParam2 
)
static

Definition at line 721 of file avifile.c.

722{
723 TRACE("(%p,0x%08lX,0x%08lX)\n", iface, lParam1, lParam2);
724
725 /* This IAVIStream interface needs an AVIFile */
726 return AVIERR_UNSUPPORTED;
727}

◆ IAVIStream_fnDelete()

static HRESULT WINAPI IAVIStream_fnDelete ( IAVIStream iface,
LONG  start,
LONG  samples 
)
static

Definition at line 1201 of file avifile.c.

1202{
1204
1205 FIXME("(%p,%d,%d): stub\n", iface, start, samples);
1206
1207 /* check parameters */
1208 if (start < 0 || samples < 0)
1209 return AVIERR_BADPARAM;
1210
1211 /* Delete before start of stream? */
1212 if (start + samples < This->sInfo.dwStart)
1213 return AVIERR_OK;
1214
1215 /* Delete after end of stream? */
1216 if (start > This->sInfo.dwLength)
1217 return AVIERR_OK;
1218
1219 /* For the rest we need write permissions */
1220 if ((This->paf->uMode & MMIO_RWMODE) == 0)
1221 return AVIERR_READONLY;
1222
1223 /* 1. overwrite the data with JUNK
1224 *
1225 * if ISINTERLEAVED {
1226 * 2. concat all neighboured JUNK-blocks in this record to one
1227 * 3. if this record only contains JUNK and is at end set dwNextFramePos
1228 * to start of this record, repeat this.
1229 * } else {
1230 * 2. concat all neighboured JUNK-blocks.
1231 * 3. if the JUNK block is at the end, then set dwNextFramePos to
1232 * start of this block.
1233 * }
1234 */
1235
1236 return AVIERR_UNSUPPORTED;
1237}
#define FIXME(fmt,...)
Definition: debug.h:114
GLuint start
Definition: gl.h:1545
GLsizei samples
Definition: glext.h:7006

◆ IAVIStream_fnFindSample()

static LONG WINAPI IAVIStream_fnFindSample ( IAVIStream iface,
LONG  pos,
LONG  flags 
)
static

Definition at line 747 of file avifile.c.

748{
750 LONG offset = 0;
751
752 TRACE("(%p,%d,0x%08X)\n",iface,pos,flags);
753
754 if (flags & FIND_FROM_START) {
755 pos = This->sInfo.dwStart;
757 flags |= FIND_NEXT;
758 }
759
760 if (This->sInfo.dwSampleSize != 0) {
761 /* convert samples into block number with offset */
763 }
764
765 if (flags & FIND_TYPE) {
766 if (flags & FIND_KEY) {
767 while (0 <= pos && pos <= This->lLastFrame) {
768 if (This->idxFrames[pos].dwFlags & AVIIF_KEYFRAME)
769 goto RETURN_FOUND;
770
771 if (flags & FIND_NEXT)
772 pos++;
773 else
774 pos--;
775 };
776 } else if (flags & FIND_ANY) {
777 while (0 <= pos && pos <= This->lLastFrame) {
778 if (This->idxFrames[pos].dwChunkLength > 0)
779 goto RETURN_FOUND;
780
781 if (flags & FIND_NEXT)
782 pos++;
783 else
784 pos--;
785
786 };
787 } else if ((flags & FIND_FORMAT) && This->idxFmtChanges != NULL &&
788 This->sInfo.fccType == streamtypeVIDEO) {
789 if (flags & FIND_NEXT) {
790 ULONG n;
791
792 for (n = 0; n < This->sInfo.dwFormatChangeCount; n++)
793 if (This->idxFmtChanges[n].ckid >= pos) {
794 pos = This->idxFmtChanges[n].ckid;
795 goto RETURN_FOUND;
796 }
797 } else {
798 LONG n;
799
800 for (n = (LONG)This->sInfo.dwFormatChangeCount; n >= 0; n--) {
801 if (This->idxFmtChanges[n].ckid <= pos) {
802 pos = This->idxFmtChanges[n].ckid;
803 goto RETURN_FOUND;
804 }
805 }
806
807 if (pos > (LONG)This->sInfo.dwStart)
808 return 0; /* format changes always for first frame */
809 }
810 }
811
812 return -1;
813 }
814
815 RETURN_FOUND:
816 if (pos < (LONG)This->sInfo.dwStart)
817 return -1;
818
819 switch (flags & FIND_RET) {
820 case FIND_LENGTH:
821 /* physical size */
822 pos = This->idxFrames[pos].dwChunkLength;
823 break;
824 case FIND_OFFSET:
825 /* physical position */
826 pos = This->idxFrames[pos].dwChunkOffset + 2 * sizeof(DWORD)
827 + offset * This->sInfo.dwSampleSize;
828 break;
829 case FIND_SIZE:
830 /* logical size */
831 if (This->sInfo.dwSampleSize)
832 pos = This->sInfo.dwSampleSize;
833 else
834 pos = 1;
835 break;
836 case FIND_INDEX:
837 FIXME(": FIND_INDEX flag is not supported!\n");
838 /* This is an index in the index-table on disc. */
839 break;
840 }; /* else logical position */
841
842 return pos;
843}
static void AVIFILE_SamplesToBlock(const IAVIStreamImpl *This, LPLONG pos, LPLONG offset)
Definition: avifile.c:2070
#define FIND_NEXT
Definition: vfw.h:1118
#define FIND_OFFSET
Definition: vfw.h:1130
#define FIND_LENGTH
Definition: vfw.h:1129
#define FIND_INDEX
Definition: vfw.h:1132
#define FIND_PREV
Definition: vfw.h:1119
#define FIND_SIZE
Definition: vfw.h:1131
#define FIND_TYPE
Definition: vfw.h:1122
#define FIND_ANY
Definition: vfw.h:1124
#define FIND_FROM_START
Definition: vfw.h:1120
#define FIND_RET
Definition: vfw.h:1127
#define FIND_KEY
Definition: vfw.h:1123
#define FIND_FORMAT
Definition: vfw.h:1125

Referenced by IAVIStream_fnReadFormat().

◆ IAVIStream_fnInfo()

static HRESULT WINAPI IAVIStream_fnInfo ( IAVIStream iface,
AVISTREAMINFOW psi,
LONG  size 
)
static

Definition at line 729 of file avifile.c.

730{
732
733 TRACE("(%p,%p,%d)\n", iface, psi, size);
734
735 if (psi == NULL)
736 return AVIERR_BADPARAM;
737 if (size < 0)
738 return AVIERR_BADSIZE;
739
740 memcpy(psi, &This->sInfo, min((DWORD)size, sizeof(This->sInfo)));
741
742 if ((DWORD)size < sizeof(This->sInfo))
744 return AVIERR_OK;
745}

◆ IAVIStream_fnQueryInterface()

static HRESULT WINAPI IAVIStream_fnQueryInterface ( IAVIStream iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 671 of file avifile.c.

672{
674
675 TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
676
677 if (!ppv) {
678 WARN("invalid parameter\n");
679 return E_INVALIDARG;
680 }
681 *ppv = NULL;
682
683 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IAVIStream, riid)) {
684 *ppv = iface;
685 IAVIStream_AddRef(iface);
686
687 return S_OK;
688 }
689 /* FIXME: IAVIStreaming interface */
690
691 return E_NOINTERFACE;
692}
const GUID IID_IUnknown
#define E_INVALIDARG
Definition: ddrawi.h:101
#define debugstr_guid
Definition: kernel32.h:35
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define E_NOINTERFACE
Definition: winerror.h:2364

◆ IAVIStream_fnRead()

static HRESULT WINAPI IAVIStream_fnRead ( IAVIStream iface,
LONG  start,
LONG  samples,
void buffer,
LONG  buffersize,
LONG bytesread,
LONG samplesread 
)
static

Definition at line 992 of file avifile.c.

994{
996 DWORD size;
997 HRESULT hr;
998
999 TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", iface, start, samples, buffer,
1000 buffersize, bytesread, samplesread);
1001
1002 /* clear return parameters if given */
1003 if (bytesread != NULL)
1004 *bytesread = 0;
1005 if (samplesread != NULL)
1006 *samplesread = 0;
1007
1008 /* check parameters */
1009 if ((LONG)This->sInfo.dwStart > start)
1010 return AVIERR_NODATA; /* couldn't read before start of stream */
1011 if (This->sInfo.dwStart + This->sInfo.dwLength < (DWORD)start)
1012 return AVIERR_NODATA; /* start is past end of stream */
1013
1014 /* should we read as much as possible? */
1015 if (samples == -1) {
1016 /* User should know how much we have read */
1017 if (bytesread == NULL && samplesread == NULL)
1018 return AVIERR_BADPARAM;
1019
1020 if (This->sInfo.dwSampleSize != 0)
1021 samples = buffersize / This->sInfo.dwSampleSize;
1022 else
1023 samples = 1;
1024 }
1025
1026 /* limit to end of stream */
1027 if ((LONG)This->sInfo.dwLength < samples)
1028 samples = This->sInfo.dwLength;
1029 if ((start - This->sInfo.dwStart) > (This->sInfo.dwLength - samples))
1030 samples = This->sInfo.dwLength - (start - This->sInfo.dwStart);
1031
1032 /* nothing to read? Then leave ... */
1033 if (samples == 0)
1034 return AVIERR_OK;
1035
1036 if (This->sInfo.dwSampleSize != 0) {
1037 /* fixed samplesize -- we can read over frame/block boundaries */
1038 LONG block = start;
1039 LONG offset = 0;
1040
1041 if (!buffer)
1042 {
1043 if (bytesread)
1044 *bytesread = samples*This->sInfo.dwSampleSize;
1045 if (samplesread)
1046 *samplesread = samples;
1047 return AVIERR_OK;
1048 }
1049
1050 /* convert start sample to block,offset pair */
1052
1053 /* convert samples to bytes */
1054 samples *= This->sInfo.dwSampleSize;
1055
1056 while (samples > 0 && buffersize > 0) {
1057 LONG blocksize;
1058 if (block != This->dwCurrentFrame) {
1060 if (FAILED(hr))
1061 return hr;
1062 }
1063
1064 size = min((DWORD)samples, (DWORD)buffersize);
1065 blocksize = This->lpBuffer[1];
1066 TRACE("blocksize = %u\n",blocksize);
1067 size = min(size, blocksize - offset);
1068 memcpy(buffer, ((BYTE*)&This->lpBuffer[2]) + offset, size);
1069
1070 block++;
1071 offset = 0;
1072 buffer = ((LPBYTE)buffer)+size;
1073 samples -= size;
1074 buffersize -= size;
1075
1076 /* fill out return parameters if given */
1077 if (bytesread != NULL)
1078 *bytesread += size;
1079 if (samplesread != NULL)
1080 *samplesread += size / This->sInfo.dwSampleSize;
1081 }
1082
1083 if (samples == 0)
1084 return AVIERR_OK;
1085 else
1086 return AVIERR_BUFFERTOOSMALL;
1087 } else {
1088 /* variable samplesize -- we can only read one full frame/block */
1089 if (samples > 1)
1090 samples = 1;
1091
1092 assert(start <= This->lLastFrame);
1093 size = This->idxFrames[start].dwChunkLength;
1094 if (buffer != NULL && buffersize >= size) {
1096 if (FAILED(hr))
1097 return hr;
1098 } else if (buffer != NULL)
1099 return AVIERR_BUFFERTOOSMALL;
1100
1101 /* fill out return parameters if given */
1102 if (bytesread != NULL)
1103 *bytesread = size;
1104 if (samplesread != NULL)
1105 *samplesread = samples;
1106
1107 return AVIERR_OK;
1108 }
1109}
static HRESULT AVIFILE_ReadBlock(IAVIStreamImpl *This, DWORD start, LPVOID buffer, DWORD size)
Definition: avifile.c:2009
unsigned char * LPBYTE
Definition: typedefs.h:53
unsigned char BYTE
Definition: xxhash.c:193

◆ IAVIStream_fnReadData()

static HRESULT WINAPI IAVIStream_fnReadData ( IAVIStream iface,
DWORD  fcc,
void lp,
LONG lpread 
)
static

Definition at line 1239 of file avifile.c.

1240{
1242
1243 TRACE("(%p,0x%08X,%p,%p)\n", iface, fcc, lp, lpread);
1244
1245 if (fcc == ckidSTREAMHANDLERDATA) {
1246 if (This->lpHandlerData != NULL && This->cbHandlerData > 0) {
1247 if (lp == NULL || *lpread <= 0) {
1248 *lpread = This->cbHandlerData;
1249 return AVIERR_OK;
1250 }
1251
1252 memcpy(lp, This->lpHandlerData, min(This->cbHandlerData, *lpread));
1253 if (*lpread < This->cbHandlerData)
1254 return AVIERR_BUFFERTOOSMALL;
1255 return AVIERR_OK;
1256 } else
1257 return AVIERR_NODATA;
1258 } else
1259 return ReadExtraChunk(&This->extra, fcc, lp, lpread);
1260}

◆ IAVIStream_fnReadFormat()

static HRESULT WINAPI IAVIStream_fnReadFormat ( IAVIStream iface,
LONG  pos,
void format,
LONG formatsize 
)
static

Definition at line 845 of file avifile.c.

847{
849
850 TRACE("(%p,%d,%p,%p)\n", iface, pos, format, formatsize);
851
852 if (formatsize == NULL)
853 return AVIERR_BADPARAM;
854
855 /* only interested in needed buffersize? */
856 if (format == NULL || *formatsize <= 0) {
857 *formatsize = This->cbFormat;
858
859 return AVIERR_OK;
860 }
861
862 /* copy initial format (only as much as will fit) */
863 memcpy(format, This->lpFormat, min(*(DWORD*)formatsize, This->cbFormat));
864 if (*(DWORD*)formatsize < This->cbFormat) {
865 *formatsize = This->cbFormat;
867 }
868
869 /* Could format change? When yes will it change? */
870 if ((This->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
871 pos > This->sInfo.dwStart) {
872 LONG lLastFmt;
873
875 if (lLastFmt > 0) {
876 FIXME(": need to read formatchange for %d -- unimplemented!\n",lLastFmt);
877 }
878 }
879
880 *formatsize = This->cbFormat;
881 return AVIERR_OK;
882}
static LONG WINAPI IAVIStream_fnFindSample(IAVIStream *iface, LONG pos, LONG flags)
Definition: avifile.c:747
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546

◆ IAVIStream_fnRelease()

static ULONG WINAPI IAVIStream_fnRelease ( IAVIStream iface)
static

Definition at line 708 of file avifile.c.

709{
712
713 TRACE("(%p) ref=%d\n", This, ref);
714
715 if (This->paf != NULL)
716 IAVIFile_Release(&This->paf->IAVIFile_iface);
717
718 return ref;
719}
#define InterlockedDecrement
Definition: armddk.h:52
#define IAVIFile_Release(p)
Definition: vfw.h:1604

◆ IAVIStream_fnSetFormat()

static HRESULT WINAPI IAVIStream_fnSetFormat ( IAVIStream iface,
LONG  pos,
void format,
LONG  formatsize 
)
static

Definition at line 884 of file avifile.c.

886{
888 BITMAPINFOHEADER *lpbiNew = format;
889
890 TRACE("(%p,%d,%p,%d)\n", iface, pos, format, formatsize);
891
892 /* check parameters */
893 if (format == NULL || formatsize <= 0)
894 return AVIERR_BADPARAM;
895
896 /* Do we have write permission? */
897 if ((This->paf->uMode & MMIO_RWMODE) == 0)
898 return AVIERR_READONLY;
899
900 /* can only set format before frame is written! */
901 if (This->lLastFrame > pos)
902 return AVIERR_UNSUPPORTED;
903
904 /* initial format or a formatchange? */
905 if (This->lpFormat == NULL) {
906 /* initial format */
907 if (This->paf->dwMoviChunkPos != 0)
908 return AVIERR_ERROR; /* user has used API in wrong sequence! */
909
910 This->lpFormat = HeapAlloc(GetProcessHeap(), 0, formatsize);
911 if (This->lpFormat == NULL)
912 return AVIERR_MEMORY;
913 This->cbFormat = formatsize;
914
915 memcpy(This->lpFormat, format, formatsize);
916
917 /* update some infos about stream */
918 if (This->sInfo.fccType == streamtypeVIDEO) {
919 LONG lDim;
920
921 lDim = This->sInfo.rcFrame.right - This->sInfo.rcFrame.left;
922 if (lDim < lpbiNew->biWidth)
923 This->sInfo.rcFrame.right = This->sInfo.rcFrame.left + lpbiNew->biWidth;
924 lDim = This->sInfo.rcFrame.bottom - This->sInfo.rcFrame.top;
925 if (lDim < lpbiNew->biHeight)
926 This->sInfo.rcFrame.bottom = This->sInfo.rcFrame.top + lpbiNew->biHeight;
927 } else if (This->sInfo.fccType == streamtypeAUDIO)
928 This->sInfo.dwSampleSize = ((LPWAVEFORMATEX)This->lpFormat)->nBlockAlign;
929
930 return AVIERR_OK;
931 } else {
932 MMCKINFO ck;
933 LPBITMAPINFOHEADER lpbiOld = This->lpFormat;
934 RGBQUAD *rgbNew = (RGBQUAD*)((LPBYTE)lpbiNew + lpbiNew->biSize);
935 AVIPALCHANGE *lppc = NULL;
936 UINT n;
937
938 /* perhaps format change, check it ... */
939 if (This->cbFormat != formatsize)
940 return AVIERR_UNSUPPORTED;
941
942 /* no format change, only the initial one */
943 if (memcmp(This->lpFormat, format, formatsize) == 0)
944 return AVIERR_OK;
945
946 /* check that's only the palette, which changes */
947 if (lpbiOld->biSize != lpbiNew->biSize ||
948 lpbiOld->biWidth != lpbiNew->biWidth ||
949 lpbiOld->biHeight != lpbiNew->biHeight ||
950 lpbiOld->biPlanes != lpbiNew->biPlanes ||
951 lpbiOld->biBitCount != lpbiNew->biBitCount ||
952 lpbiOld->biCompression != lpbiNew->biCompression ||
953 lpbiOld->biClrUsed != lpbiNew->biClrUsed)
954 return AVIERR_UNSUPPORTED;
955
956 This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
957
958 /* simply say all colors have changed */
959 ck.ckid = MAKEAVICKID(cktypePALchange, This->nStream);
960 ck.cksize = 2 * sizeof(WORD) + lpbiOld->biClrUsed * sizeof(PALETTEENTRY);
961 lppc = HeapAlloc(GetProcessHeap(), 0, ck.cksize);
962 if (lppc == NULL)
963 return AVIERR_MEMORY;
964
965 lppc->bFirstEntry = 0;
966 lppc->bNumEntries = (lpbiOld->biClrUsed < 256 ? lpbiOld->biClrUsed : 0);
967 lppc->wFlags = 0;
968 for (n = 0; n < lpbiOld->biClrUsed; n++) {
969 lppc->peNew[n].peRed = rgbNew[n].rgbRed;
970 lppc->peNew[n].peGreen = rgbNew[n].rgbGreen;
971 lppc->peNew[n].peBlue = rgbNew[n].rgbBlue;
972 lppc->peNew[n].peFlags = 0;
973 }
974
975 if (mmioSeek(This->paf->hmmio, This->paf->dwNextFramePos, SEEK_SET) == -1 ||
976 mmioCreateChunk(This->paf->hmmio, &ck, 0) != S_OK ||
977 mmioWrite(This->paf->hmmio, (HPSTR)lppc, ck.cksize) != ck.cksize ||
978 mmioAscend(This->paf->hmmio, &ck, 0) != S_OK)
979 {
980 HeapFree(GetProcessHeap(), 0, lppc);
981 return AVIERR_FILEWRITE;
982 }
983
984 This->paf->dwNextFramePos += ck.cksize + 2 * sizeof(DWORD);
985
986 HeapFree(GetProcessHeap(), 0, lppc);
987
989 }
990}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ULONG RGBQUAD
Definition: precomp.h:59
struct _WAVEFORMATEX * LPWAVEFORMATEX
PALETTEENTRY peNew[1]
Definition: vfw.h:996
BYTE bNumEntries
Definition: vfw.h:994
WORD wFlags
Definition: vfw.h:995
BYTE bFirstEntry
Definition: vfw.h:993
#define AVIERR_ERROR
Definition: vfw.h:1761

◆ IAVIStream_fnSetInfo()

static HRESULT WINAPI IAVIStream_fnSetInfo ( IAVIStream iface,
AVISTREAMINFOW info,
LONG  infolen 
)
static

Definition at line 1309 of file avifile.c.

1310{
1311 FIXME("(%p,%p,%d): stub\n", iface, info, infolen);
1312
1313 return E_FAIL;
1314}
#define E_FAIL
Definition: ddrawi.h:102

◆ IAVIStream_fnWrite()

static HRESULT WINAPI IAVIStream_fnWrite ( IAVIStream iface,
LONG  start,
LONG  samples,
void buffer,
LONG  buffersize,
DWORD  flags,
LONG sampwritten,
LONG byteswritten 
)
static

Definition at line 1111 of file avifile.c.

1113{
1115 FOURCC ckid;
1116 HRESULT hr;
1117
1118 TRACE("(%p,%d,%d,%p,%d,0x%08X,%p,%p)\n", iface, start, samples,
1119 buffer, buffersize, flags, sampwritten, byteswritten);
1120
1121 /* clear return parameters if given */
1122 if (sampwritten != NULL)
1123 *sampwritten = 0;
1124 if (byteswritten != NULL)
1125 *byteswritten = 0;
1126
1127 /* check parameters */
1128 if (buffer == NULL && (buffersize > 0 || samples > 0))
1129 return AVIERR_BADPARAM;
1130
1131 /* Have we write permission? */
1132 if ((This->paf->uMode & MMIO_RWMODE) == 0)
1133 return AVIERR_READONLY;
1134
1135 switch (This->sInfo.fccType) {
1136 case streamtypeAUDIO:
1137 ckid = MAKEAVICKID(cktypeWAVEbytes, This->nStream);
1138 break;
1139 default:
1140 if ((flags & AVIIF_KEYFRAME) && buffersize != 0)
1141 ckid = MAKEAVICKID(cktypeDIBbits, This->nStream);
1142 else
1143 ckid = MAKEAVICKID(cktypeDIBcompressed, This->nStream);
1144 break;
1145 };
1146
1147 /* append to end of stream? */
1148 if (start == -1) {
1149 if (This->lLastFrame == -1)
1150 start = This->sInfo.dwStart;
1151 else
1152 start = This->sInfo.dwLength;
1153 } else if (This->lLastFrame == -1)
1154 This->sInfo.dwStart = start;
1155
1156 if (This->sInfo.dwSampleSize != 0) {
1157 /* fixed sample size -- audio like */
1158 if (samples * This->sInfo.dwSampleSize != buffersize)
1159 return AVIERR_BADPARAM;
1160
1161 /* Couldn't skip audio-like data -- User must supply appropriate silence */
1162 if (This->sInfo.dwLength != start)
1163 return AVIERR_UNSUPPORTED;
1164
1165 /* Convert position to frame/block */
1166 start = This->lLastFrame + 1;
1167
1168 if ((This->paf->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) == 0) {
1169 FIXME(": not interleaved, could collect audio data!\n");
1170 }
1171 } else {
1172 /* variable sample size -- video like */
1173 if (samples > 1)
1174 return AVIERR_UNSUPPORTED;
1175
1176 /* must we fill up with empty frames? */
1177 if (This->lLastFrame != -1) {
1178 FOURCC ckid2 = MAKEAVICKID(cktypeDIBcompressed, This->nStream);
1179
1180 while (start > This->lLastFrame + 1) {
1181 hr = AVIFILE_WriteBlock(This, This->lLastFrame + 1, ckid2, 0, NULL, 0);
1182 if (FAILED(hr))
1183 return hr;
1184 }
1185 }
1186 }
1187
1188 /* write the block now */
1189 hr = AVIFILE_WriteBlock(This, start, ckid, flags, buffer, buffersize);
1190 if (SUCCEEDED(hr)) {
1191 /* fill out return parameters if given */
1192 if (sampwritten != NULL)
1193 *sampwritten = samples;
1194 if (byteswritten != NULL)
1195 *byteswritten = buffersize;
1196 }
1197
1198 return hr;
1199}
static HRESULT AVIFILE_WriteBlock(IAVIStreamImpl *This, DWORD block, FOURCC ckid, DWORD flags, LPCVOID buffer, LONG size)
Definition: avifile.c:2546
DWORD FOURCC
Definition: dmdls.h:25

◆ IAVIStream_fnWriteData()

static HRESULT WINAPI IAVIStream_fnWriteData ( IAVIStream iface,
DWORD  fcc,
void lp,
LONG  size 
)
static

Definition at line 1262 of file avifile.c.

1263{
1265
1266 TRACE("(%p,0x%08x,%p,%d)\n", iface, fcc, lp, size);
1267
1268 /* check parameters */
1269 if (lp == NULL)
1270 return AVIERR_BADPARAM;
1271 if (size <= 0)
1272 return AVIERR_BADSIZE;
1273
1274 /* need write permission */
1275 if ((This->paf->uMode & MMIO_RWMODE) == 0)
1276 return AVIERR_READONLY;
1277
1278 /* already written something to this file? */
1279 if (This->paf->dwMoviChunkPos != 0) {
1280 /* the data will be inserted before the 'movi' chunk, so check for
1281 * enough space */
1282 DWORD dwPos = AVIFILE_ComputeMoviStart(This->paf);
1283
1284 /* ckid,size => 2 * sizeof(DWORD) */
1285 dwPos += 2 * sizeof(DWORD) + size;
1286 if (dwPos >= This->paf->dwMoviChunkPos - 2 * sizeof(DWORD))
1287 return AVIERR_UNSUPPORTED; /* not enough space left */
1288 }
1289
1290 This->paf->fDirty = TRUE;
1291
1292 if (fcc == ckidSTREAMHANDLERDATA) {
1293 if (This->lpHandlerData != NULL) {
1294 FIXME(": handler data already set -- overwrite?\n");
1295 return AVIERR_UNSUPPORTED;
1296 }
1297
1298 This->lpHandlerData = HeapAlloc(GetProcessHeap(), 0, size);
1299 if (This->lpHandlerData == NULL)
1300 return AVIERR_MEMORY;
1301 This->cbHandlerData = size;
1302 memcpy(This->lpHandlerData, lp, size);
1303
1304 return AVIERR_OK;
1305 } else
1306 return WriteExtraChunk(&This->extra, fcc, lp, size);
1307}

◆ impl_from_IAVIFile()

static IAVIFileImpl * impl_from_IAVIFile ( IAVIFile iface)
inlinestatic

◆ impl_from_IAVIStream()

◆ impl_from_IPersistFile()

static IAVIFileImpl * impl_from_IPersistFile ( IPersistFile iface)
inlinestatic

◆ impl_from_IUnknown()

static IAVIFileImpl * impl_from_IUnknown ( IUnknown iface)
inlinestatic

Definition at line 120 of file avifile.c.

121{
122 return CONTAINING_RECORD(iface, IAVIFileImpl, IUnknown_inner);
123}

Referenced by IUnknown_fnAddRef(), IUnknown_fnQueryInterface(), and IUnknown_fnRelease().

◆ IPersistFile_fnAddRef()

static ULONG WINAPI IPersistFile_fnAddRef ( IPersistFile iface)
static

Definition at line 503 of file avifile.c.

504{
506
507 return IUnknown_AddRef(This->outer_unk);
508}
static IAVIFileImpl * impl_from_IPersistFile(IPersistFile *iface)
Definition: avifile.c:130

◆ IPersistFile_fnGetClassID()

static HRESULT WINAPI IPersistFile_fnGetClassID ( IPersistFile iface,
LPCLSID  pClassID 
)
static

Definition at line 517 of file avifile.c.

518{
519 TRACE("(%p,%p)\n", iface, pClassID);
520
521 if (pClassID == NULL)
522 return AVIERR_BADPARAM;
523
524 *pClassID = CLSID_AVIFile;
525
526 return AVIERR_OK;
527}

◆ IPersistFile_fnGetCurFile()

static HRESULT WINAPI IPersistFile_fnGetCurFile ( IPersistFile iface,
LPOLESTR ppszFileName 
)
static

Definition at line 609 of file avifile.c.

610{
612
613 TRACE("(%p,%p)\n", iface, ppszFileName);
614
615 if (ppszFileName == NULL)
616 return AVIERR_BADPARAM;
617
618 *ppszFileName = NULL;
619
620 if (This->szFileName != NULL) {
621 int len = lstrlenW(This->szFileName) + 1;
622
623 *ppszFileName = CoTaskMemAlloc(len * sizeof(WCHAR));
624 if (*ppszFileName == NULL)
625 return AVIERR_MEMORY;
626
627 lstrcpyW(*ppszFileName, This->szFileName);
628 }
629
630 return AVIERR_OK;
631}
#define lstrcpyW
Definition: compat.h:749
GLenum GLsizei len
Definition: glext.h:6722
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426

◆ IPersistFile_fnIsDirty()

static HRESULT WINAPI IPersistFile_fnIsDirty ( IPersistFile iface)
static

Definition at line 529 of file avifile.c.

530{
532
533 TRACE("(%p)\n", iface);
534
535 return (This->fDirty ? S_OK : S_FALSE);
536}
#define S_FALSE
Definition: winerror.h:2357

◆ IPersistFile_fnLoad()

static HRESULT WINAPI IPersistFile_fnLoad ( IPersistFile iface,
LPCOLESTR  pszFileName,
DWORD  dwMode 
)
static

Definition at line 538 of file avifile.c.

539{
541 int len;
542
543 TRACE("(%p,%s,0x%08X)\n", iface, debugstr_w(pszFileName), dwMode);
544
545 /* check parameter */
546 if (pszFileName == NULL)
547 return AVIERR_BADPARAM;
548
549 if (This->hmmio != NULL)
550 return AVIERR_ERROR; /* No reuse of this object for another file! */
551
552 /* remember mode and name */
553 This->uMode = dwMode;
554
555 len = lstrlenW(pszFileName) + 1;
556 This->szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
557 if (This->szFileName == NULL)
558 return AVIERR_MEMORY;
559 lstrcpyW(This->szFileName, pszFileName);
560
561 /* try to open the file */
562 This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
563 if (This->hmmio == NULL) {
564 /* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
565 LPSTR szFileName;
566
567 len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, NULL, 0, NULL, NULL);
568 szFileName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR));
569 if (szFileName == NULL)
570 return AVIERR_MEMORY;
571
572 WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName, len, NULL, NULL);
573
574 This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
575 HeapFree(GetProcessHeap(), 0, szFileName);
576 if (This->hmmio == NULL)
577 return AVIERR_FILEOPEN;
578 }
579
580 /* should we create a new file? */
581 if (dwMode & OF_CREATE) {
582 memset(& This->fInfo, 0, sizeof(This->fInfo));
584
585 return AVIERR_OK;
586 } else
587 return AVIFILE_LoadFile(This);
588}
static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
Definition: avifile.c:1575
HMMIO WINAPI mmioOpenA(LPSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:693
HMMIO WINAPI mmioOpenW(LPWSTR szFileName, MMIOINFO *lpmmioinfo, DWORD dwOpenFlags)
Definition: mmio.c:670
#define debugstr_w
Definition: kernel32.h:32
#define MMIO_ALLOCBUF
Definition: mmsystem.h:532
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
#define OF_CREATE
Definition: winbase.h:125
char CHAR
Definition: xmlstorage.h:175

◆ IPersistFile_fnQueryInterface()

static HRESULT WINAPI IPersistFile_fnQueryInterface ( IPersistFile iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 496 of file avifile.c.

497{
499
500 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
501}

◆ IPersistFile_fnRelease()

static ULONG WINAPI IPersistFile_fnRelease ( IPersistFile iface)
static

Definition at line 510 of file avifile.c.

511{
513
514 return IUnknown_Release(This->outer_unk);
515}

◆ IPersistFile_fnSave()

static HRESULT WINAPI IPersistFile_fnSave ( IPersistFile iface,
LPCOLESTR  pszFileName,
BOOL  fRemember 
)
static

Definition at line 590 of file avifile.c.

592{
593 TRACE("(%p,%s,%d)\n", iface, debugstr_w(pszFileName), fRemember);
594
595 /* We write directly to disk, so nothing to do. */
596
597 return AVIERR_OK;
598}

◆ IPersistFile_fnSaveCompleted()

static HRESULT WINAPI IPersistFile_fnSaveCompleted ( IPersistFile iface,
LPCOLESTR  pszFileName 
)
static

Definition at line 600 of file avifile.c.

601{
602 TRACE("(%p,%s)\n", iface, debugstr_w(pszFileName));
603
604 /* We write directly to disk, so nothing to do. */
605
606 return AVIERR_OK;
607}

◆ IUnknown_fnAddRef()

static ULONG WINAPI IUnknown_fnAddRef ( IUnknown iface)
static

Definition at line 189 of file avifile.c.

190{
193
194 TRACE("(%p) ref=%d\n", This, ref);
195
196 return ref;
197}
static IAVIFileImpl * impl_from_IUnknown(IUnknown *iface)
Definition: avifile.c:120

◆ IUnknown_fnQueryInterface()

static HRESULT WINAPI IUnknown_fnQueryInterface ( IUnknown iface,
REFIID  riid,
void **  ppv 
)
static

Definition at line 161 of file avifile.c.

162{
164
165 TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
166
167 if (!ppv) {
168 WARN("invalid parameter\n");
169 return E_INVALIDARG;
170 }
171 *ppv = NULL;
172
174 *ppv = &This->IUnknown_inner;
175 else if (IsEqualIID(riid, &IID_IAVIFile))
176 *ppv = &This->IAVIFile_iface;
178 *ppv = &This->IPersistFile_iface;
179 else {
180 WARN("unknown IID %s\n", debugstr_guid(riid));
181 return E_NOINTERFACE;
182 }
183
184 /* Violation of the COM aggregation ref counting rule */
185 IUnknown_AddRef(&This->IUnknown_inner);
186 return S_OK;
187}
const GUID IID_IPersistFile
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95

◆ IUnknown_fnRelease()

static ULONG WINAPI IUnknown_fnRelease ( IUnknown iface)
static

Definition at line 199 of file avifile.c.

200{
203 UINT i;
204
205 TRACE("(%p) ref=%d\n", This, ref);
206
207 if (!ref) {
208 if (This->fDirty)
210
211 for (i = 0; i < This->fInfo.dwStreams; i++) {
212 if (This->ppStreams[i] != NULL) {
213 if (This->ppStreams[i]->ref != 0)
214 ERR(": someone has still %u reference to stream %u (%p)!\n",
215 This->ppStreams[i]->ref, i, This->ppStreams[i]);
216 AVIFILE_DestructAVIStream(This->ppStreams[i]);
217 HeapFree(GetProcessHeap(), 0, This->ppStreams[i]);
218 This->ppStreams[i] = NULL;
219 }
220 }
221
222 if (This->idxRecords != NULL) {
223 HeapFree(GetProcessHeap(), 0, This->idxRecords);
224 This->idxRecords = NULL;
225 This->nIdxRecords = 0;
226 }
227
228 if (This->fileextra.lp != NULL) {
229 HeapFree(GetProcessHeap(), 0, This->fileextra.lp);
230 This->fileextra.lp = NULL;
231 This->fileextra.cb = 0;
232 }
233
234 HeapFree(GetProcessHeap(), 0, This->szFileName);
235 This->szFileName = NULL;
236
237 if (This->hmmio != NULL) {
238 mmioClose(This->hmmio, 0);
239 This->hmmio = NULL;
240 }
241
243 }
244 return ref;
245}
static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This)
Definition: avifile.c:2096
static void AVIFILE_DestructAVIStream(IAVIStreamImpl *This)
Definition: avifile.c:1538
MMRESULT WINAPI mmioClose(HMMIO hmmio, UINT uFlags)
Definition: mmio.c:702

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( avifile  )

Variable Documentation

◆ avif_vt

const struct IAVIFileVtbl avif_vt
static
Initial value:
= {
}
static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile *iface)
Definition: avifile.c:405
static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile *iface, AVIFILEINFOW *afi, LONG size)
Definition: avifile.c:275
static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile *iface, DWORD ckid, void *lpData, LONG *size)
Definition: avifile.c:396
static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile *iface, IAVIStream **avis, DWORD fccType, LONG lParam)
Definition: avifile.c:295
static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile *iface)
Definition: avifile.c:261
static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile *iface, DWORD ckid, void *lpData, LONG size)
Definition: avifile.c:375
static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile *iface, REFIID riid, void **ppv)
Definition: avifile.c:254
static ULONG WINAPI IAVIFile_fnRelease(IAVIFile *iface)
Definition: avifile.c:268
static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile *iface, IAVIStream **avis, AVISTREAMINFOW *asi)
Definition: avifile.c:322
static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile *iface, DWORD fccType, LONG lParam)
Definition: avifile.c:446

Definition at line 482 of file avifile.c.

Referenced by AVIFILE_CreateAVIFile().

◆ avist_vt

const struct IAVIStreamVtbl avist_vt
static
Initial value:
= {
}
static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
Definition: avifile.c:694
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, void *format, LONG formatsize)
Definition: avifile.c:884
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface, REFIID riid, void **ppv)
Definition: avifile.c:671
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1, LPARAM lParam2)
Definition: avifile.c:721
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start, LONG samples)
Definition: avifile.c:1201
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, LONG *bytesread, LONG *samplesread)
Definition: avifile.c:992
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream *iface)
Definition: avifile.c:708
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface, AVISTREAMINFOW *psi, LONG size)
Definition: avifile.c:729
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, void *lp, LONG size)
Definition: avifile.c:1262
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos, void *format, LONG *formatsize)
Definition: avifile.c:845
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten)
Definition: avifile.c:1111
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread)
Definition: avifile.c:1239
static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream *iface, AVISTREAMINFOW *info, LONG infolen)
Definition: avifile.c:1309

Definition at line 1316 of file avifile.c.

Referenced by AVIFILE_ConstructAVIStream().

◆ pf_vt

const struct IPersistFileVtbl pf_vt
static
Initial value:
= {
}
static HRESULT WINAPI IPersistFile_fnSave(IPersistFile *iface, LPCOLESTR pszFileName, BOOL fRemember)
Definition: avifile.c:590
static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
Definition: avifile.c:529
static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface, REFIID riid, void **ppv)
Definition: avifile.c:496
static ULONG WINAPI IPersistFile_fnRelease(IPersistFile *iface)
Definition: avifile.c:510
static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
Definition: avifile.c:503
static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
Definition: avifile.c:600
static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface, LPCLSID pClassID)
Definition: avifile.c:517
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, LPOLESTR *ppszFileName)
Definition: avifile.c:609
static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
Definition: avifile.c:538

Definition at line 633 of file avifile.c.

Referenced by AVIFILE_CreateAVIFile().

◆ unk_vtbl

const IUnknownVtbl unk_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI IUnknown_fnRelease(IUnknown *iface)
Definition: avifile.c:199
static ULONG WINAPI IUnknown_fnAddRef(IUnknown *iface)
Definition: avifile.c:189
static HRESULT WINAPI IUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, void **ppv)
Definition: avifile.c:161

Definition at line 247 of file avifile.c.

Referenced by AVIFILE_CreateAVIFile().