ReactOS 0.4.17-dev-804-g023d8af
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 1333 of file avifile.c.

1334{
1335 UINT n;
1336
1337 /* pre-conditions */
1338 assert(This != NULL);
1339
1340 switch (TWOCCFromFOURCC(ckid)) {
1341 case cktypeDIBbits:
1342 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1344 break;
1346 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1347 flags &= ~AVIIF_KEYFRAME;
1348 break;
1349 case cktypePALchange:
1350 if (This->sInfo.fccType != streamtypeVIDEO) {
1351 ERR(": found palette change in non-video stream!\n");
1352 return AVIERR_BADFORMAT;
1353 }
1354
1355 if (This->idxFmtChanges == NULL || This->nIdxFmtChanges <= This->sInfo.dwFormatChangeCount) {
1356 DWORD new_count = This->nIdxFmtChanges + 16;
1357 void *new_buffer = _recalloc(This->idxFmtChanges, new_count, sizeof(AVIINDEXENTRY));
1358 if (!new_buffer) return AVIERR_MEMORY;
1359 This->idxFmtChanges = new_buffer;
1360 This->nIdxFmtChanges = new_count;
1361 }
1362
1363 This->sInfo.dwFlags |= AVISTREAMINFO_FORMATCHANGES;
1364 n = ++This->sInfo.dwFormatChangeCount;
1365 This->idxFmtChanges[n].ckid = This->lLastFrame;
1366 This->idxFmtChanges[n].dwFlags = 0;
1367 This->idxFmtChanges[n].dwChunkOffset = offset;
1368 This->idxFmtChanges[n].dwChunkLength = size;
1369
1370 return AVIERR_OK;
1371 case cktypeWAVEbytes:
1372 if (This->paf->fInfo.dwFlags & AVIFILEINFO_TRUSTCKTYPE)
1374 break;
1375 default:
1376 WARN(": unknown TWOCC 0x%04X found\n", TWOCCFromFOURCC(ckid));
1377 break;
1378 };
1379
1380 /* first frame is always a keyframe */
1381 if (This->lLastFrame == -1)
1383
1384 if (This->sInfo.dwSuggestedBufferSize < size)
1385 This->sInfo.dwSuggestedBufferSize = size;
1386
1387 /* get memory for index */
1388 if (This->idxFrames == NULL || This->lLastFrame + 1 >= This->nIdxFrames) {
1389 This->nIdxFrames += 512;
1390 This->idxFrames = _recalloc(This->idxFrames, This->nIdxFrames, sizeof(AVIINDEXENTRY));
1391 if (This->idxFrames == NULL)
1392 return AVIERR_MEMORY;
1393 }
1394
1395 This->lLastFrame++;
1396 This->idxFrames[This->lLastFrame].ckid = ckid;
1397 This->idxFrames[This->lLastFrame].dwFlags = flags;
1398 This->idxFrames[This->lLastFrame].dwChunkOffset = offset;
1399 This->idxFrames[This->lLastFrame].dwChunkLength = size;
1400
1401 /* update AVISTREAMINFO structure if necessary */
1402 if (This->sInfo.dwLength <= This->lLastFrame)
1403 This->sInfo.dwLength = This->lLastFrame + 1;
1404
1405 return AVIERR_OK;
1406}
#define AVIIF_KEYFRAME
Definition: aviriff.h:131
#define streamtypeVIDEO
Definition: aviriff.h:92
#define TWOCCFromFOURCC(fcc)
Definition: avisplit.c:49
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define NULL
Definition: types.h:112
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP void *__cdecl _recalloc(void *, size_t, size_t) __WINE_ALLOC_SIZE(2
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble n
Definition: glext.h:7729
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLbitfield flags
Definition: glext.h:7161
unsigned int UINT
Definition: sysinfo.c:13
#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 1408 of file avifile.c.

1409{
1410 /* pre-conditions */
1411 assert(This != NULL && This->ppStreams[0] != NULL);
1412
1413 if (This->idxRecords == NULL || This->cbIdxRecords / sizeof(AVIINDEXENTRY) <= This->nIdxRecords) {
1414 DWORD new_count = This->cbIdxRecords + 1024 * sizeof(AVIINDEXENTRY);
1415 void *mem;
1416 mem = _recalloc(This->idxRecords, 1, new_count);
1417 if (mem) {
1418 This->cbIdxRecords = new_count;
1419 This->idxRecords = mem;
1420 } else {
1421 free(This->idxRecords);
1422 This->idxRecords = NULL;
1423 return AVIERR_MEMORY;
1424 }
1425 }
1426
1427 assert(This->nIdxRecords < This->cbIdxRecords/sizeof(AVIINDEXENTRY));
1428
1429 This->idxRecords[This->nIdxRecords].ckid = listtypeAVIRECORD;
1430 This->idxRecords[This->nIdxRecords].dwFlags = AVIIF_LIST;
1431 This->idxRecords[This->nIdxRecords].dwChunkOffset =
1432 This->ckLastRecord.dwDataOffset - 2 * sizeof(DWORD);
1433 This->idxRecords[This->nIdxRecords].dwChunkLength =
1434 This->ckLastRecord.cksize;
1435 This->nIdxRecords++;
1436
1437 return AVIERR_OK;
1438}
#define AVIIF_LIST
Definition: aviriff.h:130
#define free
Definition: debug_ros.c:5
#define DWORD
Definition: nt_native.h:44
Definition: mem.c:349
#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 1440 of file avifile.c.

1441{
1442 DWORD dwPos;
1443 DWORD nStream;
1444
1445 /* RIFF,hdrl,movi,avih => (3 * 3 + 2) * sizeof(DWORD) = 11 * sizeof(DWORD) */
1446 dwPos = 11 * sizeof(DWORD) + sizeof(MainAVIHeader);
1447
1448 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
1449 IAVIStreamImpl *pStream = This->ppStreams[nStream];
1450
1451 /* strl,strh,strf => (3 + 2 * 2) * sizeof(DWORD) = 7 * sizeof(DWORD) */
1452 dwPos += 7 * sizeof(DWORD) + sizeof(AVIStreamHeader);
1453 dwPos += ((pStream->cbFormat + 1) & ~1U);
1454 if (pStream->lpHandlerData != NULL && pStream->cbHandlerData > 0)
1455 dwPos += 2 * sizeof(DWORD) + ((pStream->cbHandlerData + 1) & ~1U);
1456 if (pStream->sInfo.szName[0])
1457 dwPos += 2 * sizeof(DWORD) + ((lstrlenW(pStream->sInfo.szName) + 1) & ~1U);
1458 }
1459
1460 if (This->dwMoviChunkPos == 0) {
1461 This->dwNextFramePos = dwPos;
1462
1463 /* pad to multiple of AVI_HEADERSIZE only if we are more than 8 bytes away from it */
1464 if (((dwPos + AVI_HEADERSIZE) & ~(AVI_HEADERSIZE - 1)) - dwPos > 2 * sizeof(DWORD))
1465 This->dwNextFramePos = (dwPos + AVI_HEADERSIZE) & ~(AVI_HEADERSIZE - 1);
1466
1467 This->dwMoviChunkPos = This->dwNextFramePos - sizeof(DWORD);
1468 }
1469
1470 return dwPos;
1471}
#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 1473 of file avifile.c.

1474{
1475 IAVIStreamImpl *pstream;
1476
1477 /* pre-conditions */
1478 assert(paf != NULL);
1480 assert(paf->ppStreams[nr] != NULL);
1481
1482 pstream = paf->ppStreams[nr];
1483
1484 pstream->IAVIStream_iface.lpVtbl = &avist_vt;
1485 pstream->ref = 0;
1486 pstream->paf = paf;
1487 pstream->nStream = nr;
1488 pstream->dwCurrentFrame = (DWORD)-1;
1489 pstream->lLastFrame = -1;
1490
1491 if (asi != NULL) {
1492 memcpy(&pstream->sInfo, asi, sizeof(pstream->sInfo));
1493
1494 if (asi->dwLength > 0) {
1495 /* pre-allocate mem for frame-index structure */
1496 pstream->idxFrames = calloc(asi->dwLength, sizeof(AVIINDEXENTRY));
1497 if (pstream->idxFrames != NULL)
1498 pstream->nIdxFrames = asi->dwLength;
1499 }
1500 if (asi->dwFormatChangeCount > 0) {
1501 /* pre-allocate mem for formatchange-index structure */
1502 pstream->idxFmtChanges = calloc(asi->dwFormatChangeCount, sizeof(AVIINDEXENTRY));
1503 if (pstream->idxFmtChanges != NULL)
1504 pstream->nIdxFmtChanges = asi->dwFormatChangeCount;
1505 }
1506
1507 /* These values will be computed */
1508 pstream->sInfo.dwLength = 0;
1509 pstream->sInfo.dwSuggestedBufferSize = 0;
1510 pstream->sInfo.dwFormatChangeCount = 0;
1511 pstream->sInfo.dwEditCount = 1;
1512 if (pstream->sInfo.dwSampleSize > 0)
1513 SetRectEmpty(&pstream->sInfo.rcFrame);
1514 }
1515
1517}
static const struct IAVIStreamVtbl avist_vt
Definition: avifile.c:1315
#define MAX_AVISTREAMS
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG nr
Definition: thread.c:7
#define calloc
Definition: rosglue.h:14
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 644 of file avifile.c.

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

Referenced by IClassFactory_fnCreateInstance().

◆ AVIFILE_DestructAVIStream()

static void AVIFILE_DestructAVIStream ( IAVIStreamImpl This)
static

Definition at line 1519 of file avifile.c.

1520{
1521 /* pre-conditions */
1522 assert(This != NULL);
1523
1524 This->dwCurrentFrame = (DWORD)-1;
1525 This->lLastFrame = -1;
1526 This->paf = NULL;
1527 if (This->idxFrames != NULL) {
1528 free(This->idxFrames);
1529 This->idxFrames = NULL;
1530 This->nIdxFrames = 0;
1531 }
1532 free(This->idxFmtChanges);
1533 This->idxFmtChanges = NULL;
1534 if (This->lpBuffer != NULL) {
1535 free(This->lpBuffer);
1536 This->lpBuffer = NULL;
1537 This->cbBuffer = 0;
1538 }
1539 if (This->lpHandlerData != NULL) {
1540 free(This->lpHandlerData);
1541 This->lpHandlerData = NULL;
1542 This->cbHandlerData = 0;
1543 }
1544 if (This->extra.lp != NULL) {
1545 free(This->extra.lp);
1546 This->extra.lp = NULL;
1547 This->extra.cb = 0;
1548 }
1549 if (This->lpFormat != NULL) {
1550 free(This->lpFormat);
1551 This->lpFormat = NULL;
1552 This->cbFormat = 0;
1553 }
1554}

Referenced by IUnknown_fnRelease().

◆ AVIFILE_LoadFile()

static HRESULT AVIFILE_LoadFile ( IAVIFileImpl This)
static

Definition at line 1556 of file avifile.c.

1557{
1558 MainAVIHeader MainAVIHdr;
1559 MMCKINFO ckRIFF;
1560 MMCKINFO ckLIST1;
1561 MMCKINFO ckLIST2;
1562 MMCKINFO ck;
1563 IAVIStreamImpl *pStream;
1564 DWORD nStream;
1565 HRESULT hr;
1566
1567 if (This->hmmio == NULL)
1568 return AVIERR_FILEOPEN;
1569
1570 /* initialize stream ptr's */
1571 memset(This->ppStreams, 0, sizeof(This->ppStreams));
1572
1573 /* try to get "RIFF" chunk -- must not be at beginning of file! */
1574 ckRIFF.fccType = formtypeAVI;
1575 if (mmioDescend(This->hmmio, &ckRIFF, NULL, MMIO_FINDRIFF) != S_OK) {
1576 ERR(": not an AVI!\n");
1577 return AVIERR_FILEREAD;
1578 }
1579
1580 /* get "LIST" "hdrl" */
1581 ckLIST1.fccType = listtypeAVIHEADER;
1582 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF, MMIO_FINDLIST);
1583 if (FAILED(hr))
1584 return hr;
1585
1586 /* get "avih" chunk */
1587 ck.ckid = ckidAVIMAINHDR;
1588 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, MMIO_FINDCHUNK);
1589 if (FAILED(hr))
1590 return hr;
1591
1592 if (ck.cksize != sizeof(MainAVIHdr)) {
1593 ERR(": invalid size of %ld for MainAVIHeader!\n", ck.cksize);
1594 return AVIERR_BADFORMAT;
1595 }
1596 if (mmioRead(This->hmmio, (HPSTR)&MainAVIHdr, ck.cksize) != ck.cksize)
1597 return AVIERR_FILEREAD;
1598
1599 /* check for MAX_AVISTREAMS limit */
1600 if (MainAVIHdr.dwStreams > MAX_AVISTREAMS) {
1601 WARN("file contains %lu streams, but only supports %d -- change MAX_AVISTREAMS!\n", MainAVIHdr.dwStreams, MAX_AVISTREAMS);
1602 return AVIERR_UNSUPPORTED;
1603 }
1604
1605 /* adjust permissions if copyrighted material in file */
1606 if (MainAVIHdr.dwFlags & AVIFILEINFO_COPYRIGHTED) {
1607 This->uMode &= ~MMIO_RWMODE;
1608 This->uMode |= MMIO_READ;
1609 }
1610
1611 /* convert MainAVIHeader into AVIFILINFOW */
1612 memset(&This->fInfo, 0, sizeof(This->fInfo));
1613 This->fInfo.dwRate = MainAVIHdr.dwMicroSecPerFrame;
1614 This->fInfo.dwScale = 1000000;
1615 This->fInfo.dwMaxBytesPerSec = MainAVIHdr.dwMaxBytesPerSec;
1616 This->fInfo.dwFlags = MainAVIHdr.dwFlags;
1618 This->fInfo.dwLength = MainAVIHdr.dwTotalFrames;
1619 This->fInfo.dwStreams = MainAVIHdr.dwStreams;
1620 This->fInfo.dwSuggestedBufferSize = 0;
1621 This->fInfo.dwWidth = MainAVIHdr.dwWidth;
1622 This->fInfo.dwHeight = MainAVIHdr.dwHeight;
1623 LoadStringW(AVIFILE_hModule, IDS_AVIFILETYPE, This->fInfo.szFileType,
1624 ARRAY_SIZE(This->fInfo.szFileType));
1625
1626 /* go back to into header list */
1627 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
1628 return AVIERR_FILEREAD;
1629
1630 /* foreach stream exists a "LIST","strl" chunk */
1631 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
1632 /* get next nested chunk in this "LIST","strl" */
1633 if (mmioDescend(This->hmmio, &ckLIST2, &ckLIST1, 0) != S_OK)
1634 return AVIERR_FILEREAD;
1635
1636 /* nested chunk must be of type "LIST","strl" -- when not normally JUNK */
1637 if (ckLIST2.ckid == FOURCC_LIST &&
1638 ckLIST2.fccType == listtypeSTREAMHEADER) {
1639 pStream = This->ppStreams[nStream] = calloc(1, sizeof(IAVIStreamImpl));
1640 if (pStream == NULL)
1641 return AVIERR_MEMORY;
1643
1644 ck.ckid = 0;
1645 while (mmioDescend(This->hmmio, &ck, &ckLIST2, 0) == S_OK) {
1646 switch (ck.ckid) {
1648 if (pStream->lpHandlerData != NULL)
1649 return AVIERR_BADFORMAT;
1650 pStream->lpHandlerData = malloc(ck.cksize);
1651 if (pStream->lpHandlerData == NULL)
1652 return AVIERR_MEMORY;
1653 pStream->cbHandlerData = ck.cksize;
1654
1655 if (mmioRead(This->hmmio, pStream->lpHandlerData, ck.cksize) != ck.cksize)
1656 return AVIERR_FILEREAD;
1657 break;
1658 case ckidSTREAMFORMAT:
1659 if (pStream->lpFormat != NULL)
1660 return AVIERR_BADFORMAT;
1661 if (ck.cksize == 0)
1662 break;
1663
1664 pStream->lpFormat = malloc(ck.cksize);
1665 if (pStream->lpFormat == NULL)
1666 return AVIERR_MEMORY;
1667 pStream->cbFormat = ck.cksize;
1668
1669 if (mmioRead(This->hmmio, pStream->lpFormat, ck.cksize) != ck.cksize)
1670 return AVIERR_FILEREAD;
1671
1672 if (pStream->sInfo.fccType == streamtypeVIDEO) {
1673 LPBITMAPINFOHEADER lpbi = pStream->lpFormat;
1674
1675 /* some corrections to the video format */
1676 if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8)
1677 lpbi->biClrUsed = 1u << lpbi->biBitCount;
1678 if (lpbi->biCompression == BI_RGB && lpbi->biSizeImage == 0)
1679 lpbi->biSizeImage = DIBWIDTHBYTES(*lpbi) * lpbi->biHeight;
1680 if (lpbi->biCompression != BI_RGB && lpbi->biBitCount == 8) {
1681 if (pStream->sInfo.fccHandler == mmioFOURCC('R','L','E','0') ||
1682 pStream->sInfo.fccHandler == mmioFOURCC('R','L','E',' '))
1683 lpbi->biCompression = BI_RLE8;
1684 }
1685 if (lpbi->biCompression == BI_RGB &&
1686 (pStream->sInfo.fccHandler == 0 ||
1687 pStream->sInfo.fccHandler == mmioFOURCC('N','O','N','E')))
1688 pStream->sInfo.fccHandler = comptypeDIB;
1689
1690 /* init rcFrame if it's empty */
1691 if (IsRectEmpty(&pStream->sInfo.rcFrame))
1692 SetRect(&pStream->sInfo.rcFrame, 0, 0, lpbi->biWidth, lpbi->biHeight);
1693 }
1694 break;
1695 case ckidSTREAMHEADER:
1696 {
1697 AVIStreamHeader streamHdr;
1698 WCHAR szType[25];
1699 UINT count;
1700 LONG n = ck.cksize;
1701
1702 if (ck.cksize > sizeof(streamHdr))
1703 n = sizeof(streamHdr);
1704
1705 if (mmioRead(This->hmmio, (HPSTR)&streamHdr, n) != n)
1706 return AVIERR_FILEREAD;
1707
1708 pStream->sInfo.fccType = streamHdr.fccType;
1709 pStream->sInfo.fccHandler = streamHdr.fccHandler;
1710 pStream->sInfo.dwFlags = streamHdr.dwFlags;
1711 pStream->sInfo.wPriority = streamHdr.wPriority;
1712 pStream->sInfo.wLanguage = streamHdr.wLanguage;
1713 pStream->sInfo.dwInitialFrames = streamHdr.dwInitialFrames;
1714 pStream->sInfo.dwScale = streamHdr.dwScale;
1715 pStream->sInfo.dwRate = streamHdr.dwRate;
1716 pStream->sInfo.dwStart = streamHdr.dwStart;
1717 pStream->sInfo.dwLength = streamHdr.dwLength;
1718 pStream->sInfo.dwSuggestedBufferSize = 0;
1719 pStream->sInfo.dwQuality = streamHdr.dwQuality;
1720 pStream->sInfo.dwSampleSize = streamHdr.dwSampleSize;
1721 pStream->sInfo.rcFrame.left = streamHdr.rcFrame.left;
1722 pStream->sInfo.rcFrame.top = streamHdr.rcFrame.top;
1723 pStream->sInfo.rcFrame.right = streamHdr.rcFrame.right;
1724 pStream->sInfo.rcFrame.bottom = streamHdr.rcFrame.bottom;
1725 pStream->sInfo.dwEditCount = 0;
1726 pStream->sInfo.dwFormatChangeCount = 0;
1727
1728 /* generate description for stream like "filename.avi Type #n" */
1729 if (streamHdr.fccType == streamtypeVIDEO)
1731 else if (streamHdr.fccType == streamtypeAUDIO)
1733 else
1734 wsprintfW(szType, L"%4.4hs", (char*)&streamHdr.fccType);
1735
1736 /* get count of this streamtype up to this stream */
1737 count = 0;
1738 for (n = nStream; 0 <= n; n--) {
1739 if (This->ppStreams[n]->sInfo.fccHandler == streamHdr.fccType)
1740 count++;
1741 }
1742
1743 memset(pStream->sInfo.szName, 0, sizeof(pStream->sInfo.szName));
1744
1745 /* FIXME: avoid overflow -- better use wsnprintfW, which doesn't exists ! */
1746 wsprintfW(pStream->sInfo.szName, L"%s %s #%d",
1747 AVIFILE_BasenameW(This->szFileName), szType, count);
1748 }
1749 break;
1750 case ckidSTREAMNAME:
1751 { /* streamname will be saved as ASCII string */
1752 char *str = malloc(ck.cksize);
1753 if (str == NULL)
1754 return AVIERR_MEMORY;
1755
1756 if (mmioRead(This->hmmio, str, ck.cksize) != ck.cksize)
1757 {
1758 free(str);
1759 return AVIERR_FILEREAD;
1760 }
1761
1762 MultiByteToWideChar(CP_ACP, 0, str, -1, pStream->sInfo.szName,
1763 ARRAY_SIZE(pStream->sInfo.szName));
1764
1765 free(str);
1766 }
1767 break;
1768 case ckidAVIPADDING:
1769 case mmioFOURCC('p','a','d','d'):
1770 break;
1771 default:
1772 WARN(": found extra chunk 0x%08lX\n", ck.ckid);
1773 hr = ReadChunkIntoExtra(&pStream->extra, This->hmmio, &ck);
1774 if (FAILED(hr))
1775 return hr;
1776 };
1777 if (pStream->lpFormat != NULL && pStream->sInfo.fccType == streamtypeAUDIO)
1778 {
1779 WAVEFORMATEX *wfx = pStream->lpFormat; /* wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample / 8; could be added */
1780 pStream->sInfo.dwSampleSize = wfx->nBlockAlign; /* to deal with corrupt wfx->nBlockAlign but Windows doesn't do this */
1781 TRACE("Block size reset to %u, chan=%u bpp=%u\n", wfx->nBlockAlign, wfx->nChannels, wfx->wBitsPerSample);
1782 pStream->sInfo.dwScale = 1;
1783 pStream->sInfo.dwRate = wfx->nSamplesPerSec;
1784 }
1785 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
1786 return AVIERR_FILEREAD;
1787 }
1788 } else {
1789 /* nested chunks in "LIST","hdrl" which are not of type "LIST","strl" */
1790 hr = ReadChunkIntoExtra(&This->fileextra, This->hmmio, &ckLIST2);
1791 if (FAILED(hr))
1792 return hr;
1793 }
1794 if (mmioAscend(This->hmmio, &ckLIST2, 0) != S_OK)
1795 return AVIERR_FILEREAD;
1796 }
1797
1798 /* read any extra headers in "LIST","hdrl" */
1799 FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckLIST1, 0);
1800 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
1801 return AVIERR_FILEREAD;
1802
1803 /* search "LIST","movi" chunk in "RIFF","AVI " */
1804 ckLIST1.fccType = listtypeAVIMOVIE;
1805 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ckLIST1, &ckRIFF,
1807 if (FAILED(hr))
1808 return hr;
1809
1810 This->dwMoviChunkPos = ckLIST1.dwDataOffset;
1811 This->dwIdxChunkPos = ckLIST1.cksize + ckLIST1.dwDataOffset;
1812 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
1813 return AVIERR_FILEREAD;
1814
1815 /* try to find an index */
1816 ck.ckid = ckidAVINEWINDEX;
1817 hr = FindChunkAndKeepExtras(&This->fileextra, This->hmmio,
1818 &ck, &ckRIFF, MMIO_FINDCHUNK);
1819 if (SUCCEEDED(hr) && ck.cksize > 0) {
1820 if (FAILED(AVIFILE_LoadIndex(This, ck.cksize, ckLIST1.dwDataOffset)))
1821 This->fInfo.dwFlags &= ~AVIFILEINFO_HASINDEX;
1822 }
1823
1824 /* when we haven't found an index or it's bad, then build one
1825 * by parsing 'movi' chunk */
1826 if ((This->fInfo.dwFlags & AVIFILEINFO_HASINDEX) == 0) {
1827 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
1828 This->ppStreams[nStream]->lLastFrame = -1;
1829
1830 if (mmioSeek(This->hmmio, ckLIST1.dwDataOffset + sizeof(DWORD), SEEK_SET) == -1) {
1831 ERR(": Oops, can't seek back to 'movi' chunk!\n");
1832 return AVIERR_FILEREAD;
1833 }
1834
1835 /* seek through the 'movi' list until end */
1836 while (mmioDescend(This->hmmio, &ck, &ckLIST1, 0) == S_OK) {
1837 if (ck.ckid != FOURCC_LIST) {
1838 if (mmioAscend(This->hmmio, &ck, 0) == S_OK) {
1839 nStream = StreamFromFOURCC(ck.ckid);
1840
1841 if (nStream > This->fInfo.dwStreams)
1842 return AVIERR_BADFORMAT;
1843
1844 AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
1845 ck.dwDataOffset - 2 * sizeof(DWORD), 0);
1846 } else {
1847 nStream = StreamFromFOURCC(ck.ckid);
1848 WARN(": file seems to be truncated!\n");
1849 if (nStream <= This->fInfo.dwStreams &&
1850 This->ppStreams[nStream]->sInfo.dwSampleSize > 0) {
1851 ck.cksize = mmioSeek(This->hmmio, 0, SEEK_END);
1852 if (ck.cksize != -1) {
1853 ck.cksize -= ck.dwDataOffset;
1854 ck.cksize &= ~(This->ppStreams[nStream]->sInfo.dwSampleSize - 1);
1855
1856 AVIFILE_AddFrame(This->ppStreams[nStream], ck.ckid, ck.cksize,
1857 ck.dwDataOffset - 2 * sizeof(DWORD), 0);
1858 }
1859 }
1860 }
1861 }
1862 }
1863 }
1864
1865 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++)
1866 {
1867 DWORD sugbuf = This->ppStreams[nStream]->sInfo.dwSuggestedBufferSize;
1868 if (This->fInfo.dwSuggestedBufferSize < sugbuf)
1869 This->fInfo.dwSuggestedBufferSize = sugbuf;
1870 }
1871
1872 /* find other chunks */
1873 FindChunkAndKeepExtras(&This->fileextra, This->hmmio, &ck, &ckRIFF, 0);
1874
1875 return AVIERR_OK;
1876}
static void AVIFILE_ConstructAVIStream(IAVIFileImpl *paf, DWORD nr, const AVISTREAMINFOW *asi)
Definition: avifile.c:1473
static HRESULT AVIFILE_LoadIndex(const IAVIFileImpl *This, DWORD size, DWORD offset)
Definition: avifile.c:1878
static HRESULT AVIFILE_AddFrame(IAVIStreamImpl *This, DWORD ckid, DWORD size, DWORD offset, DWORD flags)
Definition: avifile.c:1333
LPCWSTR AVIFILE_BasenameW(LPCWSTR szFileName)
Definition: factory.c:157
#define IDS_VIDEO
#define DIBWIDTHBYTES(bi)
#define IDS_AVIFILETYPE
HMODULE AVIFILE_hModule
Definition: factory.c:39
#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:20
#define SEEK_END
Definition: cabinet.c:29
#define malloc
Definition: debug_ros.c:4
#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 L(x)
Definition: resources.c:13
HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra, HMMIO hmmio, MMCKINFO *lpck, MMCKINFO *lpckParent, UINT flags)
Definition: extrachunk.c:135
HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra, HMMIO hmmio, const MMCKINFO *lpck)
Definition: extrachunk.c:98
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:1479
#define MMIO_FINDLIST
Definition: mmsystem.h:553
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
const WCHAR * str
#define LoadStringW
Definition: utils.h:64
#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:1509
DWORD cksize
Definition: mmsystem.h:1510
DWORD dwDataOffset
Definition: mmsystem.h:1512
FOURCC fccType
Definition: mmsystem.h:1511
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
#define BI_RGB
Definition: uefivid.c:46
#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 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)

Referenced by IPersistFile_fnLoad().

◆ AVIFILE_LoadIndex()

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

Definition at line 1878 of file avifile.c.

1879{
1880 AVIINDEXENTRY *lp;
1881 DWORD pos, n;
1883 BOOL bAbsolute = TRUE;
1884
1885 lp = malloc(IDX_PER_BLOCK * sizeof(AVIINDEXENTRY));
1886 if (lp == NULL)
1887 return AVIERR_MEMORY;
1888
1889 /* adjust limits for index tables, so that inserting will be faster */
1890 for (n = 0; n < This->fInfo.dwStreams; n++) {
1891 IAVIStreamImpl *pStream = This->ppStreams[n];
1892
1893 pStream->lLastFrame = -1;
1894
1895 if (pStream->idxFrames != NULL) {
1896 free(pStream->idxFrames);
1897 pStream->idxFrames = NULL;
1898 pStream->nIdxFrames = 0;
1899 }
1900
1901 if (pStream->sInfo.dwSampleSize != 0) {
1902 if (n > 0 && This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) {
1903 pStream->nIdxFrames = This->ppStreams[0]->nIdxFrames;
1904 } else if (pStream->sInfo.dwSuggestedBufferSize) {
1905 pStream->nIdxFrames =
1906 pStream->sInfo.dwLength / pStream->sInfo.dwSuggestedBufferSize;
1907 }
1908 } else
1909 pStream->nIdxFrames = pStream->sInfo.dwLength;
1910
1911 pStream->idxFrames = calloc(pStream->nIdxFrames, sizeof(AVIINDEXENTRY));
1912 if (pStream->idxFrames == NULL && pStream->nIdxFrames > 0) {
1913 pStream->nIdxFrames = 0;
1914 free(lp);
1915 return AVIERR_MEMORY;
1916 }
1917 }
1918
1919 pos = (DWORD)-1;
1920 while (size != 0) {
1922
1923 if (mmioRead(This->hmmio, (HPSTR)lp, read) != read) {
1925 break;
1926 }
1927 size -= read;
1928
1929 if (pos == (DWORD)-1)
1930 pos = offset - lp->dwChunkOffset + sizeof(DWORD);
1931
1933 pos, &bAbsolute);
1934 }
1935
1936 free(lp);
1937
1938 /* checking ... */
1939 for (n = 0; n < This->fInfo.dwStreams; n++) {
1940 IAVIStreamImpl *pStream = This->ppStreams[n];
1941
1942 if (pStream->sInfo.dwSampleSize == 0 &&
1943 pStream->sInfo.dwLength != pStream->lLastFrame+1)
1944 ERR("stream %lu length mismatch: dwLength=%lu found=%ld\n",
1945 n, pStream->sInfo.dwLength, pStream->lLastFrame);
1946 }
1947
1948 return hr;
1949}
#define read
Definition: acwin.h:97
#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:1951
#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 1951 of file avifile.c.

1953{
1954 if (lp == NULL)
1955 return AVIERR_BADPARAM;
1956
1957 for (; count > 0; count--, lp++) {
1958 WORD nStream = StreamFromFOURCC(lp->ckid);
1959
1960 if (lp->ckid == listtypeAVIRECORD || nStream == 0x7F)
1961 continue; /* skip these */
1962
1963 if (nStream > This->fInfo.dwStreams)
1964 return AVIERR_BADFORMAT;
1965
1966 /* Video frames can be either indexed in a relative position to the
1967 * "movi" chunk or in a absolute position in the file. If the index
1968 * is relative the frame offset will always be so small that it will
1969 * virtually never reach the "movi" offset so we can detect if the
1970 * video is relative very fast.
1971 */
1972 if (*bAbsolute && lp->dwChunkOffset < This->dwMoviChunkPos)
1973 *bAbsolute = FALSE;
1974
1975 if (!*bAbsolute)
1976 lp->dwChunkOffset += pos; /* make the offset absolute */
1977
1978 if (FAILED(AVIFILE_AddFrame(This->ppStreams[nStream], lp->ckid, lp->dwChunkLength, lp->dwChunkOffset, lp->dwFlags)))
1979 return AVIERR_MEMORY;
1980 }
1981
1982 return AVIERR_OK;
1983}
#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 1985 of file avifile.c.

1987{
1988 /* pre-conditions */
1989 assert(This != NULL);
1990 assert(This->paf != NULL);
1991 assert(This->paf->hmmio != NULL);
1992 assert(This->sInfo.dwStart <= pos && pos < This->sInfo.dwLength);
1993 assert(pos <= This->lLastFrame);
1994
1995 /* should we read as much as block gives us? */
1996 if (size == 0 || size > This->idxFrames[pos].dwChunkLength)
1997 size = This->idxFrames[pos].dwChunkLength;
1998
1999 /* read into out own buffer or given one? */
2000 if (buffer == NULL) {
2001 /* we also read the chunk */
2002 size += 2 * sizeof(DWORD);
2003
2004 /* check that buffer is big enough -- don't trust dwSuggestedBufferSize */
2005 if (This->lpBuffer == NULL || This->cbBuffer < size) {
2006 DWORD maxSize = max(size, This->sInfo.dwSuggestedBufferSize);
2007 void *new_buffer = realloc(This->lpBuffer, maxSize);
2008 if (!new_buffer) return AVIERR_MEMORY;
2009 This->lpBuffer = new_buffer;
2010 This->cbBuffer = maxSize;
2011 }
2012
2013 /* now read the complete chunk into our buffer */
2014 if (mmioSeek(This->paf->hmmio, This->idxFrames[pos].dwChunkOffset, SEEK_SET) == -1)
2015 return AVIERR_FILEREAD;
2016 if (mmioRead(This->paf->hmmio, (HPSTR)This->lpBuffer, size) != size)
2017 return AVIERR_FILEREAD;
2018
2019 /* check if it was the correct block which we have read */
2020 if (This->lpBuffer[0] != This->idxFrames[pos].ckid ||
2021 This->lpBuffer[1] != This->idxFrames[pos].dwChunkLength) {
2022 ERR(": block %ld not found at 0x%08lX\n", pos, This->idxFrames[pos].dwChunkOffset);
2023 ERR(": Index says: '%4.4s'(0x%08lX) size 0x%08lX\n",
2024 (char*)&This->idxFrames[pos].ckid, This->idxFrames[pos].ckid,
2025 This->idxFrames[pos].dwChunkLength);
2026 ERR(": Data says: '%4.4s'(0x%08lX) size 0x%08lX\n",
2027 (char*)&This->lpBuffer[0], This->lpBuffer[0], This->lpBuffer[1]);
2028 return AVIERR_FILEREAD;
2029 }
2030 } else {
2031 if (mmioSeek(This->paf->hmmio, This->idxFrames[pos].dwChunkOffset + 2 * sizeof(DWORD), SEEK_SET) == -1)
2032 return AVIERR_FILEREAD;
2033 if (mmioRead(This->paf->hmmio, buffer, size) != size)
2034 return AVIERR_FILEREAD;
2035 }
2036
2037 return AVIERR_OK;
2038}
#define realloc
Definition: debug_ros.c:6
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 2040 of file avifile.c.

2041{
2042 LONG block;
2043
2044 /* pre-conditions */
2045 assert(This != NULL);
2046 assert(pos != NULL);
2047 assert(offset != NULL);
2048 assert(This->sInfo.dwSampleSize != 0);
2049 assert(*pos >= This->sInfo.dwStart);
2050
2051 /* convert start sample to start bytes */
2052 (*offset) = (*pos) - This->sInfo.dwStart;
2053 (*offset) *= This->sInfo.dwSampleSize;
2054
2055 /* convert bytes to block number */
2056 for (block = 0; block <= This->lLastFrame; block++) {
2057 if (This->idxFrames[block].dwChunkLength <= *offset)
2058 (*offset) -= This->idxFrames[block].dwChunkLength;
2059 else
2060 break;
2061 }
2062
2063 *pos = block;
2064}
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 2066 of file avifile.c.

2067{
2068 MainAVIHeader MainAVIHdr;
2069 IAVIStreamImpl* pStream;
2070 MMCKINFO ckRIFF;
2071 MMCKINFO ckLIST1;
2072 MMCKINFO ckLIST2;
2073 MMCKINFO ck;
2074 DWORD nStream;
2075 DWORD dwPos;
2076 HRESULT hr;
2077
2078 /* initialize some things */
2079 if (This->dwMoviChunkPos == 0)
2081
2082 /* written one record too much? */
2083 if (This->ckLastRecord.dwFlags & MMIO_DIRTY) {
2084 This->dwNextFramePos -= 3 * sizeof(DWORD);
2085 if (This->nIdxRecords > 0)
2086 This->nIdxRecords--;
2087 }
2088
2090
2091 assert(This->fInfo.dwScale != 0);
2092
2093 memset(&MainAVIHdr, 0, sizeof(MainAVIHdr));
2094 MainAVIHdr.dwMicroSecPerFrame = MulDiv(This->fInfo.dwRate, 1000000,
2095 This->fInfo.dwScale);
2096 MainAVIHdr.dwMaxBytesPerSec = This->fInfo.dwMaxBytesPerSec;
2098 MainAVIHdr.dwFlags = This->fInfo.dwFlags;
2099 MainAVIHdr.dwTotalFrames = This->fInfo.dwLength;
2100 MainAVIHdr.dwInitialFrames = 0;
2101 MainAVIHdr.dwStreams = This->fInfo.dwStreams;
2102 MainAVIHdr.dwSuggestedBufferSize = This->fInfo.dwSuggestedBufferSize;
2103 MainAVIHdr.dwWidth = This->fInfo.dwWidth;
2104 MainAVIHdr.dwHeight = This->fInfo.dwHeight;
2105 MainAVIHdr.dwInitialFrames = This->dwInitialFrames;
2106
2107 /* now begin writing ... */
2108 mmioSeek(This->hmmio, 0, SEEK_SET);
2109
2110 /* RIFF chunk */
2111 ckRIFF.cksize = 0;
2112 ckRIFF.fccType = formtypeAVI;
2113 if (mmioCreateChunk(This->hmmio, &ckRIFF, MMIO_CREATERIFF) != S_OK)
2114 return AVIERR_FILEWRITE;
2115
2116 /* AVI headerlist */
2117 ckLIST1.cksize = 0;
2118 ckLIST1.fccType = listtypeAVIHEADER;
2119 if (mmioCreateChunk(This->hmmio, &ckLIST1, MMIO_CREATELIST) != S_OK)
2120 return AVIERR_FILEWRITE;
2121
2122 /* MainAVIHeader */
2123 ck.ckid = ckidAVIMAINHDR;
2124 ck.cksize = sizeof(MainAVIHdr);
2125 ck.fccType = 0;
2126 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2127 return AVIERR_FILEWRITE;
2128 if (mmioWrite(This->hmmio, (HPSTR)&MainAVIHdr, ck.cksize) != ck.cksize)
2129 return AVIERR_FILEWRITE;
2130 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2131 return AVIERR_FILEWRITE;
2132
2133 /* write the headers of each stream into a separate streamheader list */
2134 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2135 AVIStreamHeader strHdr;
2136
2137 pStream = This->ppStreams[nStream];
2138
2139 /* begin the new streamheader list */
2140 ckLIST2.cksize = 0;
2141 ckLIST2.fccType = listtypeSTREAMHEADER;
2142 if (mmioCreateChunk(This->hmmio, &ckLIST2, MMIO_CREATELIST) != S_OK)
2143 return AVIERR_FILEWRITE;
2144
2145 /* create an AVIStreamHeader from the AVSTREAMINFO */
2146 strHdr.fccType = pStream->sInfo.fccType;
2147 strHdr.fccHandler = pStream->sInfo.fccHandler;
2148 strHdr.dwFlags = pStream->sInfo.dwFlags;
2149 strHdr.wPriority = pStream->sInfo.wPriority;
2150 strHdr.wLanguage = pStream->sInfo.wLanguage;
2151 strHdr.dwInitialFrames = pStream->sInfo.dwInitialFrames;
2152 strHdr.dwScale = pStream->sInfo.dwScale;
2153 strHdr.dwRate = pStream->sInfo.dwRate;
2154 strHdr.dwStart = pStream->sInfo.dwStart;
2155 strHdr.dwLength = pStream->sInfo.dwLength;
2157 strHdr.dwQuality = pStream->sInfo.dwQuality;
2158 strHdr.dwSampleSize = pStream->sInfo.dwSampleSize;
2159 strHdr.rcFrame.left = pStream->sInfo.rcFrame.left;
2160 strHdr.rcFrame.top = pStream->sInfo.rcFrame.top;
2161 strHdr.rcFrame.right = pStream->sInfo.rcFrame.right;
2162 strHdr.rcFrame.bottom = pStream->sInfo.rcFrame.bottom;
2163
2164 /* now write the AVIStreamHeader */
2166 ck.cksize = sizeof(strHdr);
2167 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2168 return AVIERR_FILEWRITE;
2169 if (mmioWrite(This->hmmio, (HPSTR)&strHdr, ck.cksize) != ck.cksize)
2170 return AVIERR_FILEWRITE;
2171 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2172 return AVIERR_FILEWRITE;
2173
2174 /* ... the hopefully ever present streamformat ... */
2176 ck.cksize = pStream->cbFormat;
2177 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2178 return AVIERR_FILEWRITE;
2179 if (pStream->lpFormat != NULL && ck.cksize > 0) {
2180 if (mmioWrite(This->hmmio, pStream->lpFormat, ck.cksize) != ck.cksize)
2181 return AVIERR_FILEWRITE;
2182 }
2183 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2184 return AVIERR_FILEWRITE;
2185
2186 /* ... some optional existing handler data ... */
2187 if (pStream->lpHandlerData != NULL && pStream->cbHandlerData > 0) {
2189 ck.cksize = pStream->cbHandlerData;
2190 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2191 return AVIERR_FILEWRITE;
2192 if (mmioWrite(This->hmmio, pStream->lpHandlerData, ck.cksize) != ck.cksize)
2193 return AVIERR_FILEWRITE;
2194 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2195 return AVIERR_FILEWRITE;
2196 }
2197
2198 /* ... some optional additional extra chunk for this stream ... */
2199 if (pStream->extra.lp != NULL && pStream->extra.cb > 0) {
2200 /* the chunk header(s) are already in the structure */
2201 if (mmioWrite(This->hmmio, pStream->extra.lp, pStream->extra.cb) != pStream->extra.cb)
2202 return AVIERR_FILEWRITE;
2203 }
2204
2205 /* ... an optional name for this stream ... */
2206 if (pStream->sInfo.szName[0]) {
2207 LPSTR str;
2208
2209 ck.ckid = ckidSTREAMNAME;
2210 ck.cksize = lstrlenW(pStream->sInfo.szName) + 1;
2211 if (ck.cksize & 1) /* align */
2212 ck.cksize++;
2213 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2214 return AVIERR_FILEWRITE;
2215
2216 /* the streamname must be saved in ASCII not Unicode */
2217 str = malloc(ck.cksize);
2218 if (str == NULL)
2219 return AVIERR_MEMORY;
2220 WideCharToMultiByte(CP_ACP, 0, pStream->sInfo.szName, -1, str,
2221 ck.cksize, NULL, NULL);
2222
2223 if (mmioWrite(This->hmmio, str, ck.cksize) != ck.cksize) {
2224 free(str);
2225 return AVIERR_FILEWRITE;
2226 }
2227
2228 free(str);
2229 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2230 return AVIERR_FILEWRITE;
2231 }
2232
2233 /* close streamheader list for this stream */
2234 if (mmioAscend(This->hmmio, &ckLIST2, 0) != S_OK)
2235 return AVIERR_FILEWRITE;
2236 } /* for (0 <= nStream < MainAVIHdr.dwStreams) */
2237
2238 /* close the aviheader list */
2239 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
2240 return AVIERR_FILEWRITE;
2241
2242 /* check for padding to pre-guessed 'movi'-chunk position */
2243 dwPos = ckLIST1.dwDataOffset + ckLIST1.cksize;
2244 if (This->dwMoviChunkPos - 2 * sizeof(DWORD) > dwPos) {
2245 ck.ckid = ckidAVIPADDING;
2246 ck.cksize = This->dwMoviChunkPos - dwPos - 4 * sizeof(DWORD);
2247 assert((LONG)ck.cksize >= 0);
2248
2249 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2250 return AVIERR_FILEWRITE;
2251 if (mmioSeek(This->hmmio, ck.cksize, SEEK_CUR) == -1)
2252 return AVIERR_FILEWRITE;
2253 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2254 return AVIERR_FILEWRITE;
2255 }
2256
2257 /* now write the 'movi' chunk */
2258 mmioSeek(This->hmmio, This->dwMoviChunkPos - 2 * sizeof(DWORD), SEEK_SET);
2259 ckLIST1.cksize = 0;
2260 ckLIST1.fccType = listtypeAVIMOVIE;
2261 if (mmioCreateChunk(This->hmmio, &ckLIST1, MMIO_CREATELIST) != S_OK)
2262 return AVIERR_FILEWRITE;
2263 if (mmioSeek(This->hmmio, This->dwNextFramePos, SEEK_SET) == -1)
2264 return AVIERR_FILEWRITE;
2265 if (mmioAscend(This->hmmio, &ckLIST1, 0) != S_OK)
2266 return AVIERR_FILEWRITE;
2267
2268 /* write 'idx1' chunk */
2270 if (FAILED(hr))
2271 return hr;
2272
2273 /* write optional extra file chunks */
2274 if (This->fileextra.lp != NULL && This->fileextra.cb > 0) {
2275 /* as for the streams, are the chunk header(s) in the structure */
2276 if (mmioWrite(This->hmmio, This->fileextra.lp, This->fileextra.cb) != This->fileextra.cb)
2277 return AVIERR_FILEWRITE;
2278 }
2279
2280 /* close RIFF chunk */
2281 if (mmioAscend(This->hmmio, &ckRIFF, 0) != S_OK)
2282 return AVIERR_FILEWRITE;
2283
2284 /* add some JUNK at end for bad parsers */
2285 memset(&ckRIFF, 0, sizeof(ckRIFF));
2286 mmioWrite(This->hmmio, (HPSTR)&ckRIFF, sizeof(ckRIFF));
2287 mmioFlush(This->hmmio, 0);
2288
2289 return AVIERR_OK;
2290}
static DWORD AVIFILE_ComputeMoviStart(IAVIFileImpl *This)
Definition: avifile.c:1440
static HRESULT AVIFILE_SaveIndex(const IAVIFileImpl *This)
Definition: avifile.c:2292
static void AVIFILE_UpdateInfo(IAVIFileImpl *This)
Definition: avifile.c:2450
#define WideCharToMultiByte
Definition: compat.h:111
#define SEEK_CUR
Definition: stdio.h:44
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
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::@3683 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
char * LPSTR
Definition: typedefs.h:51
#define AVIERR_FILEWRITE
Definition: vfw.h:1752

Referenced by IUnknown_fnRelease().

◆ AVIFILE_SaveIndex()

static HRESULT AVIFILE_SaveIndex ( const IAVIFileImpl This)
static

Definition at line 2292 of file avifile.c.

2293{
2294 IAVIStreamImpl *pStream;
2296 MMCKINFO ck;
2297 DWORD nStream;
2298 LONG n;
2299
2300 ck.ckid = ckidAVINEWINDEX;
2301 ck.cksize = 0;
2302 if (mmioCreateChunk(This->hmmio, &ck, 0) != S_OK)
2303 return AVIERR_FILEWRITE;
2304
2305 if (This->fInfo.dwFlags & AVIFILEINFO_ISINTERLEAVED) {
2306 /* is interleaved -- write block of corresponding frames */
2307 LONG lInitialFrames = 0;
2308 LONG stepsize;
2309 LONG i;
2310
2311 if (This->ppStreams[0]->sInfo.dwSampleSize == 0)
2312 stepsize = 1;
2313 else
2314 stepsize = AVIStreamTimeToSample(&This->ppStreams[0]->IAVIStream_iface, 1000000);
2315
2316 assert(stepsize > 0);
2317
2318 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2319 if (lInitialFrames < This->ppStreams[nStream]->sInfo.dwInitialFrames)
2320 lInitialFrames = This->ppStreams[nStream]->sInfo.dwInitialFrames;
2321 }
2322
2323 for (i = -lInitialFrames; i < (LONG)This->fInfo.dwLength - lInitialFrames;
2324 i += stepsize) {
2325 DWORD nFrame = lInitialFrames + i;
2326
2327 assert(nFrame < This->nIdxRecords);
2328
2329 idx.ckid = listtypeAVIRECORD;
2330 idx.dwFlags = AVIIF_LIST;
2331 idx.dwChunkLength = This->idxRecords[nFrame].dwChunkLength;
2332 idx.dwChunkOffset = This->idxRecords[nFrame].dwChunkOffset
2333 - This->dwMoviChunkPos;
2334 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2335 return AVIERR_FILEWRITE;
2336
2337 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2338 pStream = This->ppStreams[nStream];
2339
2340 /* heave we reached start of this stream? */
2341 if (-(LONG)pStream->sInfo.dwInitialFrames > i)
2342 continue;
2343
2344 if (pStream->sInfo.dwInitialFrames < lInitialFrames)
2345 nFrame -= (lInitialFrames - pStream->sInfo.dwInitialFrames);
2346
2347 /* reached end of this stream? */
2348 if (pStream->lLastFrame <= nFrame)
2349 continue;
2350
2351 if ((pStream->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
2352 pStream->sInfo.dwFormatChangeCount != 0 &&
2353 pStream->idxFmtChanges != NULL) {
2354 DWORD pos;
2355
2356 for (pos = 0; pos < pStream->sInfo.dwFormatChangeCount; pos++) {
2357 if (pStream->idxFmtChanges[pos].ckid == nFrame) {
2358 idx.dwFlags = AVIIF_NOTIME;
2359 idx.ckid = MAKEAVICKID(cktypePALchange, pStream->nStream);
2360 idx.dwChunkLength = pStream->idxFmtChanges[pos].dwChunkLength;
2361 idx.dwChunkOffset = pStream->idxFmtChanges[pos].dwChunkOffset
2362 - This->dwMoviChunkPos;
2363
2364 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2365 return AVIERR_FILEWRITE;
2366 break;
2367 }
2368 }
2369 } /* if have formatchanges */
2370
2371 idx.ckid = pStream->idxFrames[nFrame].ckid;
2372 idx.dwFlags = pStream->idxFrames[nFrame].dwFlags;
2373 idx.dwChunkLength = pStream->idxFrames[nFrame].dwChunkLength;
2374 idx.dwChunkOffset = pStream->idxFrames[nFrame].dwChunkOffset
2375 - This->dwMoviChunkPos;
2376 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2377 return AVIERR_FILEWRITE;
2378 }
2379 }
2380 } else {
2381 /* not interleaved -- write index for each stream at once */
2382 for (nStream = 0; nStream < This->fInfo.dwStreams; nStream++) {
2383 pStream = This->ppStreams[nStream];
2384
2385 for (n = 0; n <= pStream->lLastFrame; n++) {
2386 if ((pStream->sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES) &&
2387 (pStream->sInfo.dwFormatChangeCount != 0)) {
2388 DWORD pos;
2389
2390 for (pos = 0; pos < pStream->sInfo.dwFormatChangeCount; pos++) {
2391 if (pStream->idxFmtChanges[pos].ckid == n) {
2392 idx.dwFlags = AVIIF_NOTIME;
2393 idx.ckid = MAKEAVICKID(cktypePALchange, pStream->nStream);
2394 idx.dwChunkLength = pStream->idxFmtChanges[pos].dwChunkLength;
2395 idx.dwChunkOffset =
2396 pStream->idxFmtChanges[pos].dwChunkOffset - This->dwMoviChunkPos;
2397 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2398 return AVIERR_FILEWRITE;
2399 break;
2400 }
2401 }
2402 } /* if have formatchanges */
2403
2404 idx.ckid = pStream->idxFrames[n].ckid;
2405 idx.dwFlags = pStream->idxFrames[n].dwFlags;
2406 idx.dwChunkLength = pStream->idxFrames[n].dwChunkLength;
2407 idx.dwChunkOffset = pStream->idxFrames[n].dwChunkOffset
2408 - This->dwMoviChunkPos;
2409
2410 if (mmioWrite(This->hmmio, (HPSTR)&idx, sizeof(idx)) != sizeof(idx))
2411 return AVIERR_FILEWRITE;
2412 }
2413 }
2414 } /* if not interleaved */
2415
2416 if (mmioAscend(This->hmmio, &ck, 0) != S_OK)
2417 return AVIERR_FILEWRITE;
2418
2419 return AVIERR_OK;
2420}
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 2422 of file avifile.c.

2423{
2424 UINT i;
2425 UINT nStream;
2426
2427 /* pre-condition */
2428 assert(lSkip >= 0);
2429
2430 if (fcc != 0) {
2431 /* search the number of the specified stream */
2432 nStream = (ULONG)-1;
2433 for (i = 0; i < This->fInfo.dwStreams; i++) {
2434 assert(This->ppStreams[i] != NULL);
2435
2436 if (This->ppStreams[i]->sInfo.fccType == fcc) {
2437 if (lSkip == 0) {
2438 nStream = i;
2439 break;
2440 } else
2441 lSkip--;
2442 }
2443 }
2444 } else
2445 nStream = lSkip;
2446
2447 return nStream;
2448}
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 2450 of file avifile.c.

2451{
2452 UINT i;
2453
2454 /* pre-conditions */
2455 assert(This != NULL);
2456
2457 This->fInfo.dwMaxBytesPerSec = 0;
2459 This->fInfo.dwSuggestedBufferSize = 0;
2460 This->fInfo.dwWidth = 0;
2461 This->fInfo.dwHeight = 0;
2462 This->fInfo.dwScale = 0;
2463 This->fInfo.dwRate = 0;
2464 This->fInfo.dwLength = 0;
2465 This->dwInitialFrames = 0;
2466
2467 for (i = 0; i < This->fInfo.dwStreams; i++) {
2468 AVISTREAMINFOW *psi;
2469 DWORD n;
2470
2471 /* pre-conditions */
2472 assert(This->ppStreams[i] != NULL);
2473
2474 psi = &This->ppStreams[i]->sInfo;
2475 assert(psi->dwScale != 0);
2476 assert(psi->dwRate != 0);
2477
2478 if (i == 0) {
2479 /* use first stream timings as base */
2480 This->fInfo.dwScale = psi->dwScale;
2481 This->fInfo.dwRate = psi->dwRate;
2482 This->fInfo.dwLength = psi->dwLength;
2483 } else {
2484 n = AVIStreamSampleToSample(&This->ppStreams[0]->IAVIStream_iface,
2485 &This->ppStreams[i]->IAVIStream_iface, psi->dwLength);
2486 if (This->fInfo.dwLength < n)
2487 This->fInfo.dwLength = n;
2488 }
2489
2490 if (This->dwInitialFrames < psi->dwInitialFrames)
2491 This->dwInitialFrames = psi->dwInitialFrames;
2492
2493 if (This->fInfo.dwSuggestedBufferSize < psi->dwSuggestedBufferSize)
2494 This->fInfo.dwSuggestedBufferSize = psi->dwSuggestedBufferSize;
2495
2496 if (psi->dwSampleSize != 0) {
2497 /* fixed sample size -- exact computation */
2498 This->fInfo.dwMaxBytesPerSec += MulDiv(psi->dwSampleSize, psi->dwRate,
2499 psi->dwScale);
2500 } else {
2501 /* variable sample size -- only upper limit */
2502 This->fInfo.dwMaxBytesPerSec += MulDiv(psi->dwSuggestedBufferSize,
2503 psi->dwRate, psi->dwScale);
2504
2505 /* update dimensions */
2506 n = psi->rcFrame.right - psi->rcFrame.left;
2507 if (This->fInfo.dwWidth < n)
2508 This->fInfo.dwWidth = n;
2509 n = psi->rcFrame.bottom - psi->rcFrame.top;
2510 if (This->fInfo.dwHeight < n)
2511 This->fInfo.dwHeight = n;
2512 }
2513 }
2514}
#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 2516 of file avifile.c.

2519{
2520 MMCKINFO ck;
2521
2522 ck.ckid = ckid;
2523 ck.cksize = size;
2524 ck.fccType = 0;
2525
2526 /* if no frame/block is already written, we must compute start of movi chunk */
2527 if (This->paf->dwMoviChunkPos == 0)
2529
2530 if (mmioSeek(This->paf->hmmio, This->paf->dwNextFramePos, SEEK_SET) == -1)
2531 return AVIERR_FILEWRITE;
2532
2533 if (mmioCreateChunk(This->paf->hmmio, &ck, 0) != S_OK)
2534 return AVIERR_FILEWRITE;
2535 if (buffer != NULL && size > 0) {
2536 if (mmioWrite(This->paf->hmmio, buffer, size) != size)
2537 return AVIERR_FILEWRITE;
2538 }
2539 if (mmioAscend(This->paf->hmmio, &ck, 0) != S_OK)
2540 return AVIERR_FILEWRITE;
2541
2542 This->paf->fDirty = TRUE;
2543 This->paf->dwNextFramePos = mmioSeek(This->paf->hmmio, 0, SEEK_CUR);
2544
2545 return AVIFILE_AddFrame(This, ckid, size,
2546 ck.dwDataOffset - 2 * sizeof(DWORD), flags);
2547}

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);
354 This->ppStreams[n] = calloc(1, sizeof(IAVIStreamImpl));
355 if (This->ppStreams[n] == NULL)
356 return AVIERR_MEMORY;
357
358 /* initialize the new allocated stream */
360
361 This->fInfo.dwStreams++;
362 This->fDirty = TRUE;
363
364 /* update our AVIFILEINFO structure */
366
367 /* return it */
368 *avis = &This->ppStreams[n]->IAVIStream_iface;
369 IAVIStream_AddRef(*avis);
370
371 return AVIERR_OK;
372}
#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 445 of file avifile.c.

446{
448 ULONG nStream;
449
450 TRACE("(%p,0x%08lX,%ld)\n", iface, fccType, lParam);
451
452 /* check parameter */
453 if (lParam < 0)
454 return AVIERR_BADPARAM;
455
456 /* Have user write permissions? */
457 if ((This->uMode & MMIO_RWMODE) == 0)
458 return AVIERR_READONLY;
459
460 nStream = AVIFILE_SearchStream(This, fccType, lParam);
461
462 /* Does the requested stream exist? */
463 if (nStream < This->fInfo.dwStreams &&
464 This->ppStreams[nStream] != NULL) {
465 /* ... so delete it now */
466 free(This->ppStreams[nStream]);
467 This->fInfo.dwStreams--;
468 if (nStream < This->fInfo.dwStreams)
469 memmove(&This->ppStreams[nStream], &This->ppStreams[nStream + 1],
470 (This->fInfo.dwStreams - nStream) * sizeof(This->ppStreams[0]));
471
472 This->ppStreams[This->fInfo.dwStreams] = NULL;
473 This->fDirty = TRUE;
474
475 /* This->fInfo will be updated further when asked for */
476 return AVIERR_OK;
477 } else
478 return AVIERR_NODATA;
479}
static ULONG AVIFILE_SearchStream(const IAVIFileImpl *This, DWORD fccType, LONG lSkip)
Definition: avifile.c:2422
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 404 of file avifile.c.

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

◆ 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%08lX,%ld)\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,%ld)\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 395 of file avifile.c.

396{
398
399 TRACE("(%p,0x%08lX,%p,%p)\n", iface, ckid, lpData, size);
400
401 return ReadExtraChunk(&This->fileextra, ckid, lpData, size);
402}
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 374 of file avifile.c.

375{
377
378 TRACE("(%p,0x%08lX,%p,%ld)\n", iface, ckid, lpData, size);
379
380 /* check parameters */
381 if (lpData == NULL)
382 return AVIERR_BADPARAM;
383 if (size < 0)
384 return AVIERR_BADSIZE;
385
386 /* Do we have write permission? */
387 if ((This->uMode & MMIO_RWMODE) == 0)
388 return AVIERR_READONLY;
389
390 This->fDirty = TRUE;
391
392 return WriteExtraChunk(&This->fileextra, ckid, lpData, size);
393}
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 693 of file avifile.c.

694{
697
698 TRACE("(%p) ref=%ld\n", This, ref);
699
700 /* also add ref to parent, so that it doesn't kill us */
701 if (This->paf != NULL && ref == 1)
702 IAVIFile_AddRef(&This->paf->IAVIFile_iface);
703
704 return ref;
705}
#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 720 of file avifile.c.

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

◆ IAVIStream_fnDelete()

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

Definition at line 1200 of file avifile.c.

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

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

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

◆ IAVIStream_fnQueryInterface()

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

Definition at line 670 of file avifile.c.

671{
673
674 TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppv);
675
676 if (!ppv) {
677 WARN("invalid parameter\n");
678 return E_INVALIDARG;
679 }
680 *ppv = NULL;
681
682 if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IAVIStream, riid)) {
683 *ppv = iface;
684 IAVIStream_AddRef(iface);
685
686 return S_OK;
687 }
688 /* FIXME: IAVIStreaming interface */
689
690 return E_NOINTERFACE;
691}
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:3479

◆ 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 991 of file avifile.c.

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

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

◆ IAVIStream_fnReadFormat()

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

Definition at line 844 of file avifile.c.

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

◆ IAVIStream_fnRelease()

static ULONG WINAPI IAVIStream_fnRelease ( IAVIStream iface)
static

Definition at line 707 of file avifile.c.

708{
711
712 TRACE("(%p) ref=%ld\n", This, ref);
713
714 if (This->paf != NULL && ref == 0)
715 IAVIFile_Release(&This->paf->IAVIFile_iface);
716
717 return ref;
718}
#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 883 of file avifile.c.

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

1309{
1310 FIXME("(%p,%p,%ld): stub\n", iface, info, infolen);
1311
1312 return E_FAIL;
1313}
#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 1110 of file avifile.c.

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

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

◆ 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 502 of file avifile.c.

503{
505
506 return IUnknown_AddRef(This->outer_unk);
507}
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 516 of file avifile.c.

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

◆ IPersistFile_fnGetCurFile()

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

Definition at line 608 of file avifile.c.

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

◆ IPersistFile_fnIsDirty()

static HRESULT WINAPI IPersistFile_fnIsDirty ( IPersistFile iface)
static

Definition at line 528 of file avifile.c.

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

◆ IPersistFile_fnLoad()

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

Definition at line 537 of file avifile.c.

538{
540 int len;
541
542 TRACE("(%p,%s,0x%08lX)\n", iface, debugstr_w(pszFileName), dwMode);
543
544 /* check parameter */
545 if (pszFileName == NULL)
546 return AVIERR_BADPARAM;
547
548 if (This->hmmio != NULL)
549 return AVIERR_ERROR; /* No reuse of this object for another file! */
550
551 /* remember mode and name */
552 This->uMode = dwMode;
553
554 len = lstrlenW(pszFileName) + 1;
555 This->szFileName = malloc(len * sizeof(WCHAR));
556 if (This->szFileName == NULL)
557 return AVIERR_MEMORY;
558 lstrcpyW(This->szFileName, pszFileName);
559
560 /* try to open the file */
561 This->hmmio = mmioOpenW(This->szFileName, NULL, MMIO_ALLOCBUF | dwMode);
562 if (This->hmmio == NULL) {
563 /* mmioOpenW not in native DLLs of Win9x -- try mmioOpenA */
564 LPSTR szFileName;
565
566 len = WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, NULL, 0, NULL, NULL);
567 szFileName = malloc(len * sizeof(CHAR));
568 if (szFileName == NULL)
569 return AVIERR_MEMORY;
570
571 WideCharToMultiByte(CP_ACP, 0, This->szFileName, -1, szFileName, len, NULL, NULL);
572
573 This->hmmio = mmioOpenA(szFileName, NULL, MMIO_ALLOCBUF | dwMode);
574 free(szFileName);
575 if (This->hmmio == NULL)
576 return AVIERR_FILEOPEN;
577 }
578
579 /* should we create a new file? */
580 if (dwMode & OF_CREATE) {
581 memset(& This->fInfo, 0, sizeof(This->fInfo));
583
584 return AVIERR_OK;
585 } else
586 return AVIFILE_LoadFile(This);
587}
static HRESULT AVIFILE_LoadFile(IAVIFileImpl *This)
Definition: avifile.c:1556
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
char CHAR
Definition: pedump.c:57
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
#define OF_CREATE
Definition: winbase.h:128

◆ IPersistFile_fnQueryInterface()

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

Definition at line 495 of file avifile.c.

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

◆ IPersistFile_fnRelease()

static ULONG WINAPI IPersistFile_fnRelease ( IPersistFile iface)
static

Definition at line 509 of file avifile.c.

510{
512
513 return IUnknown_Release(This->outer_unk);
514}

◆ IPersistFile_fnSave()

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

Definition at line 589 of file avifile.c.

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

◆ IPersistFile_fnSaveCompleted()

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

Definition at line 599 of file avifile.c.

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

◆ IUnknown_fnAddRef()

static ULONG WINAPI IUnknown_fnAddRef ( IUnknown iface)
static

Definition at line 189 of file avifile.c.

190{
193
194 TRACE("(%p) ref=%ld\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=%ld\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 %lu reference to stream %u (%p)!\n",
215 This->ppStreams[i]->ref, i, This->ppStreams[i]);
216 AVIFILE_DestructAVIStream(This->ppStreams[i]);
217 free(This->ppStreams[i]);
218 This->ppStreams[i] = NULL;
219 }
220 }
221
222 if (This->idxRecords != NULL) {
223 free(This->idxRecords);
224 This->idxRecords = NULL;
225 This->nIdxRecords = 0;
226 }
227
228 if (This->fileextra.lp != NULL) {
229 free(This->fileextra.lp);
230 This->fileextra.lp = NULL;
231 This->fileextra.cb = 0;
232 }
233
234 free(This->szFileName);
235 This->szFileName = NULL;
236
237 if (This->hmmio != NULL) {
238 mmioClose(This->hmmio, 0);
239 This->hmmio = NULL;
240 }
241
242 free(This);
243 }
244 return ref;
245}
static HRESULT AVIFILE_SaveFile(IAVIFileImpl *This)
Definition: avifile.c:2066
static void AVIFILE_DestructAVIStream(IAVIStreamImpl *This)
Definition: avifile.c:1519
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:404
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:395
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:374
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:445

Definition at line 481 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:693
static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream *iface, LONG pos, void *format, LONG formatsize)
Definition: avifile.c:883
static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream *iface, REFIID riid, void **ppv)
Definition: avifile.c:670
static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream *iface, LPARAM lParam1, LPARAM lParam2)
Definition: avifile.c:720
static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream *iface, LONG start, LONG samples)
Definition: avifile.c:1200
static HRESULT WINAPI IAVIStream_fnRead(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, LONG *bytesread, LONG *samplesread)
Definition: avifile.c:991
static ULONG WINAPI IAVIStream_fnRelease(IAVIStream *iface)
Definition: avifile.c:707
static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream *iface, AVISTREAMINFOW *psi, LONG size)
Definition: avifile.c:728
static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream *iface, DWORD fcc, void *lp, LONG size)
Definition: avifile.c:1261
static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream *iface, LONG pos, void *format, LONG *formatsize)
Definition: avifile.c:844
static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream *iface, LONG start, LONG samples, void *buffer, LONG buffersize, DWORD flags, LONG *sampwritten, LONG *byteswritten)
Definition: avifile.c:1110
static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream *iface, DWORD fcc, void *lp, LONG *lpread)
Definition: avifile.c:1238
static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream *iface, AVISTREAMINFOW *info, LONG infolen)
Definition: avifile.c:1308

Definition at line 1315 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:589
static HRESULT WINAPI IPersistFile_fnIsDirty(IPersistFile *iface)
Definition: avifile.c:528
static HRESULT WINAPI IPersistFile_fnQueryInterface(IPersistFile *iface, REFIID riid, void **ppv)
Definition: avifile.c:495
static ULONG WINAPI IPersistFile_fnRelease(IPersistFile *iface)
Definition: avifile.c:509
static ULONG WINAPI IPersistFile_fnAddRef(IPersistFile *iface)
Definition: avifile.c:502
static HRESULT WINAPI IPersistFile_fnSaveCompleted(IPersistFile *iface, LPCOLESTR pszFileName)
Definition: avifile.c:599
static HRESULT WINAPI IPersistFile_fnGetClassID(IPersistFile *iface, LPCLSID pClassID)
Definition: avifile.c:516
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile *iface, LPOLESTR *ppszFileName)
Definition: avifile.c:608
static HRESULT WINAPI IPersistFile_fnLoad(IPersistFile *iface, LPCOLESTR pszFileName, DWORD dwMode)
Definition: avifile.c:537

Definition at line 632 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().