244 lines
7.8 KiB
C
244 lines
7.8 KiB
C
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) Microsoft Corporation 1985 - 1995. All rights reserved.
|
||
|
|
||
|
AVIIDX.H - AVI Index stuff
|
||
|
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#ifndef _INC_AVIFMT
|
||
|
#include <vfw.h>
|
||
|
#endif
|
||
|
|
||
|
#ifndef EXTERN_C
|
||
|
#ifdef __cplusplus
|
||
|
#define EXTERN_C extern "C"
|
||
|
#else
|
||
|
#define EXTERN_C extern
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#define ERR_POS (-100) // bad position
|
||
|
#define ERR_IDX (-1) // bad index
|
||
|
|
||
|
typedef AVIINDEXENTRY _huge *PAVIINDEXENTRY;
|
||
|
|
||
|
|
||
|
// to some customers, this 1Gb limit is not worth the few bytes it saves.
|
||
|
#ifndef _WIN32
|
||
|
|
||
|
//
|
||
|
// this is the in memory form of a AVI INDEX, we want this to be 8 bytes
|
||
|
// to save memory.
|
||
|
//
|
||
|
// the bit fields may not be portable, so a new structure will be needed.
|
||
|
//
|
||
|
// we always access via macros, so changing the structure should be posible
|
||
|
//
|
||
|
// this stucture sotres the following:
|
||
|
//
|
||
|
// offset 0-1GB (30 bits) we assume even number so only need 29bits
|
||
|
// flags (4 bits)
|
||
|
// stream 0-127 (7 bits)
|
||
|
// length 0-4MB (24 bits)
|
||
|
//
|
||
|
#pragma pack(1)
|
||
|
typedef union {
|
||
|
struct {
|
||
|
DWORD offset; // 0-1GB
|
||
|
DWORD length; // 0-4MB
|
||
|
};
|
||
|
struct {
|
||
|
BYTE ack[3]; // 24 bits of the offset
|
||
|
WORD flags; // access to all flags
|
||
|
BYTE smag[3]; // length (24 bits)
|
||
|
};
|
||
|
#if 0 // I hate bit-fields
|
||
|
struct {
|
||
|
DWORD offset:29; // 0-1GB
|
||
|
DWORD key:1;
|
||
|
DWORD nonkey:1;
|
||
|
DWORD pal:1;
|
||
|
DWORD stream:7; // 0-127
|
||
|
DWORD half:1;
|
||
|
DWORD length:24; // 0-4MB
|
||
|
};
|
||
|
#endif
|
||
|
} AVIIDX;
|
||
|
#pragma pack()
|
||
|
|
||
|
//
|
||
|
// limits
|
||
|
//
|
||
|
#define MAX_OFFSET (1l<<30)
|
||
|
#define MAX_LENGTH (1l<<24)
|
||
|
#define MAX_STREAM (1l<<7)
|
||
|
|
||
|
//
|
||
|
// index flags
|
||
|
//
|
||
|
#define IDX_OFFHI 0x001F // hi part of offset.
|
||
|
#define IDX_KEY 0x0020 // key frame
|
||
|
#define IDX_NONKEY 0x0040 // not a key frame (but not blank either)
|
||
|
#define IDX_PAL 0x0080 // palette change
|
||
|
#define IDX_STREAM 0x7F00 // stream number
|
||
|
#define IDX_HALF 0x8000 // RLE half frame.
|
||
|
#define IDX_NOTIME IDX_PAL
|
||
|
|
||
|
//
|
||
|
// macros to acces index to help porting
|
||
|
//
|
||
|
#define Index(px, lx) ((AVIIDX _huge *)px)[lx+1]
|
||
|
#define IndexOffset(px, lx) (LONG)((Index(px,lx).offset & 0x1FFFFFFF) * 2)
|
||
|
#define IndexLength(px, lx) (LONG)((Index(px,lx).length) >> 8)
|
||
|
#define IndexStream(px, lx) (BYTE)((Index(px,lx).flags & IDX_STREAM) >> 8)
|
||
|
#define IndexFlags(px, lx) (UINT)(Index(px,lx).flags)
|
||
|
|
||
|
#define IndexSetOffset(px, lx, x) { Index(px,lx).offset &= ~0x1FFFFFFF; Index(px,lx).offset |= (DWORD)(x)>>1; }
|
||
|
#define IndexSetLength(px, lx, x) { Index(px,lx).length &= ~0xFFFFFF00; Index(px,lx).length |= (DWORD)(x)<<8; }
|
||
|
#define IndexSetStream(px, lx, x) { Index(px,lx).flags &= ~IDX_STREAM; Index(px,lx).flags |= (DWORD)(x)<<8; }
|
||
|
#define IndexSetFlags(px, lx, x) { Index(px,lx).flags &= IDX_STREAM|IDX_OFFHI; Index(px,lx).flags |= (UINT)(x); }
|
||
|
#define IndexSetKey(px, lx) { Index(px,lx).flags |= IDX_KEY; Index(px,lx).flags &= ~(IDX_NONKEY); }
|
||
|
|
||
|
#else // --- 4Gb version of index macros ----------------------------------
|
||
|
|
||
|
typedef struct {
|
||
|
WORD flags;
|
||
|
WORD stream;
|
||
|
DWORD offset;
|
||
|
long length;
|
||
|
} AVIIDX;
|
||
|
|
||
|
//
|
||
|
// limits
|
||
|
//
|
||
|
#define MAX_OFFSET ((DWORD)0xffffffff) // signed in some places ??
|
||
|
#define MAX_LENGTH (1l<<30)
|
||
|
#define MAX_STREAM (1l<<16)
|
||
|
|
||
|
//
|
||
|
// index flags
|
||
|
//
|
||
|
#define IDX_KEY 0x0020 // key frame
|
||
|
#define IDX_NONKEY 0x0040 // not a key frame (but not blank either)
|
||
|
#define IDX_PAL 0x0080 // palette change
|
||
|
#define IDX_HALF 0x8000 // RLE half frame.
|
||
|
#define IDX_NOTIME IDX_PAL
|
||
|
|
||
|
//
|
||
|
// macros to acces index to help porting
|
||
|
//
|
||
|
#define Index(px, lx) (px)->idx[lx]
|
||
|
#define IndexOffset(px, lx) (Index(px,lx).offset)
|
||
|
#define IndexLength(px, lx) (Index(px,lx).length)
|
||
|
#define IndexStream(px, lx) (Index(px,lx).stream)
|
||
|
#define IndexFlags(px, lx) (Index(px,lx).flags)
|
||
|
|
||
|
#define IndexSetOffset(px, lx, x) { Index(px,lx).offset = (DWORD)(x); }
|
||
|
#define IndexSetLength(px, lx, x) { Index(px,lx).length = (long)(x); }
|
||
|
#define IndexSetStream(px, lx, x) { Index(px,lx).stream = (WORD)(x); }
|
||
|
#define IndexSetFlags(px, lx, x) { Index(px,lx).flags = (WORD)(x); }
|
||
|
#define IndexSetKey(px, lx) { Index(px,lx).flags |= IDX_KEY; Index(px,lx).flags &= ~(IDX_NONKEY); }
|
||
|
|
||
|
|
||
|
#endif //------------------------------------------------------------------
|
||
|
//
|
||
|
// special streams
|
||
|
//
|
||
|
#define STREAM_REC 0x7F // interleave records.
|
||
|
|
||
|
//
|
||
|
// this is the header we put on a list of AVIIDX entries.
|
||
|
//
|
||
|
#pragma warning(disable:4200)
|
||
|
typedef struct
|
||
|
{
|
||
|
LONG nIndex; // number of entries in index
|
||
|
LONG nIndexSize; // alocated size
|
||
|
AVIIDX idx[]; // the entries.
|
||
|
} AVIINDEX, _huge *PAVIINDEX;
|
||
|
|
||
|
//
|
||
|
// AVI Stream Index
|
||
|
//
|
||
|
typedef LONG (FAR PASCAL *STREAMIOPROC)(HANDLE hFile, LONG off, LONG cb, LPVOID p);
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
UINT stream; // stream number
|
||
|
UINT flags; // combination of all flags in index.
|
||
|
|
||
|
PAVIINDEX px; // main index
|
||
|
|
||
|
LONG lx; // Index index
|
||
|
LONG lPos; // index position
|
||
|
|
||
|
LONG lxStart; // Index start
|
||
|
|
||
|
LONG lStart; // start of stream
|
||
|
LONG lEnd; // end of stream
|
||
|
|
||
|
LONG lMaxSampleSize; // largest sample
|
||
|
LONG lSampleSize; // sample size for stream
|
||
|
|
||
|
LONG lFrames; // total "frames"
|
||
|
LONG lKeyFrames; // total key "frames"
|
||
|
LONG lPalFrames; // total pal "frames"
|
||
|
LONG lNulFrames; // total nul "frames"
|
||
|
|
||
|
HANDLE hFile;
|
||
|
STREAMIOPROC Read;
|
||
|
STREAMIOPROC Write;
|
||
|
|
||
|
} STREAMINDEX, *PSTREAMINDEX;
|
||
|
|
||
|
//
|
||
|
// create and free a index.
|
||
|
//
|
||
|
EXTERN_C PAVIINDEX IndexCreate(void);
|
||
|
#define FreeIndex(px) GlobalFreePtr(px)
|
||
|
|
||
|
//
|
||
|
// convert to and from a file index
|
||
|
//
|
||
|
EXTERN_C PAVIINDEX IndexAddFileIndex(PAVIINDEX px, AVIINDEXENTRY _huge *pidx, LONG cnt, LONG lAdjust, BOOL fRle);
|
||
|
EXTERN_C LONG IndexGetFileIndex(PAVIINDEX px, LONG l, LONG cnt, PAVIINDEXENTRY pidx, LONG lAdjust);
|
||
|
|
||
|
EXTERN_C PSTREAMINDEX MakeStreamIndex(PAVIINDEX px, UINT stream, LONG lStart, LONG lSampleSize, HANDLE hFile, STREAMIOPROC ReadProc, STREAMIOPROC WriteProc);
|
||
|
#define FreeStreamIndex(psx) LocalFree((HLOCAL)psx)
|
||
|
|
||
|
//
|
||
|
// index access functions
|
||
|
//
|
||
|
EXTERN_C LONG IndexFirst(PAVIINDEX px, UINT stream);
|
||
|
EXTERN_C LONG IndexNext (PAVIINDEX px, LONG lx, UINT f);
|
||
|
EXTERN_C LONG IndexPrev (PAVIINDEX px, LONG lx, UINT f);
|
||
|
|
||
|
//
|
||
|
// search index for data
|
||
|
//
|
||
|
#ifndef FIND_DIR
|
||
|
#define FIND_DIR 0x0000000FL // direction
|
||
|
#define FIND_NEXT 0x00000001L // go forward
|
||
|
#define FIND_PREV 0x00000004L // go backward
|
||
|
#define FIND_FROM_START 0x00000008L // start at the logical beginning
|
||
|
|
||
|
#define FIND_TYPE 0x000000F0L // type mask
|
||
|
#define FIND_KEY 0x00000010L // find key frame.
|
||
|
#define FIND_ANY 0x00000020L // find any (non-empty) sample
|
||
|
#define FIND_FORMAT 0x00000040L // find format change
|
||
|
#endif
|
||
|
|
||
|
#ifndef FIND_RET
|
||
|
#define FIND_RET 0x0000F000L // return mask
|
||
|
#define FIND_POS 0x00000000L // return logical position
|
||
|
#define FIND_LENGTH 0x00001000L // return logical size
|
||
|
#define FIND_OFFSET 0x00002000L // return physical position
|
||
|
#define FIND_SIZE 0x00003000L // return physical size
|
||
|
#define FIND_INDEX 0x00004000L // return physical index position
|
||
|
#endif
|
||
|
|
||
|
EXTERN_C LONG StreamFindSample(PSTREAMINDEX psx, LONG lPos, UINT f);
|
||
|
EXTERN_C LONG StreamRead(PSTREAMINDEX psx, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer);
|
||
|
EXTERN_C LONG StreamWrite(PSTREAMINDEX psx, LONG lStart, LONG lSamples, LPVOID lpBuffer, LONG cbBuffer);
|