Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,86 @@
/****************************************************************************
Entry for "C" calls
****************************************************************************/
#ifndef WCOMPC_H
#define WCOMPC_H
#ifndef YUVINPUTBUFFERCONFIG
#define YUVINPUTBUFFERCONFIG
typedef struct
{
int YWidth;
int YHeight;
int YStride;
int UVWidth;
int UVHeight;
int UVStride;
char * YBuffer;
char * UBuffer;
char * VBuffer;
} YUV_INPUT_BUFFER_CONFIG;
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void NewWC(void **wc);
void DeleteWC(void **wc);
int BeginCompressWC(
void *wc,
int ScreenWidth,
int ScreenHeight,
int Width,
int Height,
int XOffset,
int YOffset);
int CompressYUVWC(void *wc,
YUV_INPUT_BUFFER_CONFIG *YuvInputData,
unsigned char *OutputBufferPtr,
unsigned char *ReconBufferPtr,
int TargetSize);
int CompressWC(void *wc,
unsigned char *InputData,
unsigned char *OutputBufferPtr,
unsigned char *ReconBufferPtr,
int TargetSize);
int AnalyzeWC(void *wc,
unsigned char *InputData);
void EndCompressWC(void *wc);
int BeginDecompressWC(void *wc,
int ScreenWidth,
int ScreenHeight,
int Width,
int Height,
int XOffset,
int YOffset);
int DecompressWC(void *wc,
unsigned char *InputBufferPtr,
unsigned char *OutputBufferPtr);
void EndDecompressWC(void *wc);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,47 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef ASMCOLORCONVERSIONS_H
#define ASMCOLORCONVERSIONS_H
void CC_RGB32toYV12_MMX( unsigned char *RGBABuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_RGB32toYV12_XMM( unsigned char *RGBABuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_RGB24toYV12_MMX( unsigned char *RGBBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_RGB24toYV12_XMM( unsigned char *RGBBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_UYVYtoYV12_MMX( unsigned char *UYVYBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_UYVYtoYV12_XMM( unsigned char *UYVYBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_YUY2toYV12_MMX( unsigned char *YUY2Buffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_YUY2toYV12_XMM( unsigned char *YUY2Buffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_YVYUtoYV12_MMX( unsigned char *YVYUBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_YVYUtoYV12_XMM( unsigned char *YVYUBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
#endif /* ASMCOLORCONVERSIONS_H */

View file

@ -0,0 +1,21 @@
#ifndef _bigend_h
#define _bigend_h
#if defined(__cplusplus)
extern "C" {
#endif
#define invert2(x) ( (((x)>>8)&0x00ff) | (((x)<<8)&0xff00) )
#define invert4(x) ( ((invert2(x)&0x0000ffff)<<16) | (invert2((x>>16))&0x0000ffff) )
#define highByte(x) (unsigned char)x
#define mid2Byte(x) (unsigned char)(x >> 8)
#define mid1Byte(x) (unsigned char)(x >> 16)
#define lowByte(x) (unsigned char)(x >> 24)
#define SWAPENDS 1
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,20 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _CIDASM_H
#define _CIDASM_H
extern PROCTYPE getCPUType(void);
extern void InitXMMReg( void );
extern void TrashXMMReg( void *Junk );
extern int VerifyXMMReg( void );
#endif /* _CIDASM_H */

View file

@ -0,0 +1,37 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef COLORCONVERSIONS_H
#define COLORCONVERSIONS_H
#define ScaleFactor 0x8000
#define ShiftFactor 15
#define PixelsPerBlock 4
#define PixelsPerBlockShift 2
void CC_RGB32toYV12_C( unsigned char *RGBABuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_RGB24toYV12_C( unsigned char *RGBBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
void CC_UYVYtoYV12_C( unsigned char *UYVYBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_YUY2toYV12_C( unsigned char *YUY2Buffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch, int DstPitch );
void CC_YVYUtoYV12_C( unsigned char *YVYUBuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer, int SrcPitch,int DstPitch );
#endif /* COLORCONVERSIONS_H */

View file

@ -0,0 +1,73 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _dkpltfrm_h
#define _dkpltfrm_h
/********************************************************
PC for Win95/DOS/etc...
********************************************************/
/*
#define DX_COUNTERS 0
*/
/* #define VOXWARE_WIN32 1 */
#define SUPPORT565 1
#define DX_TR20 1
#define TINKER 1
#define LARGECHUNKS 1
#define RGBORDER 0
#define BGRORDER 1
#define DKTRUE 1
#define DKFALSE !DKTRUE
#define TBLOFFSET 0
#define CENTER_TABLE 0
#define BLACK16X2 0x00000000
//#include "nofar.h"
#include "littlend.h"
#define LIMITREADS /* limit reads average frame size */
#define LIMIT_1_5 /* limit reads to 1.5x the average frame size */
#define DISPLAYDIB 0
#define AUDIOINTERLEAVED 1
typedef int GfsHn;
#define slow_seek duck_seek
#define gooseCD(x,y)
#define COLORORDER RGBORDER
#define SWAPENDS 0
#define HW_CD_BUFFER 0
#define CD_ONLY 0
#define DX24BIT
#if !defined(UINT64)
typedef unsigned __int64 UINT64;
#endif
#endif /* include guards */

View file

@ -0,0 +1,871 @@
#ifndef _duck_hfb_h
#define _duck_hfb_h
/******************************************************************************\
<table BGCOLOR=#FFC0C0 border=1 WIDTH=100% ><tr><td><b>
duck_hfb.h </b></td><td><b> TrueMotion include file for buffering/streaming libraries </b>
</td></tr><tr><td>&nbsp</td><td> Version: 6.0.0
</td></tr><tr><td>&nbsp</td><td> Updated: $Date: 2010/07/23 19:10:44 $
</td></tr><tr><td>&nbsp</td><td> Copyright (c) 1994-98, The Duck Corp. All rights reserved.
</td></tr>
</table>
******************************************************************************/
#define lHFB_ HFB_
#define libFunc
#if defined(__cplusplus)
extern "C" {
#endif
#include "duck_bmp.h"
#include "duck_wav.h"
#include <string.h> /* for size_t */
typedef enum dukDirect { /* direction to move within stream */
DUK_BACKWARD=-1, /* move backward from current position */
DUK_ABSOLUTE=0, /* move to an absolute position */
DUK_FORWARD=1, /* move forward from current position */
DUK_RESET=2 /* reset stream according to file position */
} hfbDirection;
typedef enum HFB_FileType { /* type of file opened */
DUK_NULFILE = 0, /* not a TrueMotion "S" A/V file */
DUK_DUKFILE = 1, /* TrueMotion "S" duk file */
DUK_AVIFILE = -1, /* TrueMotion "S" Video for Windows AVI compatible file */
DUK_QTFILE = 3 /* TrueMotion "S" Quicktime MOV compatible file */
} hfbFileType;
typedef enum HFB_StreamType {/* stream types */
DUK_UNDEFINED = 0, /* indeterminate or uninitialized stream */
DUK_AUDSTREAM = 1, /* audio stream */
DUK_VIDSTREAM = 2, /* video stream */
DUK_TXTSTREAM = 3 /* text stream */
} hfbStreamType;
typedef enum HFB_Modes { /* HFB buffering modes */
HFBMODE_NORMAL = 0, /* normal play once mode */
HFBMODE_FORWARDLOOP = 1, /* forward looping mode (loop back to start) */
HFBMODE_REVERSE = 2, /* reverse play once mode (not yet implemented)*/
HFBMODE_REVERSELOOP = 4, /* reverse looping mode (not yet implemented)*/
HFBMODE_QUEUE = 8, /* file queue mode (not yet implemented)*/
HFBMODE_FLYINDEX = 16, /* HFB does not have to read the AVI index to play the movie */ /* FWG 6-23-99 */
HFBMODE_ASYNC = 32, /* HFB is in asnyc mode. Needed for first read and index stuff */ /* FWG 7-7-99 */
HFBMODE_ASYNC_FLYINDEX = 64, /* Asnyc & Fly-Index mode. */ /* FWG 7-7-99 */
HFBMODE_PSEUDO_ASYNC = 128 /* */
} hfbBufferMode;
typedef enum BUFFERSTATUS {
HFB_BUSY = 0,
HFB_COMPLETE
} hfbBufferStatus;
typedef enum PRELOADSPEC {
HFB_FULL = -2,
HFB_THREEQUARTERS = -1,
HFB_NONE = 0
} hfbPreloadSpec;
#define HFB_USE_DEFAULT 0L
#define HFB_RESET_COUNT -1L
#define HFB_IGNORE_COUNT -2L
#define HFB_DATA_READ 0x01
#define HFB_DATA_RELEASED 0x02
#define HFB_DATA_KEYFRAME 0x08
typedef struct tHFB_STREAM_INFO{
hfbStreamType streamType;
int streamNum;
int lSampleRate;
int lStart;
int lLength;
char szName[24];
union {
DKWAVEFORM WaveformInfo;
DKBITMAP BitmapInfo;
DKBITMAP_old depricatedBitmapInfo; /* please don't use this */
} a;
DK_BITMAPINFOHEADER bmih; /* should be part of union or replace DKBITMAP ... but due to healthy paranoia add here ... */
} HFB_STREAM_INFO, MFP_STREAM_INFO;
typedef struct tHFB_FILE_INFO{
int lFileSize;
int lNumStreams;
char sName[96];
int lNumFrames;
} HFB_FILE_INFO, MFP_FILE_INFO;
typedef struct tHFBFile *HFB_FILE_HANDLE;
typedef struct tHFBStream *HFB_STREAM_HANDLE;
typedef struct tHFBBuffer *HFB_BUFFER_HANDLE;
typedef int HFB_DATA_HANDLE;
#define DCK_DEFAULT_READSIZE 0
#define DCK_DEFAULT_BUFFSIZE 0
/* main HFB initialization and exit routines */
/*@
@Name HFB_Init
@Description Allocate and initialize required data structures.If all three parameters are -1,
HFB will dynamically allocate objects as needed.
@Return value 0 if success or negative return code.
@*/
libFunc int HFB_Init(
int maxOpenFiles, /* maximum of concurently open file objects. */
int maxOpenStreams, /* maximum of concurently open streams. */
int maxOpenBuffers /* maximum of concurently open buffer objects. */
);
/*@
@Name HFB_Exit
@Description free any allocated strcutures, close all files, etc.
@Return value none.
@*/
libFunc void HFB_Exit(void);
/*@
@Name HFB_SeekToIndex
@Description Seek to the index in the AVI file
@Return Value returns 0 on success.
@*/
libFunc int HFB_SeekToIndex(HFB_FILE_HANDLE FileHandle);
/*@
@!Name HFB_BeginLoadIndex
@Description
@Return value
@*/
libFunc int HFB_BeginLoadIndex(
HFB_BUFFER_HANDLE dckPtr, /* */
int size /* */
);
/*@
@!Name HFB_FinishLoadIndex
@Description
@Return value
@*/
libFunc int HFB_FinishLoadIndex(
HFB_BUFFER_HANDLE dckPtr, /* */
void *data, /* */
int size /* */
);
/*@
@!Name HFB_ParseBigIndex
@Description
@Return value
@*/
libFunc int HFB_ParseBigIndex(
HFB_BUFFER_HANDLE dckPtr,
void *data,
int size
);
/*@
@Name HFB_OpenFile
@Description open specified file, parse its header(s) and load the index
@Return value handle to HFB file object.
@*/
libFunc HFB_FILE_HANDLE HFB_OpenFile(
const char *fileName, /* file to be opened. */
HFB_BUFFER_HANDLE bufferHandle, /* handle to a pre-existing HFB buffer. */
unsigned int userData /* user data. */
);
/* the following three functions, findfile, parsefile and loadindex,
are encapsulated by openfile, they are provided as a convenience
for use on systems with asynchronous i/o */
#if 0 // Changed to a static funtion MEW 11-6-03
/*@
@Name HFB_FindFile
@Description This function implements a portion of the functionality performed by HFB_OpenFile.
@Return value Handle to a HFB file object.
@*/
libFunc HFB_FILE_HANDLE HFB_FindFile(
const char *fileName, /* name of file to open */
unsigned int userData /* user data */
);
#endif
/*@
@Name HFB_ParseFile
@Description After a file has been found, and at least a single sector is buffered, it's header can be
parsedfor the information necessary to describe what the file contains. The combination of loading functions must
appear in this order HFB_FindFile, HFB_ParseFile, HFBLoadIndex.
@Return value none.
@*/
libFunc int HFB_ParseFile(
HFB_FILE_HANDLE fileHandle, /* handle to an HFB file object. */
HFB_BUFFER_HANDLE bufferHandle /* handle to an HFB buffer object. */
);
/*@
@Name HFB_LoadIndex
@Description Load a TrueMotion file's index into the specified buffer object.
Must be used in this order ... HFB_FindFile, HFB_ParseFile, HFB_LoadIndex.
@Return value 0 if successful, -1 if error
@*/
libFunc int HFB_LoadIndex(
HFB_FILE_HANDLE fileHandle, /* handle to HFB file object. */
HFB_BUFFER_HANDLE bufferHandle /* handle to HFFB buffer object. */
);
/*@
@Name HFB_CloseFile
@Description Close a TrueMotion file (AVI) and release file structures.
@Return value None.
@*/
libFunc void HFB_CloseFile(
HFB_FILE_HANDLE fHnd /* handle to an HFB file object. */
);
/*@
@Name HFB_GetFileInfo
@Description Used to read information about an opened TrueMotion File (AVI).
@Return value a pointer to an HFB_FILE_INFO structure describing the indicated file.
@*/
libFunc HFB_FILE_INFO *HFB_GetFileInfo(
HFB_FILE_HANDLE fileHandle /* handle to an HFB file object. */
);
/*@
@Name HFB_CreateBuffer
@Description Create High-speed File Buffer.
@Return value Handle to an HFB Buffer object, or null if no buffer objects available.
@*/
libFunc HFB_BUFFER_HANDLE HFB_CreateBuffer(
int sizeOfBuffer, /* size in bytes of buffer to allocate. */
int reserved /* reserved - must bbe zero. */
);
/*@
@Name HFB_InitBuffer
@Description After creating a buffer and opening a file, an application mst initialize the buffer with data.
@Return value Zero if successful, non-zero if not successful.
@*/
libFunc int HFB_InitBuffer(
HFB_BUFFER_HANDLE bufferHandle, /* handle to HFB buffer object. */
HFB_FILE_HANDLE fileToLoad, /* handle to HFB file object */
int startFrame, /* frame at which to being playback , normally 0. */
int initialReadSize /* amount of buffer to preload with data (specified in bytes). -1 means 3/4 buffer. -2 fill entire buffer */
);
/*@
@Name HFB_FillBuffer
@Description read additional data from a file into space invalidated by HFB_ReleaseStreamingData calls
or any empty buffer space available. For best results call this function once per frame with the elapsedFrames set to DUCK_IGNORE_COUNT.
The function will use the elapsedFrame parameter in conjunction with internal computed values to determine the amount to read from the file
in order to avoid waiting for data to become availabble.
@Return value Number of bytes actually read from the disk file into the buffer or a negative error code.
@*/
libFunc int HFB_FillBuffer(
HFB_BUFFER_HANDLE bufferHandle, /* handle to a buffer objects */
int maxToRead, /* maximum number of bytes to read during this call */
int elapsedFrames /* number of frames elapsed since start of play */
);
/*@
@Name HFB_DestroyBuffer
@Description Free memory used by buffer and release buffer object.
@Return value none.
@*/
libFunc void HFB_DestroyBuffer(
HFB_BUFFER_HANDLE bufferHandle /* handle to an HFB buffer object */
);
/*@
@!Name HFB_ResetStreams
@Description
@Return value
@*/
libFunc void HFB_ResetStreams(
HFB_BUFFER_HANDLE bufferHandle /* */
);
/*@
@Name HFB_SetBufferMode
@Description Sets the mode for the specified bufffer. Buffer mode defaults to HFBMODE_NORMAL unless this function is called.
@Return value
@*/
libFunc int HFB_SetBufferMode(
HFB_BUFFER_HANDLE buffer, /* handle to HFB buffer object. */
hfbBufferMode mode /* mode. */
);
/*@
@!Name HFB_GetBufferPerCentFull
@Description
@Return value
@*/
libFunc int HFB_GetBufferPerCentFull(
HFB_BUFFER_HANDLE buffer /* */
);
/*@
@!Name HFB_GetmovieSize
@Description
@Return value
@*/
libFunc int HFB_GetmovieSize(
HFB_BUFFER_HANDLE buffer /* */
);
/*@
@!Name HFB_GetBufferSpace
@Description
@Return value
@*/
libFunc int HFB_GetBufferSpace(
HFB_BUFFER_HANDLE buffer /* */
);
/*@
@Name HFB_GetBufferStatus
@Description Use this to detemine if a buffer has reached an end of file.
@Return value 0 - buffer OK. 1 - Buffer reached end of file.
@*/
libFunc hfbBufferStatus HFB_GetBufferStatus(
HFB_BUFFER_HANDLE buffer /* handle to an HFB buffer object. */
);
/*@
@!Name HFB_ConditionBuffer
@Description
@Return value
@*/
libFunc int HFB_ConditionBuffer(
HFB_BUFFER_HANDLE bufferHandle, /* */
int bufferSize, /* */
int reserved /* */
);
#define HFB_ResetBuffer HFB_ConditionBuffer
/*@
@Name HFB_GetStream
@Description get a stream reference handle by name, number, or type.
@Return value handle to a stream object.
@*/
libFunc HFB_STREAM_HANDLE HFB_GetStream(
HFB_FILE_HANDLE fileHandle, /* handle to HFB file object. */
const char *StreamNameOrNull, /* C string containing the name of a stream within the specified file. Null to ignore. */
int streamNumber, /* an absolute stream number or the nth occuring stream of the specified file. */
unsigned int streamType /* the type of stream to be opened. */
);
/*@
@Name HFB_ReleaseStream
@Description relinquish reference to stream object so it may return to the pool.
@Return value none.
@*/
libFunc void HFB_ReleaseStream(
HFB_STREAM_HANDLE streamHandle /* handle to an HFB stream object. */
);
/*@
@Name HFB_GetStreamInfo
@Description get a pointer to stream info struct
@Return value pointer to a struct containing the stream info.
@*/
libFunc HFB_STREAM_INFO* HFB_GetStreamInfo(
HFB_STREAM_HANDLE streamHandle /* handle to an HFB stream object */
);
#define HFB_GetStreamLength(strmh) HFB_GetStreamInfo(strmh)->lLength
#define HFB_GetStreamName(strmh) HFB_GetStreamInfo(strmh)->szName
/*@
@Name HFB_GetStreamingData
@Description Get pointer to buffered record and length. Normally this will be balanced by a call to HFB_ReleaseStreamingData, unless
the entire file fits within the HFB buffer. The operation does not move compressed data.
@Return value >= 0 handle to compressed block; -1 request out of range ; -2 block exists but is not in the buffer ...
usually caused by unrleased block of buffer starvation ; -4 block has been release from use.
@*/
libFunc HFB_DATA_HANDLE HFB_GetStreamingData(
HFB_STREAM_HANDLE streamHandle, /* handle to an HFB stream object. */
void **ptrToPtr, /* pointer to pointer to compressed data. */
int *ptrToLength, /* pointer to length of data in bytes. */
hfbDirection directionToMove, /* direction in which to read records. */
int framesToMove /* the number of reqested records. */
);
/*@
@Name HFB_ReleaseStreamingData
@Description release buffer space occupied by record
@Return value none.
@*/
libFunc void HFB_ReleaseStreamingData(
HFB_BUFFER_HANDLE bufferHandle, /* handle to HFB buffer object. */
HFB_DATA_HANDLE recordToRelease /* index of data record to release. */
);
/*@
@Name HFB_ReadData
@Description read data directly from a file into a supplied buffer,
limit is set by initial value of *ptrToLength
@Return value 0 on success, or negative error code.
@*/
libFunc int HFB_ReadData(
HFB_STREAM_HANDLE streamHandle, /* handle to HFB stream object. */
void *data, /* pointer to where data should be copied. Used by duck_read. */
int *maxLength, /* pointer to max data size, will be over-written with actual count of bytes read. */
hfbDirection directionToMove, /* direction in which the seek should move. */
int count /* the number of datarecords to move before reading. Absolute referencse begin at 0. */
);
libFunc int HFB_ReadDataBlocking(
HFB_STREAM_HANDLE streamHandle, /* handle to HFB stream object. */
void *data, /* pointer to where data should be copied. Used by duck_read. */
int *maxLength, /* pointer to max data size, will be over-written with actual count of bytes read. */
hfbDirection directionToMove, /* direction in which the seek should move. */
int count /* the number of datarecords to move before reading. Absolute referencse begin at 0. */
);
/*@
@!Name HFB_FramestoNextKeyFrame
@Description
@Return value
@*/
libFunc int HFB_FramestoNextKeyFrame(
HFB_STREAM_HANDLE streamHandle, /* */
int recordHandle, /* */
int *numberOfRecordsSpanned /* */
);
/*@
@!Name HFB_FrameToChunk
@Description
@Return value
@*/
libFunc int HFB_FrameToChunk(
HFB_STREAM_HANDLE streamHandle, /* */
int frameNumber /* */
);
/*@
@Name HFB_PreviousKeyFrame
@Description Get the frameNumber of the keyframe at or prior to the specified frameNumber
@Return value
@*/
libFunc int HFB_PreviousKeyFrame(
HFB_STREAM_HANDLE streamHandle, /* */
int frameNumber /* */
);
typedef enum FTYPE {
HFB_FRAMENUM = 0,
HFB_INDEXNUM = 1
} hfbFrameNumber;
/*@
@Name HFB_GetIndexFlags
@Description get the HFB index flags for the specified record/frame
@Return value >= 0 data block flags for data block specifid; -1 frameNum is out of index range ; -2 frameNum is out of frame range.
@*/
libFunc int HFB_GetIndexFlags(
HFB_STREAM_HANDLE , /* handle to HFB stream object. */
hfbFrameNumber frameNumberType, /* one of HFB_FRAMENUM, HFB_INDEXNUM */
int recordHandleOrFrameNumber /* record handle or frame number. */
);
/*@
@Name HFB_AddIndexFlags
@Description add the HFB index flags for the specified record/frame
@Return value 0 if unsuccessful; 1 if successful;
@*/
libFunc int HFB_AddIndexFlags(
HFB_STREAM_HANDLE , /* handle to HFB stream object. */
hfbFrameNumber frameNumberType, /* one of HFB_FRAMENUM, HFB_INDEXNUM */
int recordHandleOrFrameNumber, /* record handle or frame number. */
int flags /* flags to add */
);
/*@
@Name HFB_GetDataPosition
@Description get current data position. video - frameNumber, audio - sampleCount.
This is useful for resolving differences between streams when starting from a position other than the beginning of the file.
@Return value Longword starting position of the data record within the stream, expressed in audio samples for audio streams and frames for video streams.
@*/
libFunc int HFB_GetDataPosition(
HFB_STREAM_HANDLE streamHandle, /* handle to HFB stream object. */
HFB_DATA_HANDLE dataIndex /* index to a data record within a stream. Use -1 to find position of first available record in the buffered stream */
);
/*@
@Name HFB_GetAudioInfo
@Description Get information about audio stream.
@Return value pointer to a DKWAVEFORM structure describing the audio information contained in the stream.
@*/
libFunc DKWAVEFORM *HFB_GetAudioInfo(
HFB_STREAM_HANDLE aStream, /* handle to HFB stream object */
int *NumChannels, /* pointer to number of channels in the audio stream. */
int *SamplesPerSec, /* pointer to samples per second in the audio stream. */
int *BytesPerSec, /* pointer to bytes per second in the audio stream. */
int *wFormat /* pointer to the format tag value for the audio stream. */
);
/*@
@!Name HFB_GetInitialFrames
@Description /* get the amount of audio skew expressed in records
@Return value
@*/
libFunc int HFB_GetInitialFrames(
HFB_STREAM_HANDLE videoStream, /* handle to video stream */
HFB_STREAM_HANDLE audioStream /* handle to audio stream */
);
/*@
@Name HFB_GetSamplesPerFrame
@Description get the number of audio frames elapsed during a single video frame
@Return value The number of audio samples from the audio stream occurring within a single frame interval of video.
@*/
libFunc int HFB_GetSamplesPerFrame(
HFB_STREAM_HANDLE videoStream, /* handle to an HFB video stream */
HFB_STREAM_HANDLE audioStream /* handle to an HFB audio stream */
);
/*@
@Name HFB_GetFrameRates
@Description get video frame rate and calculated audio skew (in audio samples)
@Return value
@*/
libFunc void HFB_GetFrameRates(
HFB_STREAM_HANDLE videoStream, /* handle to an HFB video stream */
HFB_STREAM_HANDLE audioStream, /* handle to an HFB audio stream */
int *ptrToIntegerFrameRate, /* pointer to receive frame rate of dominant stream. */
int *ptrToEstimatedAudioSampleSkew /* pointer to number of audio samples appearing before the first video frame in file. */
);
/*@
@Name HFB_GetDRMData
@Description get the DRMX data chunk
@Return value
@*/
libFunc int HFB_GetDRMData(
HFB_FILE_HANDLE dckPtr, /* */
unsigned int* pOutEncFourCC, /* */
int* pOutLength, /* */
unsigned char** ppOutData /* */
);
/*@
@!Name HFB_GetStreamParentBuffer
@Description functions to retrieve parent buffer and file of a given stream
@Return value
@*/
libFunc HFB_BUFFER_HANDLE HFB_GetStreamParentBuffer(
HFB_STREAM_HANDLE streamHandle /* */
);
/*@
@!Name HFB_GetStreamParentFile
@Description
@Return value
@*/
libFunc HFB_FILE_HANDLE HFB_GetStreamParentFile(
HFB_STREAM_HANDLE streamHandle /* */
);
/*@
@!Name HFB_GetStreamParentFileHandle
@Description function to retrieve parent file handle of a given stream
@Return value
@*/
libFunc int HFB_GetStreamParentFileHandle(
HFB_STREAM_HANDLE streamhandle /* */
); /* FWG 6-23-99 */
/*@
@Name HFB_SetMaxFrameSize
@Description Tell HFB maximum frame size in bytes.
****** DO NOT GIVE WRONG NUMBER****** This might cause
HFB to crash. Only used in Fly-Index mode.
@Return Value T.B.D.
@*/
libFunc int HFB_SetMaxFrameSize(
HFB_BUFFER_HANDLE Buffer, /* handle to an HFB Buffer */
int maxFrameSize /* maximum frame size */
); /* FWG 7-7-99 */
libFunc hfbBufferMode HFB_GetBufferMode(HFB_BUFFER_HANDLE); /* FWG 7-8-99 */
/* used to precisely calculate rational frame rates
for a specific stream */
libFunc void HFB_GetStreamRateAndScale(
HFB_STREAM_HANDLE xStream, /* stream handle */
int *rate, /* rate - of rate and scale. */
int *scale /* scale - of rate and scale. */
);
/*@
@Name HFB_GetStreamFCCs
@Description get stream type and handler fourCC codes,
@Return Value returns type (not handler)
@*/
libFunc unsigned int HFB_GetStreamFCCs(
HFB_STREAM_HANDLE xStream, /* handle to compressed stream */
unsigned int *type, /* pointer to stream type */
unsigned int *handler /* pointer to fourCC code */
);
/*@
@Name HFB_NextKeyFrame
@Description returns the index of the next keyframe, looking forward from StartChunk.
byteRate is the projected byterate up to that keyframe.
@Return Value returns the index of the next keyframe
@*/
int HFB_NextKeyFrame(
HFB_STREAM_HANDLE sPtr, /* stream handle */
int StartChunk, /* look forward from here. */
int *byteRate /* */
);
/*
@Name HFB_isVideoKeyFrame
@Description checks if a video frame is a key frame (in logarithmic time)
@Return Value returns 1 if key frame, 0 if not, -1 on error
@Note: only works for the first video stream*/
int HFB_isVideoKeyFrame(
HFB_BUFFER_HANDLE dckPtr, /* buffer handle */
int frameNum /* video frame to check */
);
int HFB_ProjectBitRate(HFB_STREAM_HANDLE sPtr, int StartChunk, int *numFrames );
// returns the byterate for the next *numFrames , given a starting chunkIndex
// numFrames is a pointer since the actual amount looked ahead may be adjusted
// as you get to the end of the stream
/* Determine the stream to which we can switch that has the highest precedence */
/* (defined by order in the array), but is below the ceiling specified by the caller */
/* Note: We can only switch to another stream if its next frame is a keyframe. */
/* Note: If no streams are below the ceiling, we will attempt to switch to the */
/* lowest bitrate stream on a keyframe. */
int HFB_SelectBestFitStream(
HFB_STREAM_HANDLE* streamArray, // array of streams to consider
int numberOfStreamsInArray, // number of streams in the array
int currentStream, // array index matching currently used stream
int desiredProjectionSpan, // distance in frames ahead to project
int bitRateCeiling); // we're looking for a stream under this bitrate
/* get streamSampleSize, <= 0 means variable */
libFunc int HFB_GetStreamSampleSize(HFB_STREAM_HANDLE xStream);
/*@
@!Name HFB_WhatsAhead
@Description
@Return value
@*/
libFunc int HFB_WhatsAhead(
HFB_STREAM_HANDLE sPtr, /* */
int StartChunk, /* */
int *horizon /* */
);
/* windows 95 dll system abstraction functions */
libFunc void HFB_Setmalloc(
void *(*mallocFuncPtr)(unsigned int size)
);
libFunc void HFB_Setcalloc(
void *(*callocFuncPtr)(unsigned int size, unsigned int number)
);
libFunc void HFB_Setfree(
void (*freeFuncPtr)(void *)
);
libFunc void HFB_Setopen(
int (*openFuncPtr)(const char *, int,...)
);
libFunc void HFB_Setclose(
int (*closeFuncPtr)(int)
);
libFunc void HFB_Setread(
int (*readFuncPtr)(int,void *, unsigned int)
);
libFunc void HFB_Setseek(
int (*seekFuncPtr)(int,int,int)
);
/*@
@Name HFB_GetStreamArray
@Description HFB_GetStreamArray
will return an array of all streams in a file
that are of the given type. If the given type is DUK_UNDEFINED,
all streams will be included in the array, regardless of type.
This function will also report back the size of the array (ie: the number
of matching streams) through the numberOfStreams pointer.
@Return value The array of stream handles
@*/
HFB_STREAM_HANDLE* HFB_GetStreamArray(
HFB_FILE_HANDLE FileHandle, /* the file we will be looking in for our streams */
unsigned int StreamType, /* the type of stream we are looking for */
unsigned int* numberOfStreams /* a pointer to the number of matching streams */
);
/*@
@Name HFB_ReleaseStreamArray
@Description HFB_ReleaseStreamArray will deallocate an array of streams which
was previously allocated by a call to HFB_GetStreamArray().
@Return Value
@*/
void HFB_ReleaseStreamArray(
HFB_STREAM_HANDLE* StreamArray, /* the array of streams we want to release */
unsigned int numberOfStreams /* number of streams in the array */
);
/*@
@Name HFB_GetLastError
@Description HFB_GetLastError will return the last error that occured
@Return Value 0 if successful, -1 if unsuccessful
@*/
int HFB_GetLastError(
HFB_BUFFER_HANDLE bfHnd, /* pointer to the buffer handle */
int* lastErrorCode, /* will return negative value for HFB error,
positive value for SAL error */
char errorString[], /* will return error string */
size_t maxLen /* max size of error string */
);
typedef enum HFB_ERR_t {
HFB_ERR_MIN = -7,
HFB_ERROR_LOADING_INDEX = -6,
HFB_ERROR_PARSING_FILE = -5,
HFB_PARTIALREAD = -4,
HFB_ENDOFSTREAM = -3,
HFB_NOTREADY = -2,
HFB_ERROR = -1,
HFB_OK = 0
} HFB_ERR;
typedef struct HFB_ERR_DECODE_temp
{
HFB_ERR code;
char* decode;
} HFB_ERR_DECODE_t;
#if defined(__cplusplus)
}
#endif
#undef libFunc
#endif

View file

@ -0,0 +1,340 @@
#if !defined(_duck_ifstream_h)
#define _duck_ifstream_h
#include "duck_io.h"
#include <stdio.h>
#include <sstream>
#include <ios>
#include <assert.h>
#include "iduck_ifstream.hpp"
class duck_ifstream_ifstream : duck_ifstream
{
public:
bool operator!() const
{
return (m_fd == 0);
}
bool is_open()
{
return (m_fd != 0);
}
int length()
{
if (m_length < 0)
{
FILE* fp = (FILE* ) m_fd;
long off = ftell(fp);
fseek(fp, 0,SEEK_END);
long off2 = ftell(fp);
fseek(fp, off, SEEK_SET);
m_length = (int ) off2;
return (int) off2;
}
else
{
return m_length;
}
}
void time_out(unsigned long milli)
{
;
}
bool eof()
{
return feof(m_fd);
}
operator bool () const
{
return (m_fd != 0);
}
void open(const char* filename, std::ios_base::openmode mode)
{
m_length = -1;
m_fd = fopen(filename, "rb");
}
void open(void *src, void* ignore)
{
assert(0);
}
void close()
{
if (m_fd)
{
fclose(m_fd);
}
}
void read(void *buffer, size_t len)
{
fread((unsigned char* ) buffer, sizeof(char), len, m_fd);
}
void get(char& c)
{
fread((unsigned char* ) &c, sizeof(char), 1, m_fd);
}
void seekg(long position)
{
fseek(m_fd, position, SEEK_SET);
}
void seekg(long offset, int origin)
{
switch (origin)
{
case std::ios_base::cur :
fseek(m_fd, offset , SEEK_CUR);
break;
case std::ios_base::end :
fseek(m_fd, offset, SEEK_END);
break;
case std::ios_base::beg :
fseek(m_fd, offset, SEEK_SET);
break;
default :
assert(0);
break;
}
}
void ignore(long offset)
{
fseek(m_fd, offset, SEEK_CUR);
}
long tellg()
{
const std::streamoff off = ftell(m_fd);
return std::streampos(off);
}
private:
FILE* m_fd;
int m_length;
};
extern "C" {
void MessageBox(char* title, char* msg);
}
#include "duck_io.h"
class duck_ifstream_http : duck_ifstream
{
public:
bool operator!() const
{
return (m_fd <= 0);
}
bool is_open()
{
return (m_fd > 0);
}
~duck_ifstream_http()
{
duck_exit_http(m_fd);
}
operator bool () const
{
return (m_fd >= 0);
}
int length()
{
return duck_length((int ) m_fd);
}
void time_out(unsigned long milli)
{
duck_http_timeout(m_fd, milli);
}
bool eof()
{
return duck_eof(m_fd);
}
void open(const char* url, std::ios_base::openmode mode)
{
m_fd = (int) duck_init_http(url);
if (duck_open((char *) m_fd, 0) < 0)
{
if (m_fd)
{
duck_close((int ) m_fd);
m_fd = -1;
}
}
}
void open(void *src, void* ignore)
{
assert(0);
}
void close()
{
if (m_fd >= 0)
{
duck_close(m_fd);
}
}
void read(void *buffer, size_t len)
{
size_t x;
x = duck_read(m_fd, (unsigned char* ) buffer, (long ) len);
if (x != len)
{
MessageBox("Error", "NSV Read Failed");
}
}
void get(char& c)
{
duck_read(m_fd, (unsigned char *) &c, 1);
}
void seekg(long position)
{
long o = position - duck_tell(m_fd);
if (o >= 0)
{
duck_seek(m_fd, o, SEEK_CUR);
}
else
{
duck_close(m_fd);
duck_open((char *) m_fd, 0);
duck_seek(m_fd, position, SEEK_CUR);
}
}
void seekg(long offset, int origin)
{
switch (origin)
{
case std::ios_base::cur :
duck_seek(m_fd, offset, SEEK_CUR);
break;
default :
/* don't do it ! */
/* assert(0); */
break;
}
}
void ignore(long offset)
{
duck_seek(m_fd, offset, SEEK_CUR);
}
long tellg()
{
long off = duck_tell(m_fd);
return off;
}
private:
int m_fd;
#if 0
/* disable copying ! */
duck_ifstream_http(const duck_ifstream_http& );
/* disable copying ! */
operator= (const duck_ifstream_http& );
#endif
};
#endif

View file

@ -0,0 +1,26 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _duck_int_h
#define _duck_int_h
#if defined(__cplusplus)
extern "C" {
#endif
int *duck_int386x(int intVal, void *r1, void *r2, void *sr);
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,109 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _duck_io_h
#define _duck_io_h
#if defined(__cplusplus)
extern "C" {
#endif
#if defined (_WIN32)
typedef __int64 int64_t;
#endif
typedef struct
{
int64_t offset; // offset to start from
int blocking; // non-zero for blocking
} ReOpen_t;
typedef enum {
SAL_ERR_MAX = -10,
SAL_ERROR = -11, // Default error
SAL_ERR_WSASTARTUP = -12,
SAL_ERR_SOCKET_CREATE = -13,
SAL_ERR_RESOLVING_HOSTNAME = -14,
SAL_ERR_SERVER_CONNECTION = -15,
SAL_ERR_SENDING_DATA = -16,
SAL_ERR_RECEIVING_DATA = -17,
SAL_ERR_404_FILE_NOT_FOUND = -18,
SAL_ERR_PARSING_HTTP_HEADER = -19,
SAL_ERR_PARSING_CONTENT_LEN = -20,
SAL_ERR_CONNECTION_TIMEOUT = -21,
SAL_ERR_FILE_OPEN_FAILED = -22,
SAL_ERR_MIN = -23
} SAL_ERR; /* EMH 1-15-03 */
typedef struct SalErrMap_temp
{
SAL_ERR code;
const char* decode;
} SalErrMap_t;
static char* SalErrText(SAL_ERR e)
{
int t;
const SalErrMap_t gSalErrMap[] =
{
{ SAL_ERR_WSASTARTUP, "Error with WSAStartup" },
{ SAL_ERR_SOCKET_CREATE, "Error creating socket" },
{ SAL_ERR_RESOLVING_HOSTNAME, "Error resolving hostname" },
{ SAL_ERR_SERVER_CONNECTION, "Error connecting to server" },
{ SAL_ERR_SENDING_DATA, "Error sending data" },
{ SAL_ERR_RECEIVING_DATA, "Error receiving data" },
{ SAL_ERR_404_FILE_NOT_FOUND, "Error file not found " },
{ SAL_ERR_PARSING_HTTP_HEADER, "Error parsing http header" },
{ SAL_ERR_PARSING_CONTENT_LEN, "Error parsing content length" },
{ SAL_ERR_CONNECTION_TIMEOUT, "Error Connection timed out" },
{ SAL_ERR_FILE_OPEN_FAILED, "Error opening file" }
};
for(t = 0; t < sizeof(gSalErrMap)/sizeof(SalErrMap_t); t++)
{
if (e == gSalErrMap[t].code)
return (char *) gSalErrMap[t].decode;
}
return 0;
}
int duck_open(const char *fname, unsigned long userData);
void duck_close(int ghndl);
int duck_read(int ghndl,unsigned char *buf, int nbytes);
int64_t duck_seek(int gHndl,int64_t offs, int origin);
int duck_readFinished(int han, int flag); /* FWG 7-9-99 */
int duck_name(int handle, char name[], size_t maxLen); /* EMH 9-23-03 */
int duck_read_blocking(int handle,unsigned char *buffer,int bytes); /* EMH 9-23-03 */
int64_t duck_available_data(int handle); /* EMH 10-23-03 */
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,44 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _duck_io_h_old
#define _duck_io_h_old
#if defined(__cplusplus)
extern "C" {
#endif
#if defined (_WIN32)
typedef __int64 int64_t;
#else
typedef long long int64_t;
#endif
#include "duck_io.h"
int duck_open_file(const char *fname, unsigned long userData);
void duck_close_file(int ghndl);
int duck_read_file(int ghndl,unsigned char *buf, int nbytes);
int64_t duck_seek_file(int gHndl,int64_t offs, int origin);
int duck_name_file(int handle, char fname[], size_t maxLen); /* EMH 9-23-03 */
int64_t duck_available_data_file(int handle); /* EMH 10-23-03 */
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,62 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _duck_io_h_http
#define _duck_io_h_http
#include <string.h> /* get size_t */
#include "duck_io.h"
#if defined(__cplusplus)
extern "C" {
#endif
#if defined (_WIN32)
typedef __int64 int64_t;
#else
typedef long long int64_t;
#endif
int duck_open_http(const char *fname, unsigned long userData);
void duck_close_http(int ghndl);
int duck_read_http(int ghndl,unsigned char *buf, int nbytes);
int64_t duck_seek_http(int gHndl,int64_t offs, int origin);
int duck_sal_error_http(void* handle, SAL_ERR* lastErrorCode, char buffer[], size_t maxLen); /* EMH 1-15-03 */
char* duck_init_http(char* url); /* EMH 1-17-03 */
void duck_exit_http(int handle); /* EMH 6-09-03 */
int duck_sal_fill(void * handle, bool blocking); /* EMH 6-12-03 */
void duck_http_timeout(int handle, unsigned long milliseconds);
int duck_sal_buff_percent(void* handle); /* debug */
int64_t duck_available_data_http(int handle); /* EMH 10-23-03 */
int64_t duck_content_len(void *handle);
int duck_name_http(int handle, char url[], size_t maxLen); /* EMH 9-23-03 */
int duck_read_blocking_http(int handle,unsigned char *buffer, int bytes); /* EMH 9-23-03 */
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,18 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _duck_mem_h
#define _duck_mem_h
#include "../on2_common/src/on2_mem/include/on2_mem.h"
#endif

View file

@ -0,0 +1,29 @@
#ifndef _duck_wav_h
#define _duck_wav_h
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct tDKWAVEFORM
{
unsigned short wFormatTag; /* format type */
unsigned short nChannels; /* number of channels (i.e. mono, stereo...) */
unsigned int nSamplesPerSec; /* sample rate */
unsigned int nAvgBytesPerSec; /* for buffer estimation */
unsigned short nBlockAlign; /* block size of data */
unsigned short wBitsPerSample; /* Number of bits per sample of mono data */
unsigned short cbSize; /* The count in bytes of the size of
extra information (after cbSize) */
unsigned short wSamplesPerBlock;
unsigned int userData[16];
} DKWAVEFORM;
/* don't try to endian fix the userData ! */
static int DKWAVEFORM_REFLECT[ ] = { 2,2, 4,4, 2,2,2,2 };
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,25 @@
#ifndef _duktypes_h
#define _duktypes_h
#if defined(__cplusplus)
extern "C" {
#endif
typedef unsigned char U8;
typedef unsigned short U16;
typedef unsigned long U32;
typedef signed char I8;
typedef short I16;
typedef long I32;
/*
//typedef int Boolean;
*/
#if 1 /* def _MSC_VER */
typedef unsigned char uchar;
/*typedef unsigned short ushort;*/
typedef unsigned long ulong;
#endif
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,38 @@
#ifndef _dxl_aud_h
#define _dxl_aud_h
#include "duck_hfb.h"
#include "duck_dxl.h"
enum spkrst8 { SPEAKEROFF = 0, SPEAKERON = 1, FEEDSPEAKER = 2, MONOSPEAKER = 3};
enum syncst8 { NOSYNC = 0, SYNCSPEAKER = 1, SYNCSYSTEM = 2};
extern enum spkrst8 speakerstate;
extern enum syncst8 syncstate;
void Announcement(char *msg);
extern "C" {
int FillAudio( HFB_BUFFER_HANDLE hfb, MFP_STREAM_HANDLE as, int *index,
void **blk, long *Len, int buffPreload, int MultiBlock);
int SetupAudio( HFB_BUFFER_HANDLE hfb, MFP_STREAM_HANDLE as, int Setstate,
int freq, int width16, int Stereo);
void StartPlaying(void) ;
void StopPlaying(void);
void ResyncAudio(
HFB_BUFFER_HANDLE hfb,
HFB_STREAM_HANDLE astr,
int *index, void **blk, long *Len, int frame, int frame_rate);
}
#endif

View file

@ -0,0 +1,307 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef _dxl_main_h
#define _dxl_main_h
#if defined(__cplusplus)
extern "C" {
#endif
struct vScreen;
struct tXImage;
struct tAudioBuff;
struct tXAudioSource;
#if defined(__cplusplus)
}
#endif
#if defined(_WIN32_WCE)
#ifndef NULL
#define NULL 0
#endif
#endif
#include "dkpltfrm.h"
//#include "duktypes.h"
#include "duck_dxl.h"
#if defined(__cplusplus)
extern "C" {
#endif
#define TMRTType 5
#define validate(x) {if (!x) return (int ) DXL_NULLSOURCE; if (!x->dkFlags.inUse) return (int ) DXL_NOTINUSE ;}
typedef void *blitFunc;
/*typedef void (*blitFunc2)(DXL_XIMAGE_HANDLE,DXL_VSCREEN_HANDLE); */
typedef int DXL_BLIT_FORMAT;
enum DKOBJECTTYPE {
DXUNUSED = 0,
DXXIMAGE = 1,
DXVSCREEN = 2
};
enum COLORDEPTH {
PALETTE8 = 0,
RGB555 = 1,
RGB555A = 2,
RGB888 = 3,
RGBA8888 = 4
};
typedef struct tagflgs {
unsigned inUse : 1;
unsigned DXed : 1;
unsigned clutOwner: 1;
unsigned doCompleteBlit : 1;
unsigned keyFrame : 1;
unsigned nullFrame : 1;
unsigned interframe : 1;
unsigned logo : 1;
unsigned allocated : 1;
} dkInfoFlags;
typedef struct vflgs {
unsigned clipped : 1;
unsigned showInfoDots : 1;
} vFlags;
typedef struct frameheader {
unsigned char hdrSize;
unsigned char Type;
unsigned char DeltaSet;
unsigned char Table;
unsigned short Ysize;
unsigned short Xsize;
unsigned short CheckSum;
unsigned char CVersion;
unsigned char metaType;
unsigned char Frameinfo;
unsigned char Control;
unsigned short xoff,yoff,width,height;
} FRAMEHEADER;
typedef struct DXINFOSTRUCT{
int imwidth;
int imheight;
int blockpower;
int lpbmione;
int block2x;
unsigned char *vectbl;
int hinterp;
int interframe;
int iskeyframe;
int sprite;
int bitcnt;
int hdrSize;
int drawing;
int fmt;
FRAMEHEADER f;
int algorithm;
} dxInfoStruct;
/*
base "class" for xImage(s):
enum DKOBJECTTYPE dkObjectType; // type of object
dkInfoFlags dkFlags; // universal flags
enum COLORDEPTH cDepth; // colorDepth
short imWidth,imHeight; // internal width & height
short x,y,w,h; // location and dx'd dimensions
unsigned char *addr; // pointer to compressed data
DXL_VSCREEN_HANDLE lVScreen; // last know destination
DXL_XIMAGE_HANDLE (*create)(void); // creator (constructor)
DXL_XIMAGE_HANDLE (*recreate)(void); // recreate base w/h/type/etc.
int (*destroy)(void); // destroyer (destructor)
int (*seedData)(void); // reseed with new compressed data
int (*dx)(void); // decompress (to vScreen)
int (*blit)(void); // blit from internal state
*/
/*
char *(*perfStats)(DXL_XIMAGE_HANDLE, char *storage); \
*/
typedef struct profilePack_t
{
UINT64 dxClocks;
UINT64 profileStart;
UINT64 profileEnd;
int frameCount;
} DXL_PROFILEPACK;
#define xImageBaseStruct \
enum DKOBJECTTYPE dkObjectType; \
dkInfoFlags dkFlags; \
enum COLORDEPTH colorDepth; \
short imWidth,imHeight; \
short x,y,w,h; \
unsigned char *addr; \
DXL_VSCREEN_HANDLE lVScreen; \
enum BITDEPTH *bdPrefs; \
DXL_XIMAGE_HANDLE (*create)(void *); \
DXL_XIMAGE_HANDLE (*recreate)(DXL_XIMAGE_HANDLE,void *,int,int,int,int); \
int (*destroy)(DXL_XIMAGE_HANDLE); \
int (*seedData)(DXL_XIMAGE_HANDLE); \
int (*dx)(DXL_XIMAGE_HANDLE, DXL_VSCREEN_HANDLE); \
int (*blit)(DXL_XIMAGE_HANDLE, DXL_VSCREEN_HANDLE); \
int (*internalFormat)(DXL_XIMAGE_HANDLE, DXL_VSCREEN_HANDLE); \
int (*verify)(DXL_XIMAGE_HANDLE, DXL_VSCREEN_HANDLE); \
int fSize; \
long (*GetXImageCSize)(DXL_XIMAGE_HANDLE); \
void *(*getFrameBuffer)(DXL_XIMAGE_HANDLE); \
void (*setParameter)(DXL_XIMAGE_HANDLE, int , unsigned long );\
DXL_PROFILEPACK prof
typedef struct tXImage{
xImageBaseStruct;
} DXL_XIMAGE;
typedef struct tXImage1{
xImageBaseStruct;
/********** TM1 specific follows **********/
enum IMAGETYPE imType;
unsigned char *lineBuffer;
int lineBufferSize;
unsigned long *chromaBuffer;
int chromaBufferSize;
short dxCount; /* number of lines left to decompress */
short lw,lh;
enum BGMODE sprMode;
short sprColor; /* sprite mode and color for blending */
dxInfoStruct dxInfo;
} DXL_XIMAGE_1,*DXL_XIMAGE_1HANDLE;
typedef struct vScreen{
enum DKOBJECTTYPE dkObjectType;
unsigned char *addr,*laddr; /* address of destination and what it was the last time */
unsigned char *bAddr,*bOffsetAddr; /* address of sprite background */
enum BITDEPTH bd; /* format of destination */
enum BLITQUALITY bq; /* blit translation mode */
short pitch,height; /* pitch and height of dest */
short bx,by,bPitch; /* x,y, and pitch of background */
short viewX,viewY; /* offset/clipping viewport within destination */
short viewW,viewH;
short clipX,clipY; /* clipping rectangle within viewport */
short clipW,clipH;
dkInfoFlags dkFlags;
DXL_XIMAGE_HANDLE lXImage; /* last XImage decompressed here, useful for smart blitting */
unsigned char *clut1,*clut2;
DXL_BLIT_FORMAT blitFormat;
void *blitSetup;
void *blitter;
void *blitExit;
int vesaMode;
unsigned char *drawAddr;
short drawW,drawH;
vFlags flags;
} DXL_VSCREEN;
/* private functions */
int decodeHeader(void *data,register dxInfoStruct *dxInfo);
#define MAX_CDEPTHS DXMAX
#define MAX_BQUALITIES DXBLITMAX
typedef enum tDXL_INTERNAL_FORMAT {
DXL_NULL_IFORMAT = -1,
DXL_LINE16 = 0,
DXL_LINE16i = 1,
DXL_LINE16hi = 2,
DXL_LINE16spr = 3,
DXL_LINE8 = 4,
TM2_BLOCK24 = 5,
TM1_24 = 6,
TORQ_YUY2 = 7,
TORQ_YUY2hi = 8,
YV12 = 9,
SWET_YUV = 10,
DXL_MAX_IFORMATS
} DXL_INTERNAL_FORMAT;
DXL_BLIT_FORMAT DXL_ReserveBlitter(void);
DXL_BLIT_FORMAT DXL_OverrideBlitter(enum BLITQUALITY bq,enum BITDEPTH bd);
int DXL_RegisterBlitter(DXL_BLIT_FORMAT dFormat, DXL_INTERNAL_FORMAT ,
blitFunc blit, blitFunc setup, blitFunc exit);
blitFunc DXL_GetBlitFunc(DXL_XIMAGE_HANDLE ,DXL_VSCREEN_HANDLE );
blitFunc DXL_GetBlitSetupFunc(DXL_XIMAGE_HANDLE ,DXL_VSCREEN_HANDLE );
blitFunc DXL_GetBlitExitFunc(DXL_XIMAGE_HANDLE ,DXL_VSCREEN_HANDLE );
blitFunc DXL_GetVBlitFunc(DXL_VSCREEN_HANDLE ,DXL_VSCREEN_HANDLE );
blitFunc DXL_GetVBlitSetupFunc(DXL_VSCREEN_HANDLE ,DXL_VSCREEN_HANDLE );
blitFunc DXL_GetVBlitExitFunc(DXL_VSCREEN_HANDLE ,DXL_VSCREEN_HANDLE );
DXL_BLIT_FORMAT DXL_GetVScreenBlitFormat(DXL_VSCREEN_HANDLE );
DXL_INTERNAL_FORMAT DXL_GetXImageInternalFormat(DXL_XIMAGE_HANDLE ,DXL_VSCREEN_HANDLE );
DXL_INTERNAL_FORMAT DXL_GetVScreenInternalFormat(DXL_VSCREEN_HANDLE vScreen);
int dxl_GetAlgHandle(unsigned long fourcc);
int dxl_RegisterInternalFormat(int xHandle, DXL_INTERNAL_FORMAT xFormat);
int DXL_VScreenInfoDots(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE dst);
int DXL_GetVScreenSizeOfPixel(DXL_VSCREEN_HANDLE );
unsigned char *DXL_GetDestAddress(DXL_XIMAGE_HANDLE src, DXL_VSCREEN_HANDLE dst);
int DXL_GetXImageOffset(DXL_XIMAGE_HANDLE,int *,int *);
typedef DXL_XIMAGE_HANDLE (*createFunc)(unsigned char *data);
int DXL_RegisterXImage(createFunc creator,unsigned long fourcc,DXL_INTERNAL_FORMAT iForm);
void registerDuckBlitters(void);
void resetBlitters(void);
void dxv_logo( unsigned char *dst, int width, int height, int pitch,
enum BITDEPTH format, int dci, enum BLITQUALITY bq);
void dxl_24c(void *compaddr, void *scrnaddr,
int dstPitch,int iskeyframe,
int hinterp,int doublesize,
int scrnwidth,int scrnheight,
int blockpower, int block2x,
int forceheight, char *lastdecomp,
char *lastcdecomp);
#define DXL_MKFOURCC( ch0, ch1, ch2, ch3 ) \
( (unsigned long)(unsigned char)(ch0) | ( (unsigned long)(unsigned char)(ch1) << 8 ) | \
( (unsigned long)(unsigned char)(ch2) << 16 ) | ( (unsigned long)(unsigned char)(ch3) << 24 ) )
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,25 @@
#ifndef _littlend_h
#define _littlend_h
#if defined(__cplusplus)
extern "C" {
#endif
#define invert2(x) (x)
#define invert4(x) (x)
#define lowByte(x) (unsigned char)x
#define mid1Byte(x) (unsigned char)(x >> 8)
#define mid2Byte(x) (unsigned char)(x >> 16)
#define highByte(x) (unsigned char)(x >> 24)
#define SWAPENDS 0
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,19 @@
//==========================================================================
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
//
//--------------------------------------------------------------------------
#ifndef MISCASM_H
#define MISCASM_H
void CC_RGB32toYV12_MMXLU( unsigned char *RGBABuffer, int ImageWidth, int ImageHeight,
unsigned char *YBuffer, unsigned char *UBuffer, unsigned char *VBuffer );
#endif MISCASM_H

View file

@ -0,0 +1,340 @@
#ifndef _nethfb_h
#define _nethfb_h
#include "duck_hfb.h"
#ifndef NETHFB
#define lHFB_GetDataSize HFB_GetDataSize
#define lHFB_GetStreamingData HFB_GetStreamingData
#define lHFB_ReleaseStreamingData HFB_ReleaseStreamingData
#define lHFB_ReadData HFB_ReadData
#define lHFB_WhatsAhead HFB_WhatsAhead
#define lHFB_GetAudioInfo HFB_GetAudioInfo
#define lHFB_GetInitialFrames HFB_GetInitialFrames
#define lHFB_GetSamplesPerFrame HFB_GetSamplesPerFrame
#define lHFB_GetFrameRates HFB_GetFrameRates
#define lHFB_GetDRMData HFB_GetDRMData
#define lHFB_LoadIndex HFB_LoadIndex
#define lHFB_ParseFile HFB_ParseFile
#define lHFB_Init HFB_Init
#define lHFB_Exit HFB_Exit
#define lHFB_FindFile HFB_FindFile
#define lHFB_OpenFile HFB_OpenFile
#define lHFB_SeekToIndex HFB_SeekToIndex
#define lHFB_BeginLoadIndex HFB_BeginLoadIndex
#define lHFB_FinishLoadIndex HFB_FinishLoadIndex
#define lHFB_ReadMoreIndex HFB_ReadMoreIndex
#define lHFB_ParseBigIndex HFB_ParseBigIndex
#define lHFB_CloseFile HFB_CloseFile
#define lHFB_GetFileInfo HFB_GetFileInfo
#define lHFB_ResetStreams HFB_ResetStreams
#define lHFB_GetStream HFB_GetStream
#define lHFB_ReleaseStream HFB_ReleaseStream
#define lHFB_GetStreamInfo HFB_GetStreamInfo
#define lHFB_CreateBuffer HFB_CreateBuffer
#define lHFB_DestroyBuffer HFB_DestroyBuffer
#define lHFB_ResetBuffer HFB_ResetBuffer
#define lHFB_SetBufferMode HFB_SetBufferMode
#define lHFB_QueueOpenFile HFB_QueueOpenFile
#define lHFB_GetBufferPerCentFull HFB_GetBufferPerCentFull
#define lHFB_GetmovieSize HFB_GetmovieSize
#define lHFB_InitBuffer HFB_InitBuffer
#define lHFB_GetBufferSpace HFB_GetBufferSpace
#define lHFB_FillBuffer HFB_FillBuffer
#define lHFB_GetBufferStatus HFB_GetBufferStatus
#define lHFB_FramestoNextKeyFrame HFB_FramestoNextKeyFrame
#define lHFB_FrameToChunk HFB_FrameToChunk
#define lHFB_PreviousKeyFrame HFB_PreviousKeyFrame
#define lHFB_GetIndexFlags HFB_GetIndexFlags
#define lHFB_AddIndexFlags HFB_AddIndexFlags
#define lHFB_GetDataPosition HFB_GetDataPosition
#define lHFB_ConditionBuffer HFB_ConditionBuffer
#define lHFB_WalkFlags HFB_WalkFlags
#define lHFB_isVideoKeyFrame HFB_isVideoKeyFrame
#define lHFB_GetStreamParentBuffer HFB_GetStreamParentBuffer
#define lHFB_GetStreamParentFile HFB_GetStreamParentFile
#define lHFB_GetStreamRateAndScale HFB_GetStreamRateAndScale
#define lHFB_GetStreamFCCs HFB_GetStreamFCCs
#define lHFB_GetStreamSampleSize HFB_GetStreamSampleSize
#define lHFB_GetLastError HFB_GetLastError
#else
#if defined(__cplusplus)
extern "C" {
#endif
/* main HFB initialization and exit routines */
int lHFB_Init(int ,int ,int );
void lHFB_Exit(void);
/* FWG 9-13-2000 */
int lHFB_SeekToIndex(HFB_FILE_HANDLE FileHandle);
int lHFB_BeginLoadIndex(HFB_BUFFER_HANDLE dckPtr, int size);
int lHFB_FinishLoadIndex(HFB_BUFFER_HANDLE dckPtr, void *data, int size);
/* open specified file, parse its header(s) and load the index */
HFB_FILE_HANDLE lHFB_OpenFile(
const char *fileName,
HFB_BUFFER_HANDLE bufferHandle,
unsigned int userData
);
/* the following three functions, findfile, parsefile and loadindex,
are encapsulated by openfile, they are provided as a convenience
for use on systems with asynchronous i/o */
//HFB_FILE_HANDLE lHFB_FindFile(const char *fileName, unsigned int userData);
int lHFB_ParseFile(
HFB_FILE_HANDLE fileHandle,
HFB_BUFFER_HANDLE bufferHandle
);
int lHFB_LoadIndex(
HFB_FILE_HANDLE fileHandle,
HFB_BUFFER_HANDLE bufferHandle
);
void lHFB_CloseFile(HFB_FILE_HANDLE fHnd);
HFB_FILE_INFO *lHFB_GetFileInfo(HFB_FILE_HANDLE fileHandle);
HFB_BUFFER_HANDLE lHFB_CreateBuffer(
int sizeOfBuffer,
int reserved
);
void lHFB_InitBuffer(
HFB_BUFFER_HANDLE bufferHandle,
HFB_FILE_HANDLE fileToLoad,
int startFrame,
int initialReadSize
);
int lHFB_FillBuffer(
HFB_BUFFER_HANDLE bufferHandle,
int maxToRead,
int frameSyncCounter
);
void lHFB_DestroyBuffer(HFB_BUFFER_HANDLE bufferHandle);
void lHFB_ResetStreams(HFB_BUFFER_HANDLE bufferHandle);
int lHFB_SetBufferMode(
HFB_BUFFER_HANDLE ,
hfbBufferMode mode
);
int lHFB_GetBufferPerCentFull(HFB_BUFFER_HANDLE );
int lHFB_GetmovieSize(HFB_BUFFER_HANDLE );
int lHFB_GetBufferSpace(HFB_BUFFER_HANDLE );
hfbBufferStatus lHFB_GetBufferStatus(HFB_BUFFER_HANDLE );
int lHFB_ConditionBuffer(
HFB_BUFFER_HANDLE bufferHandle,
int bufferSize,
int reserved);
#define lHFB_ResetBuffer lHFB_ConditionBuffer
/* get a stream reference handle */
HFB_STREAM_HANDLE lHFB_GetStream(
HFB_FILE_HANDLE fileHandle,
const char *StreamNameOrNull,
int streamNumber,
unsigned int streamType);
/* relinquish reference to stream */
void lHFB_ReleaseStream(HFB_STREAM_HANDLE streamHandle);
/* get a pointer to stream info struct */
HFB_STREAM_INFO *lHFB_GetStreamInfo(HFB_STREAM_HANDLE );
#define lHFB_GetStreamLength(strmh) \
lHFB_GetStreamInfo(strmh)->lLength
#define lHFB_GetStreamName(strmh) \
lHFB_GetStreamInfo(strmh)->szName
/* get pointer to buffered record and length */
HFB_DATA_HANDLE lHFB_GetStreamingData(
HFB_STREAM_HANDLE streamHandle,
void **ptrToPtr,
int *ptrToLength,
hfbDirection directionToMove,
int framesToMove
);
/* release buffer space occupied by record */
void lHFB_ReleaseStreamingData(
HFB_BUFFER_HANDLE bufferHandle,
HFB_DATA_HANDLE recordToRelease);
/* read data directly from a file into a
supplied buffer, limit is set by initial value
of *ptrToLength */
int lHFB_ReadData(
HFB_STREAM_HANDLE streamHandle,
void *ptrToBuffer,
int *ptrToLength,
hfbDirection directionToMove,
int framesToMove);
int lHFB_FramestoNextKeyFrame(
HFB_STREAM_HANDLE streamHandle,
int recordHandle,
int *numberOfRecordsSpanned
);
int lHFB_FrameToChunk(
HFB_STREAM_HANDLE streamHandle,
int frameNumber
);
/* get the frameNumber of the keyframe
at or prior to the specified frameNumber */
int lHFB_PreviousKeyFrame(
HFB_STREAM_HANDLE streamHandle,
int frameNumber
);
/* get the HFB index flags for the specified record/frame */
int lHFB_GetIndexFlags(
HFB_STREAM_HANDLE ,
hfbFrameNumber frameNumberType,
int recordHandleOrFrameNumber);
/* add the HFB index flags for the specified record/frame */
int lHFB_AddIndexFlags(
HFB_STREAM_HANDLE ,
hfbFrameNumber frameNumberType,
int recordHandleOrFrameNumber,
int flagsToAdd);
/* get current data position
video - frameNumber
audio - sampleCount */
int lHFB_GetDataPosition(
HFB_STREAM_HANDLE streamHandle,
HFB_DATA_HANDLE dataRecordHandle
);
/* get information about audio stream */
DKWAVEFORM *lHFB_GetAudioInfo(
HFB_STREAM_HANDLE nStream,
int *NumChannels,
int *SamplesPerSec,
int *BytesPerSec,
int *wFormat);
/* get the amount of audio skew
expressed in records */
int lHFB_GetInitialFrames(
HFB_STREAM_HANDLE videoStream,
HFB_STREAM_HANDLE audioStream
);
/* get the number of audio frames elapsed
during a single video frame */
int lHFB_GetSamplesPerFrame(
HFB_STREAM_HANDLE videoStream,
HFB_STREAM_HANDLE audioStream
);
/* get video frame rate and
calculated audio skew (in audio samples) */
void lHFB_GetFrameRates(
HFB_STREAM_HANDLE videoStream,
HFB_STREAM_HANDLE audioStream,
int *ptrToIntegerFrameRate,
int *ptrToEstimatedAudioSampleSkew);
/* */
int lHFB_GetDRMData(
HFB_FILE_HANDLE dckPtr,
unsigned int* pOutEncFourCC,
int* pOutLength,
unsigned char** ppOutData);
/*get pointer to stream information streuct */
HFB_STREAM_INFO *lHFB_GetStreamInfo(HFB_STREAM_HANDLE );
/* functions to retrieve parent buffer
and file of a given stream*/
HFB_BUFFER_HANDLE lHFB_GetStreamParentBuffer(HFB_STREAM_HANDLE );
HFB_FILE_HANDLE lHFB_GetStreamParentFile(HFB_STREAM_HANDLE);
/* used to precisely calculate rational frame rates
for a specific stream */
void lHFB_GetStreamRateAndScale(
HFB_STREAM_HANDLE xStream,
int *rate, int *scale
);
/* get stream type and handler fourCC codes,
returns type (not handler) */
unsigned int lHFB_GetStreamFCCs(
HFB_STREAM_HANDLE xStream,
unsigned int *type,
unsigned int *handler
);
/* get the last error that occured in HFB */
int lHFB_GetLastError(
HFB_BUFFER_HANDLE bfHnd,
int* lastErrorCode,
char errorString[],
size_t maxLen
);
/* get streamSampleSize, <= 0 means variable */
int lHFB_GetStreamSampleSize(HFB_STREAM_HANDLE xStream);
int lHFB_WhatsAhead(HFB_STREAM_HANDLE ,int ,int *);
/* windows 95 dll system abstraction functions */
void lHFB_Setmalloc(
void *(*mallocFuncPtr)(unsigned int size)
);
void lHFB_Setcalloc(
void *(*callocFuncPtr)(unsigned int size, unsigned int number)
);
void lHFB_Setfree(
void (*freeFuncPtr)(void *)
);
void lHFB_Setopen(
int (*openFuncPtr)(const char *, int,...)
);
void lHFB_Setclose(
int (*closeFuncPtr)(int)
);
void lHFB_Setread(
int (*readFuncPtr)(int,void *, unsigned int)
);
void lHFB_Setseek(
int (*seekFuncPtr)(int,int,int)
);
#if defined(__cplusplus)
}
#endif
#endif
#endif

View file

@ -0,0 +1,24 @@
#if !defined(_TestResults_h)
#define _TestResults_h
#include <string.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct TestResults_T
{
char * results;
int testResultMaxLength;
} TestResults;
int GetTestResults( TestResults *T ,int argc, char *argv[]);
const char * GetTestHelp(void);
inline void StoreTestResult(TestResults *p, char *msg)
{
if (p)
{
sprintf(&(p->results[strlen(p->results)]),"%s",msg);
}
}
#if defined(__cplusplus)
}
#endif
#endif /* include guards */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,148 @@
/*****************************************************************************
*
* Module tvGetStr.H
* The defines and prototypes for the ToolVox error string
* reporting module.
*
* Voxware Proprietary Material
* Copyright 1996, Voxware, Inc.
* All Rights Resrved
*
* DISTRIBUTION PROHIBITED without
* written authorization from Voxware
*
****************************************************************************/
#if (_DEBUG_MESSAGES == 1) || defined(_DEBUG)
#ifndef __TVGETSTR_H_
#define __TVGETSTR_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Windows users must define VOXWARE_??? as a compiler option. This will */
/* enable system specific code. */
#if defined (VOXWARE_WIN16) || (VOXWARE_WIN32)
#define STRING_FORMAT wsprintf
#elif defined(VOXWARE_MAC)
#define STRING_FORMAT sprintf
#elif defined(VOXWARE_HP)
#define STRING_FORMAT sprintf
#elif defined(VOXWARE_SUN)
#define STRING_FORMAT sprintf
#elif defined(VOXWARE_DOS)
#define STRING_FORMAT sprintf
#else
#pragma message ("TVGETSTR.H: Platform indicator #define not setup.")
#pragma message ("TVGETSTR.H: One of the following must be initialized:")
#pragma message ("TVGETSTR.H: #define VOXWARE_WIN16")
#pragma message ("TVGETSTR.H: #define VOXWARE_WIN32")
#pragma message ("TVGETSTR.H: #define VOXWARE_MAC")
#pragma message ("TVGETSTR.H: #define VOXWARE_SUN")
#pragma message ("TVGETSTR.H: #define VOXWARE_HP")
#pragma message ("TVGETSTR.H: #define VOXWARE_AIX")
#pragma message ("TVGETSTR.H: #define VOXWARE_DOS")
#pragma message ("TVGETSTR.H: Check the Voxware manual for more information.")
#endif
#define TVGETSTR_MAX_STRING_LENGTH 512
void tvGetStringFromError(VOXWARE_RETCODE wVoxwareError, signed long dwReturnCode,
char VOX_FAR *lpMessage);
#ifdef __cplusplus
}
#endif
#endif /*__TVGETSTR_H_*/
#endif /* _DEBUG_MESSAGES */

View file

@ -0,0 +1,127 @@
/**********************************************************************
* (c) 1996 Voxware, Inc. All Rights Reserved. This file contains
* proprietary information of trade secrets of Voxware, Inc. and may
* not be distributed without the authorization of Voxware, Inc.
**********************************************************************
*
* File: VOXCHUNK.H
* Purpose: Types and #defines which describe the handling of
* the INFO chunks in the vox files.
* Created: 5/29/96 - George T. Talbot
* Modified: 6/17/96 - GTT - Added code to set lengths to -1 on
* the VOXCHUNK_SET() macro so that
* the default behaviour is to read
* existing info data.
* Notes:
*
**********************************************************************/
#ifndef _VOXCHUNK_H_
#define _VOXCHUNK_H_
typedef struct tagVox_Chunk_Info
{
unsigned long id;
long length;
char info[256];
} VOX_CHUNK_INFO;
// Important note: When adding a new VOXCHUNK_xxx, make sure to add
// the cooresponding elements to the gRIFF_VoxChunk_IDs[] and
// gAIFF_VoxChunk_IDs[] arrays in INFOCHNK.C
#define VOXCHUNK_NONE 0
#define VOXCHUNK_URL 1
#define VOXCHUNK_COPYRIGHT 2
#define VOXCHUNK_TITLE 3
#define VOXCHUNK_SOFTWARE 4
#define VOXCHUNK_AUTHOR 5
#define VOXCHUNK_COMMENT 6
#define VOXCHUNK_NUM_KINDS 7
// Convenience macros...
// Clear out a set of VOX_CHUNK_INFO records for use...
//
// Parameters are: _zz1 - Pointer to array of VOX_CHUNK_INFO.
// _zz2 - Number of elements in the array.
#define VOXCHUNK_SET(_zz1, _zz2) { \
memset((_zz1), 0, (_zz2) * sizeof(VOX_CHUNK_INFO)); \
for (short i=0; i<(_zz2); ++i) \
{ \
(_zz1)[i].length = -1; \
} \
}
// Write a C string into a VOX_CHUNK_INFO record...
//
// Parameters are: _zz1 - VOX_CHUNK_INFO record
// _zz2 - Chunk ID from above list
// _zz3 - A C string
#define VOXCHUNK_INFO(_zz1, _zz2, _zz3) \
{ \
(_zz1).id = (_zz2); \
(_zz1).length = strlen(_zz3)+1; \
memcpy((_zz1).info, (_zz3), (_zz1).length); \
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,317 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{C3547FC9-A6AC-4706-BED7-D696A8EF9EED}</ProjectGuid>
<RootNamespace>on2_mem</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>17.0.32505.173</_ProjectFileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>..\..\..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\..\..\obj\on2_mem\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\..\..\obj\on2_mem\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>..\..\..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\..\..\obj\on2_mem\$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<OutDir>..\..\..\..\..\..\lib\$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>..\..\..\..\..\..\obj\on2_mem\$(PlatformShortName)_$(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\..\include;..\..\..\common\include;..\..\memory_manager\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile>$(IntDir)on2_mem.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)on2_mem.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<AdditionalIncludeDirectories>..\..\include;..\..\..\common\include;..\..\memory_manager\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>$(IntDir)on2_mem.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)on2_mem.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\..\common\include;..\..\memory_manager\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader />
<PrecompiledHeaderOutputFile>$(IntDir)on2_mem.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)on2_mem.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;..\..\..\common\include;..\..\memory_manager\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>$(IntDir)on2_mem.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
<ObjectFileName>$(IntDir)</ObjectFileName>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Lib>
<OutputFile>$(OutDir)on2_mem.lib</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\memory_manager\hmm_alloc.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_base.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_dflt_abort.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_grow.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_largest.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_resize.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_shrink.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_true.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\on2_mem.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
<ClCompile Include="..\..\on2_mem_tracker.c">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\on2_mem.h" />
<ClInclude Include="..\..\include\on2_mem_tracker.h" />
<ClInclude Include="..\..\memory_manager\include\cavl_if.h" />
<ClInclude Include="..\..\memory_manager\include\cavl_impl.h" />
<ClInclude Include="..\..\memory_manager\include\heapmm.h" />
<ClInclude Include="..\..\memory_manager\include\hmm_cnfg.h" />
<ClInclude Include="..\..\memory_manager\include\hmm_intrnl.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{9e1216e0-9418-47c8-8b65-d829ad4b69a5}</UniqueIdentifier>
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
</Filter>
<Filter Include="Source Files\memory_manager">
<UniqueIdentifier>{4c33a825-25eb-47cb-b841-87f800085fba}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{70389f5d-efd2-456e-a0e2-09499eb80192}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl</Extensions>
</Filter>
<Filter Include="Header Files\memory_manager_hdrs">
<UniqueIdentifier>{7deb3717-4ad2-4cdc-8773-cc326f108428}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\on2_mem.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\on2_mem_tracker.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_alloc.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_base.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_dflt_abort.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_grow.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_largest.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_resize.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_shrink.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
<ClCompile Include="..\..\memory_manager\hmm_true.c">
<Filter>Source Files\memory_manager</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\on2_mem.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\include\on2_mem_tracker.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\memory_manager\include\cavl_if.h">
<Filter>Header Files\memory_manager_hdrs</Filter>
</ClInclude>
<ClInclude Include="..\..\memory_manager\include\cavl_impl.h">
<Filter>Header Files\memory_manager_hdrs</Filter>
</ClInclude>
<ClInclude Include="..\..\memory_manager\include\heapmm.h">
<Filter>Header Files\memory_manager_hdrs</Filter>
</ClInclude>
<ClInclude Include="..\..\memory_manager\include\hmm_cnfg.h">
<Filter>Header Files\memory_manager_hdrs</Filter>
</ClInclude>
<ClInclude Include="..\..\memory_manager\include\hmm_intrnl.h">
<Filter>Header Files\memory_manager_hdrs</Filter>
</ClInclude>
</ItemGroup>
</Project>

View file

@ -0,0 +1,108 @@
#ifndef __ON2_MEM_H__
#define __ON2_MEM_H__
/* on2_mem version info */
#define on2_mem_version "2.0.1.1"
#define ON2_MEM_VERSION_CHIEF 2
#define ON2_MEM_VERSION_MAJOR 0
#define ON2_MEM_VERSION_MINOR 1
#define ON2_MEM_VERSION_PATCH 1
/* end - on2_mem version info */
#define ON2_TRACK_MEM_USAGE 0 //enable memory tracking/integrity checks
#define ON2_CHECK_MEM_FUNCTIONS 0 //enable basic safety checks in _memcpy,
//_memset, and _memmove
#define REPLACE_BUILTIN_FUNCTIONS 0 //replace builtin functions with their
//on2_ equivalents
#include <stddef.h>
#include "on2_mem_tracker.h"
#if defined(__cplusplus)
extern "C" {
#endif
/*
on2_mem_get_version()
provided for runtime version checking. Returns an unsigned int of the form
CHIEF | MAJOR | MINOR | PATCH, where the chief version number is the high
order byte.
*/
unsigned int on2_mem_get_version();
/*
on2_mem_set_heap_size(size_t size)
size - size in bytes for the memory manager to allocate for its heap
Sets the memory manager's initial heap size
Return:
0: on success
-1: if memory manager calls have not been included in the on2_mem lib
-2: if the memory manager has been compiled to use static memory
-3: if the memory manager has already allocated its heap
*/
int on2_mem_set_heap_size(size_t size);
void* on2_memalign(size_t align, size_t size);
void* on2_malloc(size_t size);
void* on2_calloc(size_t num, size_t size);
void* on2_realloc(void* memblk, size_t size);
void on2_free(void* memblk);
void* on2_memcpy(void* dest, const void* src, size_t length);
void* on2_memset(void* dest, int val, size_t length);
void* on2_memmove(void* dest, const void* src, size_t count);
/* some defines for backward compatibility */
#define DMEM_GENERAL 0
#define duck_memalign(X,Y,Z) on2_memalign(X,Y)
#define duck_malloc(X,Y) on2_malloc(X)
#define duck_calloc(X,Y,Z) on2_calloc(X,Y)
#define duck_realloc on2_realloc
#define duck_free on2_free
#define duck_memcpy on2_memcpy
#define duck_memmove on2_memmove
#define duck_memset on2_memset
#if REPLACE_BUILTIN_FUNCTIONS
#define memalign on2_memalign
#define malloc on2_malloc
#define calloc on2_calloc
#define realloc on2_realloc
#define free on2_free
#define memcpy on2_memcpy
#define memmove on2_memmove
#define memset on2_memset
#endif
#if ON2_TRACK_MEM_USAGE
# ifndef __ON2_MEM_C__
# define on2_memalign(align, size) xon2_memalign((align), (size), __FILE__, __LINE__)
# define on2_malloc(size) xon2_malloc((size), __FILE__, __LINE__)
# define on2_calloc(num, size) xon2_calloc(num, size, __FILE__, __LINE__)
# define on2_realloc(addr, size) xon2_realloc(addr, size, __FILE__, __LINE__)
# define on2_free(addr) xon2_free(addr, __FILE__, __LINE__)
# endif
void* xon2_memalign(size_t align, size_t size, char* file, int line);
void* xon2_malloc(size_t size, char* file, int line);
void* xon2_calloc(size_t num, size_t size, char* file, int line);
void* xon2_realloc(void* memblk, size_t size, char* file, int line);
void xon2_free(void* memblk, char* file, int line);
#endif
#if !ON2_CHECK_MEM_FUNCTIONS
# ifndef __ON2_MEM_C__
# include <string.h>
# define on2_memcpy memcpy
# define on2_memset memset
# define on2_memmove memmove
# endif
#endif
#if defined(__cplusplus)
}
#endif
#endif /* __ON2_MEM_H__ */

View file

@ -0,0 +1,126 @@
#ifndef __ON2_MEM_TRACKER_H__
#define __ON2_MEM_TRACKER_H__
/* on2_mem_tracker version info */
#define on2_mem_tracker_version "2.3.1.2"
#define ON2_MEM_TRACKER_VERSION_CHIEF 2
#define ON2_MEM_TRACKER_VERSION_MAJOR 3
#define ON2_MEM_TRACKER_VERSION_MINOR 1
#define ON2_MEM_TRACKER_VERSION_PATCH 2
/* END - on2_mem_tracker version info */
struct MemBlock
{
size_t addr;
unsigned int size,
line;
char* file;
struct MemBlock* prev,
* next;
};
#if defined(__cplusplus)
extern "C" {
#endif
/*
on2_MemoryTrackerInit(int padding_size, int pad_value)
padding_size - the size of the padding before and after each mem addr.
Values > 0 indicate that integrity checks can be performed
by inspecting these areas.
pad_value - the initial value within the padding area before and after
each mem addr.
Initializes the memory tracker interface. Should be called before any
other calls to the memory tracker.
*/
int on2_MemoryTrackerInit(int padding_size, int pad_value);
/*
on2_MemoryTrackerDestroy()
Deinitializes the memory tracker interface
*/
void on2_MemoryTrackerDestroy();
/*
on2_MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line)
addr - memory address to be added to list
size - size of addr
file - the file addr was referenced from
line - the line in file addr was referenced from
Adds memory address addr, it's size, file and line it came from
to the memory tracker allocation table
*/
void on2_MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line);
/*
on2_MemoryTrackerAdd(size_t addr, unsigned int size, char * file, unsigned int line)
addr - memory address to be added to be removed
Removes the specified address from the memory tracker's allocation
table
Return:
0: on success
-1: if memory allocation table's mutex could not be locked
-2: if the addr was not found in the list
*/
int on2_MemoryTrackerRemove(size_t addr);
/*
on2_MemoryTrackerFind(unsigned int addr)
addr - address to be found in the memory tracker's
allocation table
Return:
If found, pointer to the memory block that matches addr
NULL otherwise
*/
struct MemBlock* on2_MemoryTrackerFind(size_t addr);
/*
on2_MemoryTrackerDump()
Dumps the current contents of the memory
tracker allocation table
*/
void on2_MemoryTrackerDump();
/*
on2_MemoryTrackerCheckIntegrity()
If a padding_size was provided to on2_MemoryTrackerInit()
This function will verify that the region before and after each
memory address contains the specified pad_value. Should the check
fail, the filename and line of the check will be printed out.
*/
void on2_MemoryTrackerCheckIntegrity(char* file, unsigned int line);
/*
on2_MemoryTrackerSetLogType
type - value representing the logging type to use
option - type specific option. This will be interpreted differently
based on the type.
Sets the logging type for the memory tracker.
Values currently supported:
0: if option is NULL, log to stderr, otherwise interpret option as a
filename and attempt to open it.
-1: Use OutputDebugString (WIN32 only), option ignored
Return:
0: on success
-1: if the logging type could not be set, because the value was invalid
or because a file could not be opened
*/
int on2_MemoryTrackerSetLogType(int type, char* option);
#if !defined(__ON2_MEM_TRACKER_C__) && !defined(__ON2_MEM_C__)
#if ON2_TRACK_MEM_USAGE
#define on2_MemoryTrackerCheckIntegrity() on2_MemoryTrackerCheckIntegrity(__FILE__, __LINE__)
#else
#define on2_MemoryTrackerCheckIntegrity()
#endif
#endif
#if defined(__cplusplus)
}
#endif
#endif //__ON2_MEM_TRACKER_H__

View file

@ -0,0 +1,48 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
void * U(alloc)(U(descriptor) *desc, U(size_aau) n)
{
#ifdef HMM_AUDIT_FAIL
if (desc->avl_tree_root)
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
if (desc->last_freed)
{
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(desc->last_freed)
#endif
U(into_free_collection)(desc, (head_record *) (desc->last_freed));
desc->last_freed = 0;
}
/* Add space for block header. */
n += HEAD_AAUS;
/* Convert n from number of address alignment units to block alignment
** units. */
n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT);
if (n < MIN_BLOCK_BAUS)
n = MIN_BLOCK_BAUS;
{
/* Search for the first node of the bin containing the smallest
** block big enough to satisfy request. */
ptr_record *ptr_rec_ptr =
U(avl_search)(
(U(avl_avl) *) &(desc->avl_tree_root), (U(size_bau)) n,
AVL_GREATER_EQUAL);
/* If an approprate bin is found, satisfy the allocation request,
** otherwise return null pointer. */
return(ptr_rec_ptr ?
U(alloc_from_bin)(desc, ptr_rec_ptr, (U(size_bau)) n) : 0);
}
}

View file

@ -0,0 +1,418 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
void U(init)(U(descriptor) *desc)
{
desc->avl_tree_root = 0;
desc->last_freed = 0;
}
/* Remove a free block from a bin's doubly-linked list when it is not,
** the first block in the bin.
*/
void U(dll_remove)(
/* Pointer to pointer record in the block to be removed. */
ptr_record *to_remove)
{
to_remove->prev->next = to_remove->next;
if (to_remove->next)
to_remove->next->prev = to_remove->prev;
}
/* Put a block into the free collection of a heap.
*/
void U(into_free_collection)(
/* Pointer to heap descriptor. */
U(descriptor) *desc,
/* Pointer to head record of block. */
head_record *head_ptr)
{
ptr_record *ptr_rec_ptr = HEAD_TO_PTR_REC(head_ptr);
ptr_record *bin_front_ptr =
U(avl_insert)((U(avl_avl) *) &(desc->avl_tree_root), ptr_rec_ptr);
if (bin_front_ptr != ptr_rec_ptr)
{
/* The block was not inserted into the AVL tree because there is
** already a bin for the size of the block. */
MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(head_ptr)
ptr_rec_ptr->self = ptr_rec_ptr;
/* Make the block the new second block in the bin's doubly-linked
** list. */
ptr_rec_ptr->prev = bin_front_ptr;
ptr_rec_ptr->next = bin_front_ptr->next;
bin_front_ptr->next = ptr_rec_ptr;
if (ptr_rec_ptr->next)
ptr_rec_ptr->next->prev = ptr_rec_ptr;
}
else
/* Block is first block in new bin. */
ptr_rec_ptr->next = 0;
}
/* Allocate a block from a given bin. Returns a pointer to the payload
** of the removed block. The "last freed" pointer must be null prior
** to calling this function.
*/
void * U(alloc_from_bin)(
/* Pointer to heap descriptor. */
U(descriptor) *desc,
/* Pointer to pointer record of first block in bin. */
ptr_record *bin_front_ptr,
/* Number of BAUs needed in the allocated block. If the block taken
** from the bin is significantly larger than the number of BAUs needed,
** the "extra" BAUs are split off to form a new free block. */
U(size_bau) n_baus)
{
head_record *head_ptr;
U(size_bau) rem_baus;
if (bin_front_ptr->next)
{
/* There are multiple blocks in this bin. Use the 2nd block in
** the bin to avoid needless change to the AVL tree.
*/
ptr_record *ptr_rec_ptr = bin_front_ptr->next;
head_ptr = PTR_REC_TO_HEAD(ptr_rec_ptr);
#ifdef AUDIT_FAIL
AUDIT_BLOCK(head_ptr)
#endif
U(dll_remove)(ptr_rec_ptr);
}
else
{
/* There is only one block in the bin, so it has to be removed
** from the AVL tree.
*/
head_ptr = PTR_REC_TO_HEAD(bin_front_ptr);
U(avl_remove)(
(U(avl_avl) *) &(desc->avl_tree_root), BLOCK_BAUS(head_ptr));
}
MARK_BLOCK_ALLOCATED(head_ptr)
rem_baus = BLOCK_BAUS(head_ptr) - n_baus;
if (rem_baus >= MIN_BLOCK_BAUS)
{
/* Since there are enough "extra" BAUs, split them off to form
** a new free block.
*/
head_record *rem_head_ptr =
(head_record *) BAUS_FORWARD(head_ptr, n_baus);
/* Change the next block's header to reflect the fact that the
** block preceeding it is now smaller.
*/
SET_PREV_BLOCK_BAUS(
BAUS_FORWARD(head_ptr, head_ptr->block_size), rem_baus)
head_ptr->block_size = n_baus;
rem_head_ptr->previous_block_size = n_baus;
rem_head_ptr->block_size = rem_baus;
desc->last_freed = rem_head_ptr;
}
return(HEAD_TO_PTR_REC(head_ptr));
}
/* Take a block out of the free collection.
*/
void U(out_of_free_collection)(
/* Descriptor of heap that block is in. */
U(descriptor) *desc,
/* Pointer to head of block to take out of free collection. */
head_record *head_ptr)
{
ptr_record *ptr_rec_ptr = HEAD_TO_PTR_REC(head_ptr);
if (ptr_rec_ptr->self == ptr_rec_ptr)
/* Block is not the front block in its bin, so all we have to
** do is take it out of the bin's doubly-linked list. */
U(dll_remove)(ptr_rec_ptr);
else
{
ptr_record *next = ptr_rec_ptr->next;
if (next)
/* Block is the front block in its bin, and there is at least
** one other block in the bin. Substitute the next block for
** the front block. */
U(avl_subst)((U(avl_avl) *) &(desc->avl_tree_root), next);
else
/* Block is the front block in its bin, but there is no other
** block in the bin. Eliminate the bin. */
U(avl_remove)(
(U(avl_avl) *) &(desc->avl_tree_root), BLOCK_BAUS(head_ptr));
}
}
void U(free)(U(descriptor) *desc, void *payload_ptr)
{
/* Flags if coalesce with adjacent block. */
int coalesce;
head_record *fwd_head_ptr;
head_record *free_head_ptr = PTR_REC_TO_HEAD(payload_ptr);
desc->num_baus_can_shrink = 0;
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(free_head_ptr)
/* Make sure not freeing an already free block. */
if (!IS_BLOCK_ALLOCATED(free_head_ptr))
HMM_AUDIT_FAIL
if (desc->avl_tree_root)
/* Audit root block in AVL tree. */
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
fwd_head_ptr =
(head_record *) BAUS_FORWARD(free_head_ptr, free_head_ptr->block_size);
if (free_head_ptr->previous_block_size)
{
/* Coalesce with backward block if possible. */
head_record *bkwd_head_ptr =
(head_record *) BAUS_BACKWARD(
free_head_ptr, free_head_ptr->previous_block_size);
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(bkwd_head_ptr)
#endif
if (bkwd_head_ptr == (head_record *) (desc->last_freed))
{
desc->last_freed = 0;
coalesce = 1;
}
else if (IS_BLOCK_ALLOCATED(bkwd_head_ptr))
coalesce = 0;
else
{
U(out_of_free_collection)(desc, bkwd_head_ptr);
coalesce = 1;
}
if (coalesce)
{
bkwd_head_ptr->block_size += free_head_ptr->block_size;
SET_PREV_BLOCK_BAUS(fwd_head_ptr, BLOCK_BAUS(bkwd_head_ptr))
free_head_ptr = bkwd_head_ptr;
}
}
if (fwd_head_ptr->block_size == 0)
{
/* Block to be freed is last block before dummy end-of-chunk block. */
desc->end_of_shrinkable_chunk =
BAUS_FORWARD(fwd_head_ptr, DUMMY_END_BLOCK_BAUS);
desc->num_baus_can_shrink = BLOCK_BAUS(free_head_ptr);
if (PREV_BLOCK_BAUS(free_head_ptr) == 0)
/* Free block is the entire chunk, so shrinking can eliminate
** entire chunk including dummy end block. */
desc->num_baus_can_shrink += DUMMY_END_BLOCK_BAUS;
}
else
{
/* Coalesce with forward block if possible. */
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(fwd_head_ptr)
#endif
if (fwd_head_ptr == (head_record *) (desc->last_freed))
{
desc->last_freed = 0;
coalesce = 1;
}
else if (IS_BLOCK_ALLOCATED(fwd_head_ptr))
coalesce = 0;
else
{
U(out_of_free_collection)(desc, fwd_head_ptr);
coalesce = 1;
}
if (coalesce)
{
free_head_ptr->block_size += fwd_head_ptr->block_size;
fwd_head_ptr =
(head_record *) BAUS_FORWARD(
fwd_head_ptr, BLOCK_BAUS(fwd_head_ptr));
SET_PREV_BLOCK_BAUS(fwd_head_ptr, BLOCK_BAUS(free_head_ptr))
if (fwd_head_ptr->block_size == 0)
{
/* Coalesced block to be freed is last block before dummy
** end-of-chunk block. */
desc->end_of_shrinkable_chunk =
BAUS_FORWARD(fwd_head_ptr, DUMMY_END_BLOCK_BAUS);
desc->num_baus_can_shrink = BLOCK_BAUS(free_head_ptr);
if (PREV_BLOCK_BAUS(free_head_ptr) == 0)
/* Free block is the entire chunk, so shrinking can
** eliminate entire chunk including dummy end block. */
desc->num_baus_can_shrink += DUMMY_END_BLOCK_BAUS;
}
}
}
if (desc->last_freed)
{
/* There is a last freed block, but it is not adjacent to the
** block being freed by this call to free, so put the last
** freed block into the free collection.
*/
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(desc->last_freed)
#endif
U(into_free_collection)(desc, (head_record *) (desc->last_freed));
}
desc->last_freed = free_head_ptr;
}
void U(new_chunk)(U(descriptor) *desc, void *start, U(size_bau) n_baus)
{
#ifdef HMM_AUDIT_FAIL
if (desc->avl_tree_root)
/* Audit root block in AVL tree. */
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
#undef HEAD_PTR
#define HEAD_PTR ((head_record *) start)
/* Make the chunk one big free block followed by a dummy end block.
*/
n_baus -= DUMMY_END_BLOCK_BAUS;
HEAD_PTR->previous_block_size = 0;
HEAD_PTR->block_size = n_baus;
U(into_free_collection)(desc, HEAD_PTR);
/* Set up the dummy end block. */
start = BAUS_FORWARD(start, n_baus);
HEAD_PTR->previous_block_size = n_baus;
HEAD_PTR->block_size = 0;
#undef HEAD_PTR
}
#ifdef HMM_AUDIT_FAIL
/* Function that does audit fail actions defined my preprocessor symbol,
** and returns a dummy integer value.
*/
int U(audit_block_fail_dummy_return)(void)
{
HMM_AUDIT_FAIL
/* Dummy return. */
return(0);
}
#endif
/* AVL Tree instantiation. */
#ifdef HMM_AUDIT_FAIL
/* The AVL tree generic package passes an ACCESS of 1 when it "touches"
** a child node for the first time during a particular operation. I use
** this feature to audit only one time (per operation) the free blocks
** that are tree nodes. Since the root node is not a child node, it has
** to be audited directly.
*/
/* The pain you feel while reading these macros will not be in vain. It
** will remove all doubt from you mind that C++ inline functions are
** a very good thing.
*/
#define AVL_GET_LESS(H, ACCESS) \
(((ACCESS) ? AUDIT_BLOCK_AS_EXPR(PTR_REC_TO_HEAD(H)) : 0), (H)->self)
#define AVL_GET_GREATER(H, ACCESS) \
(((ACCESS) ? AUDIT_BLOCK_AS_EXPR(PTR_REC_TO_HEAD(H)) : 0), (H)->prev)
#else
#define AVL_GET_LESS(H, ACCESS) ((H)->self)
#define AVL_GET_GREATER(H, ACCESS) ((H)->prev)
#endif
#define AVL_SET_LESS(H, LH) (H)->self = (LH);
#define AVL_SET_GREATER(H, GH) (H)->prev = (GH);
/* high bit of high bit of
** block_size previous_block_size balance factor
** ----------- ------------------- --------------
** 0 0 n/a (block allocated)
** 0 1 1
** 1 0 -1
** 1 1 0
*/
#define AVL_GET_BALANCE_FACTOR(H) \
((((head_record *) (PTR_REC_TO_HEAD(H)))->block_size & \
HIGH_BIT_BAU_SIZE) ? \
(((head_record *) (PTR_REC_TO_HEAD(H)))->previous_block_size & \
HIGH_BIT_BAU_SIZE ? 0 : -1) : 1)
#define AVL_SET_BALANCE_FACTOR(H, BF) \
{ \
register head_record *p = \
(head_record *) PTR_REC_TO_HEAD(H); \
register int bal_f = (BF); \
\
if (bal_f <= 0) \
p->block_size |= HIGH_BIT_BAU_SIZE; \
else \
p->block_size &= ~HIGH_BIT_BAU_SIZE; \
if (bal_f >= 0) \
p->previous_block_size |= HIGH_BIT_BAU_SIZE; \
else \
p->previous_block_size &= ~HIGH_BIT_BAU_SIZE; \
}
#define COMPARE_KEY_KEY(K1, K2) ((K1) == (K2) ? 0 : ((K1) > (K2) ? 1 : -1))
#define AVL_COMPARE_KEY_NODE(K, H) \
COMPARE_KEY_KEY(K, BLOCK_BAUS(PTR_REC_TO_HEAD(H)))
#define AVL_COMPARE_NODE_NODE(H1, H2) \
COMPARE_KEY_KEY(BLOCK_BAUS(PTR_REC_TO_HEAD(H1)), \
BLOCK_BAUS(PTR_REC_TO_HEAD(H2)))
#define AVL_NULL ((ptr_record *) 0)
#define AVL_IMPL_MASK \
( AVL_IMPL_INSERT | AVL_IMPL_SEARCH | AVL_IMPL_REMOVE | AVL_IMPL_SUBST )
#include "cavl_impl.h"

View file

@ -0,0 +1,43 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
/* The function in this file performs default actions if self-auditing
** finds heap corruption. Don't rely my feeble attempt to handle the
** case where HMM is being used to implement the malloc and free standard
** library functions. Rewrite the function if necessary to avoid using
** I/O and execution termination functions that call malloc or free.
** In Unix, for example, you would replace the fputs calls with calls
** to the write system call using file handle number 2.
*/
#include <stdio.h>
#include <stdlib.h>
static int entered = 0;
/* Print abort message, file and line. Terminate execution.
*/
void HMM_dflt_abort(const char *file, const char *line)
{
/* Avoid use of printf(), which is more likely to use heap. */
if (entered)
/* The standard I/O functions called a heap function and caused
** an indirect recursive call to this function. So we'll have
** to just exit without printing a message. */
while(1);
entered = 1;
fputs("\nABORT - Heap corruption\n" "File: ", stderr);
fputs(file, stderr);
fputs(" Line: ", stderr);
fputs(line, stderr);
fputs("\n\n", stderr);
fputs( "HMM_dflt_abort: while(1)!!!\n", stderr );
fflush(stderr);
while(1);
}

View file

@ -0,0 +1,39 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
void U(grow_chunk)(U(descriptor) *desc, void *end, U(size_bau) n_baus)
{
#undef HEAD_PTR
#define HEAD_PTR ((head_record *) end)
end = BAUS_BACKWARD(end, DUMMY_END_BLOCK_BAUS);
#ifdef HMM_AUDIT_FAIL
if (HEAD_PTR->block_size != 0)
/* Chunk does not have valid dummy end block. */
HMM_AUDIT_FAIL
#endif
/* Create a new block that absorbs the old dummy end block. */
HEAD_PTR->block_size = n_baus;
/* Set up the new dummy end block. */
{
head_record *dummy = (head_record *) BAUS_FORWARD(end, n_baus);
dummy->previous_block_size = n_baus;
dummy->block_size = 0;
}
/* Simply free the new block, allowing it to coalesce with any
** free block at that was the last block in the chunk prior to
** growth.
*/
U(free)(desc, HEAD_TO_PTR_REC(end));
#undef HEAD_PTR
}

View file

@ -0,0 +1,49 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
U(size_aau) U(largest_available)(U(descriptor) *desc)
{
U(size_bau) largest;
if (!(desc->avl_tree_root))
largest = 0;
else
{
#ifdef HMM_AUDIT_FAIL
/* Audit root block in AVL tree. */
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
largest =
BLOCK_BAUS(
PTR_REC_TO_HEAD(
U(avl_search)(
(U(avl_avl) *) &(desc->avl_tree_root),
(U(size_bau)) ~ (U(size_bau)) 0, AVL_LESS)));
}
if (desc->last_freed)
{
/* Size of last freed block. */
register U(size_bau) lf_size;
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(desc->last_freed)
#endif
lf_size = BLOCK_BAUS(desc->last_freed);
if (lf_size > largest)
largest = lf_size;
}
/* Convert largest size to AAUs and subract head size leaving payload
** size.
*/
return(largest ?
((largest * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) - HEAD_AAUS) :
0);
}

View file

@ -0,0 +1,107 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
int U(resize)(U(descriptor) *desc, void *mem, U(size_aau) n)
{
U(size_aau) i;
head_record *next_head_ptr;
head_record *head_ptr = PTR_REC_TO_HEAD(mem);
/* Flag. */
int next_block_free;
/* Convert n from desired block size in AAUs to BAUs. */
n += HEAD_AAUS;
n = DIV_ROUND_UP(n, HMM_BLOCK_ALIGN_UNIT);
if (n < MIN_BLOCK_BAUS)
n = MIN_BLOCK_BAUS;
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(head_ptr)
if (!IS_BLOCK_ALLOCATED(head_ptr))
HMM_AUDIT_FAIL
if (desc->avl_tree_root)
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
i = head_ptr->block_size;
next_head_ptr =
(head_record *) BAUS_FORWARD(head_ptr, head_ptr->block_size);
next_block_free =
(next_head_ptr == desc->last_freed) ||
!IS_BLOCK_ALLOCATED(next_head_ptr);
if (next_block_free)
/* Block can expand into next free block. */
i += BLOCK_BAUS(next_head_ptr);
if (n > i)
/* Not enough room for block to expand. */
return(-1);
if (next_block_free)
{
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(next_head_ptr)
#endif
if (next_head_ptr == desc->last_freed)
desc->last_freed = 0;
else
U(out_of_free_collection)(desc, next_head_ptr);
next_head_ptr =
(head_record *) BAUS_FORWARD(head_ptr, (U(size_bau)) i);
}
/* Set i to number of "extra" BAUs. */
i -= n;
if (i < MIN_BLOCK_BAUS)
/* Not enough extra BAUs to be a block on their own, so just keep them
** in the block being resized.
*/
{
n += i;
i = n;
}
else
{
/* There are enough "leftover" BAUs in the next block to
** form a remainder block. */
head_record *rem_head_ptr;
rem_head_ptr = (head_record *) BAUS_FORWARD(head_ptr, n);
rem_head_ptr->previous_block_size = (U(size_bau)) n;
rem_head_ptr->block_size = (U(size_bau)) i;
if (desc->last_freed)
{
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(desc->last_freed)
#endif
U(into_free_collection)(desc, (head_record *) (desc->last_freed));
desc->last_freed = 0;
}
desc->last_freed = rem_head_ptr;
}
head_ptr->block_size = (U(size_bau)) n;
next_head_ptr->previous_block_size = (U(size_bau)) i;
return(0);
}

View file

@ -0,0 +1,96 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
void U(shrink_chunk)(U(descriptor) *desc, U(size_bau) n_baus_to_shrink)
{
head_record *dummy_end_block = (head_record *)
BAUS_BACKWARD(desc->end_of_shrinkable_chunk, DUMMY_END_BLOCK_BAUS);
#ifdef HMM_AUDIT_FAIL
if (dummy_end_block->block_size != 0)
/* Chunk does not have valid dummy end block. */
HMM_AUDIT_FAIL
#endif
if (n_baus_to_shrink)
{
head_record *last_block = (head_record *)
BAUS_BACKWARD(
dummy_end_block, dummy_end_block->previous_block_size);
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(last_block)
#endif
if (last_block == desc->last_freed)
{
U(size_bau) bs = BLOCK_BAUS(last_block);
/* Chunk will not be shrunk out of existence if
** 1. There is at least one allocated block in the chunk
** and the amount to shrink is exactly the size of the
** last block, OR
** 2. After the last block is shrunk, there will be enough
** BAUs left in it to form a minimal size block. */
int chunk_will_survive =
(PREV_BLOCK_BAUS(last_block) && (n_baus_to_shrink == bs)) ||
(n_baus_to_shrink <= (U(size_bau)) (bs - MIN_BLOCK_BAUS));
if (chunk_will_survive ||
(!PREV_BLOCK_BAUS(last_block) &&
(n_baus_to_shrink ==
(U(size_bau)) (bs + DUMMY_END_BLOCK_BAUS))))
{
desc->last_freed = 0;
if (chunk_will_survive)
{
bs -= n_baus_to_shrink;
if (bs)
{
/* The last (non-dummy) block was not completely
** eliminated by the shrink. */
last_block->block_size = bs;
/* Create new dummy end record.
*/
dummy_end_block =
(head_record *) BAUS_FORWARD(last_block, bs);
dummy_end_block->previous_block_size = bs;
dummy_end_block->block_size = 0;
#ifdef HMM_AUDIT_FAIL
if (desc->avl_tree_root)
AUDIT_BLOCK(PTR_REC_TO_HEAD(desc->avl_tree_root))
#endif
U(into_free_collection)(desc, last_block);
}
else
{
/* The last (non-dummy) block was completely
** eliminated by the shrink. Make its head
** the new dummy end block.
*/
last_block->block_size = 0;
last_block->previous_block_size &= ~HIGH_BIT_BAU_SIZE;
}
}
}
#ifdef HMM_AUDIT_FAIL
else
HMM_AUDIT_FAIL
#endif
}
#ifdef HMM_AUDIT_FAIL
else
HMM_AUDIT_FAIL
#endif
}
}

View file

@ -0,0 +1,21 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#include "hmm_intrnl.h"
U(size_aau) U(true_size)(void *payload_ptr)
{
register head_record *head_ptr = PTR_REC_TO_HEAD(payload_ptr);
#ifdef HMM_AUDIT_FAIL
AUDIT_BLOCK(head_ptr)
#endif
/* Convert block size from BAUs to AAUs. Subtract head size, leaving
** payload size.
*/
return(
(BLOCK_BAUS(head_ptr) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT)) -
HEAD_AAUS);
}

View file

@ -0,0 +1,216 @@
/* Abstract AVL Tree Generic C Package.
** Interface generation header file.
**
** This code is in the public domain. See cavl_tree.html for interface
** documentation.
**
** Version: 1.5 Author: Walt Karas
*/
/* This header contains the definition of CHAR_BIT (number of bits in a
** char). */
#include <limits.h>
#undef L__
#undef L__EST_LONG_BIT
#undef L__SIZE
#undef L__SC
#undef L__LONG_BIT
#undef L__BIT_ARR_DEFN
#ifndef AVL_SEARCH_TYPE_DEFINED_
#define AVL_SEARCH_TYPE_DEFINED_
typedef enum
{
AVL_EQUAL = 1,
AVL_LESS = 2,
AVL_GREATER = 4,
AVL_LESS_EQUAL = AVL_EQUAL | AVL_LESS,
AVL_GREATER_EQUAL = AVL_EQUAL | AVL_GREATER
}
avl_search_type;
#endif
#ifdef AVL_UNIQUE
#define L__ AVL_UNIQUE
#else
#define L__(X) X
#endif
/* Determine storage class for function prototypes. */
#ifdef AVL_PRIVATE
#define L__SC static
#else
#define L__SC extern
#endif
#ifdef AVL_SIZE
#define L__SIZE AVL_SIZE
#else
#define L__SIZE unsigned long
#endif
typedef struct
{
#ifdef AVL_INSIDE_STRUCT
AVL_INSIDE_STRUCT
#endif
AVL_HANDLE root;
}
L__(avl);
/* Function prototypes. */
L__SC void L__(init)(L__(avl) *tree);
L__SC int L__(is_empty)(L__(avl) *tree);
L__SC AVL_HANDLE L__(insert)(L__(avl) *tree, AVL_HANDLE h);
L__SC AVL_HANDLE L__(search)(L__(avl) *tree, AVL_KEY k, avl_search_type st);
L__SC AVL_HANDLE L__(search_least)(L__(avl) *tree);
L__SC AVL_HANDLE L__(search_greatest)(L__(avl) *tree);
L__SC AVL_HANDLE L__(remove)(L__(avl) *tree, AVL_KEY k);
L__SC AVL_HANDLE L__(subst)(L__(avl) *tree, AVL_HANDLE new_node);
#ifdef AVL_BUILD_ITER_TYPE
L__SC int L__(build)(
L__(avl) *tree, AVL_BUILD_ITER_TYPE p, L__SIZE num_nodes);
#endif
/* ANSI C/ISO C++ require that a long have at least 32 bits. Set
** L__EST_LONG_BIT to be the greatest multiple of 8 in the range
** 32 - 64 (inclusive) that is less than or equal to the number of
** bits in a long.
*/
#if (((LONG_MAX >> 31) >> 7) == 0)
#define L__EST_LONG_BIT 32
#elif (((LONG_MAX >> 31) >> 15) == 0)
#define L__EST_LONG_BIT 40
#elif (((LONG_MAX >> 31) >> 23) == 0)
#define L__EST_LONG_BIT 48
#elif (((LONG_MAX >> 31) >> 31) == 0)
#define L__EST_LONG_BIT 56
#else
#define L__EST_LONG_BIT 64
#endif
/* Number of bits in a long. */
#define L__LONG_BIT (sizeof(long) * CHAR_BIT)
/* The macro L__BIT_ARR_DEFN defines a bit array whose index is a (0-based)
** node depth. The definition depends on whether the maximum depth is more
** or less than the number of bits in a single long.
*/
#if ((AVL_MAX_DEPTH) > L__EST_LONG_BIT)
/* Maximum depth may be more than number of bits in a long. */
#define L__BIT_ARR_DEFN(NAME) \
unsigned long NAME[((AVL_MAX_DEPTH) + L__LONG_BIT - 1) / L__LONG_BIT];
#else
/* Maximum depth is definitely less than number of bits in a long. */
#define L__BIT_ARR_DEFN(NAME) unsigned long NAME;
#endif
/* Iterator structure. */
typedef struct
{
/* Tree being iterated over. */
L__(avl) *tree_;
/* Records a path into the tree. If bit n is true, indicates
** take greater branch from the nth node in the path, otherwise
** take the less branch. bit 0 gives branch from root, and
** so on. */
L__BIT_ARR_DEFN(branch)
/* Zero-based depth of path into tree. */
unsigned depth;
/* Handles of nodes in path from root to current node (returned by *). */
AVL_HANDLE path_h[(AVL_MAX_DEPTH) - 1];
}
L__(iter);
/* Iterator function prototypes. */
L__SC void L__(start_iter)(
L__(avl) *tree, L__(iter) *iter, AVL_KEY k, avl_search_type st);
L__SC void L__(start_iter_least)(L__(avl) *tree, L__(iter) *iter);
L__SC void L__(start_iter_greatest)(L__(avl) *tree, L__(iter) *iter);
L__SC AVL_HANDLE L__(get_iter)(L__(iter) *iter);
L__SC void L__(incr_iter)(L__(iter) *iter);
L__SC void L__(decr_iter)(L__(iter) *iter);
L__SC void L__(init_iter)(L__(iter) *iter);
#define AVL_IMPL_INIT 1
#define AVL_IMPL_IS_EMPTY (1 << 1)
#define AVL_IMPL_INSERT (1 << 2)
#define AVL_IMPL_SEARCH (1 << 3)
#define AVL_IMPL_SEARCH_LEAST (1 << 4)
#define AVL_IMPL_SEARCH_GREATEST (1 << 5)
#define AVL_IMPL_REMOVE (1 << 6)
#define AVL_IMPL_BUILD (1 << 7)
#define AVL_IMPL_START_ITER (1 << 8)
#define AVL_IMPL_START_ITER_LEAST (1 << 9)
#define AVL_IMPL_START_ITER_GREATEST (1 << 10)
#define AVL_IMPL_GET_ITER (1 << 11)
#define AVL_IMPL_INCR_ITER (1 << 12)
#define AVL_IMPL_DECR_ITER (1 << 13)
#define AVL_IMPL_INIT_ITER (1 << 14)
#define AVL_IMPL_SUBST (1 << 15)
#define AVL_IMPL_ALL (~0)
#undef L__
#undef L__EST_LONG_BIT
#undef L__SIZE
#undef L__SC
#undef L__LONG_BIT
#undef L__BIT_ARR_DEFN

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,142 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
/* External header file for Heap Memory Manager. See documentation in
** heapmm.html.
*/
#undef HMM_PROCESS
/* Include once per configuration in a particular translation unit. */
#ifndef HMM_CNFG_NUM
/* Default configuration. */
#ifndef HMM_INC_CNFG_DFLT
#define HMM_INC_CNFG_DFLT
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 0
/* Test configuration. */
#ifndef HMM_INC_CNFG_0
#define HMM_INC_CNFG_0
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 1
#ifndef HMM_INC_CNFG_1
#define HMM_INC_CNFG_1
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 2
#ifndef HMM_INC_CNFG_2
#define HMM_INC_CNFG_2
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 3
#ifndef HMM_INC_CNFG_3
#define HMM_INC_CNFG_3
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 4
#ifndef HMM_INC_CNFG_4
#define HMM_INC_CNFG_4
#define HMM_PROCESS
#endif
#elif HMM_CNFG_NUM == 5
#ifndef HMM_INC_CNFG_5
#define HMM_INC_CNFG_5
#define HMM_PROCESS
#endif
#endif
#ifdef HMM_PROCESS
#include "hmm_cnfg.h"
/* Heap descriptor. */
typedef struct HMM_UNIQUE(structure)
{
/* private: */
/* Pointer to (payload of) root node in AVL tree. This field should
** really be the AVL tree descriptor (type avl_avl). But (in the
** instantiation of the AVL tree generic package used in package) the
** AVL tree descriptor simply contains a pointer to the root. So,
** whenever a pointer to the AVL tree descriptor is needed, I use the
** cast:
**
** (avl_avl *) &(heap_desc->avl_tree_root)
**
** (where heap_desc is a pointer to a heap descriptor). This trick
** allows me to avoid including cavl_if.h in this external header. */
void *avl_tree_root;
/* Pointer to first byte of last block freed, after any coalescing. */
void *last_freed;
/* public: */
HMM_UNIQUE(size_bau) num_baus_can_shrink;
void *end_of_shrinkable_chunk;
}
HMM_UNIQUE(descriptor);
/* Prototypes for externally-callable functions. */
void HMM_UNIQUE(init)(HMM_UNIQUE(descriptor) *desc);
void * HMM_UNIQUE(alloc)(
HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) num_addr_align_units);
/* NOT YET IMPLEMENTED */
void * HMM_UNIQUE(greedy_alloc)(
HMM_UNIQUE(descriptor) *desc, HMM_UNIQUE(size_aau) needed_addr_align_units,
HMM_UNIQUE(size_aau) coveted_addr_align_units);
int HMM_UNIQUE(resize)(
HMM_UNIQUE(descriptor) *desc, void *mem,
HMM_UNIQUE(size_aau) num_addr_align_units);
/* NOT YET IMPLEMENTED */
int HMM_UNIQUE(greedy_resize)(
HMM_UNIQUE(descriptor) *desc, void *mem,
HMM_UNIQUE(size_aau) needed_addr_align_units,
HMM_UNIQUE(size_aau) coveted_addr_align_units);
void HMM_UNIQUE(free)(HMM_UNIQUE(descriptor) *desc, void *mem);
HMM_UNIQUE(size_aau) HMM_UNIQUE(true_size)(void *mem);
HMM_UNIQUE(size_aau) HMM_UNIQUE(largest_available)(
HMM_UNIQUE(descriptor) *desc);
void HMM_UNIQUE(new_chunk)(
HMM_UNIQUE(descriptor) *desc, void *start_of_chunk,
HMM_UNIQUE(size_bau) num_block_align_units);
void HMM_UNIQUE(grow_chunk)(
HMM_UNIQUE(descriptor) *desc, void *end_of_chunk,
HMM_UNIQUE(size_bau) num_block_align_units);
/* NOT YET IMPLEMENTED */
void HMM_UNIQUE(shrink_chunk)(
HMM_UNIQUE(descriptor) *desc,
HMM_UNIQUE(size_bau) num_block_align_units);
#endif /* defined HMM_PROCESS */

View file

@ -0,0 +1,105 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
/* Configure Heap Memory Manager for processor architecture, compiler,
** and desired performance characteristics. This file is included
** by heapmm.h, so these definitions can be used by code external to
** HMM. You can change the default configuration, and/or create alternate
** configuration(s).
*/
/* To allow for multiple configurations of HMM to be used in the same
** compilation unit, undefine all preprocessor symbols that will be
** defined below.
*/
#undef HMM_ADDR_ALIGN_UNIT
#undef HMM_BLOCK_ALIGN_UNIT
#undef HMM_UNIQUE
#undef HMM_DESC_PARAM
#undef HMM__SYM_TO_STRING
#undef HMM_SYM_TO_STRING
#undef HMM_AUDIT_FAIL
/* Turn X into a string after one macro expansion pass of X. This trick
** works with both GCC and Visual C++. */
#define HMM_SYM_TO_STRING(X) HMM__SYM_TO_STRING(X)
#define HMM__SYM_TO_STRING(X) #X
#ifndef HMM_CNFG_NUM
/* Default configuration. */
/* Use hmm_ prefix to avoid identifier conflicts. */
#define HMM_UNIQUE(BASE) hmm_ ## BASE
/* Number of bytes in an Address Alignment Unit (AAU). */
//fwghack
//#define HMM_ADDR_ALIGN_UNIT sizeof(int)
#define HMM_ADDR_ALIGN_UNIT 32
/* Number of AAUs in a Block Alignment Unit (BAU). */
#define HMM_BLOCK_ALIGN_UNIT 1
/* Type of unsigned integer big enough to hold the size of a Block in AAUs. */
typedef unsigned long HMM_UNIQUE(size_aau);
/* Type of unsigned integer big enough to hold the size of a Block/Chunk
** in BAUs. The high bit will be robbed. */
typedef unsigned long HMM_UNIQUE(size_bau);
void HMM_dflt_abort(const char *, const char *);
/* Actions upon a self-audit failure. Must expand to a single complete
** statement. If you remove the definition of this macro, no self-auditing
** will be performed. */
#define HMM_AUDIT_FAIL \
HMM_dflt_abort(__FILE__, HMM_SYM_TO_STRING(__LINE__));
#elif HMM_CNFG_NUM == 0
/* Definitions for testing. */
#define HMM_UNIQUE(BASE) thmm_ ## BASE
#define HMM_ADDR_ALIGN_UNIT sizeof(int)
#define HMM_BLOCK_ALIGN_UNIT 3
typedef unsigned HMM_UNIQUE(size_aau);
typedef unsigned short HMM_UNIQUE(size_bau);
/* Under this test setup, a long jump is done if there is a self-audit
** failure.
*/
extern jmp_buf HMM_UNIQUE(jmp_buf);
extern const char * HMM_UNIQUE(fail_file);
extern unsigned HMM_UNIQUE(fail_line);
#define HMM_AUDIT_FAIL \
{ HMM_UNIQUE(fail_file) = __FILE__; HMM_UNIQUE(fail_line) = __LINE__; \
longjmp(HMM_UNIQUE(jmp_buf), 1); }
#elif HMM_CNFG_NUM == 1
/* Put configuration 1 definitions here (if there is a configuration 1). */
#elif HMM_CNFG_NUM == 2
/* Put configuration 2 definitions here. */
#elif HMM_CNFG_NUM == 3
/* Put configuration 3 definitions here. */
#elif HMM_CNFG_NUM == 4
/* Put configuration 4 definitions here. */
#elif HMM_CNFG_NUM == 5
/* Put configuration 5 definitions here. */
#endif

View file

@ -0,0 +1,149 @@
/* This code is in the public domain.
** Version: 1.1 Author: Walt Karas
*/
#ifndef HMM_INTRNL_H_
#define HMM_INTRNL_H_
#include "heapmm.h"
#define U(BASE) HMM_UNIQUE(BASE)
/* Mask of high bit of variable of size_bau type. */
#define HIGH_BIT_BAU_SIZE \
((U(size_bau)) ~ (((U(size_bau)) ~ (U(size_bau)) 0) >> 1))
/* Add a given number of AAUs to pointer. */
#define AAUS_FORWARD(PTR, AAU_OFFSET) \
(((char *) (PTR)) + ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
/* Subtract a given number of AAUs from pointer. */
#define AAUS_BACKWARD(PTR, AAU_OFFSET) \
(((char *) (PTR)) - ((AAU_OFFSET) * ((U(size_aau)) HMM_ADDR_ALIGN_UNIT)))
/* Add a given number of BAUs to a pointer. */
#define BAUS_FORWARD(PTR, BAU_OFFSET) \
AAUS_FORWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
/* Subtract a given number of BAUs to a pointer. */
#define BAUS_BACKWARD(PTR, BAU_OFFSET) \
AAUS_BACKWARD((PTR), (BAU_OFFSET) * ((U(size_aau)) HMM_BLOCK_ALIGN_UNIT))
typedef struct head_struct
{
/* Sizes in Block Alignment Units. */
HMM_UNIQUE(size_bau) previous_block_size, block_size;
}
head_record;
typedef struct ptr_struct
{
struct ptr_struct *self, *prev, *next;
}
ptr_record;
/* Divide and round up any fraction to the next whole number. */
#define DIV_ROUND_UP(NUMER, DENOM) (((NUMER) + (DENOM) - 1) / (DENOM))
/* Number of AAUs in a block head. */
#define HEAD_AAUS DIV_ROUND_UP(sizeof(head_record), HMM_ADDR_ALIGN_UNIT)
/* Number of AAUs in a block pointer record. */
#define PTR_RECORD_AAUS DIV_ROUND_UP(sizeof(ptr_record), HMM_ADDR_ALIGN_UNIT)
/* Number of BAUs in a dummy end record (at end of chunk). */
#define DUMMY_END_BLOCK_BAUS DIV_ROUND_UP(HEAD_AAUS, HMM_BLOCK_ALIGN_UNIT)
/* Minimum number of BAUs in a block (allowing room for the pointer record. */
#define MIN_BLOCK_BAUS \
DIV_ROUND_UP(HEAD_AAUS + PTR_RECORD_AAUS, HMM_BLOCK_ALIGN_UNIT)
/* Return number of BAUs in block (masking off high bit containing block
** status). */
#define BLOCK_BAUS(HEAD_PTR) \
(((head_record *) (HEAD_PTR))->block_size & ~HIGH_BIT_BAU_SIZE)
/* Return number of BAUs in previous block (masking off high bit containing
** block status). */
#define PREV_BLOCK_BAUS(HEAD_PTR) \
(((head_record *) (HEAD_PTR))->previous_block_size & ~HIGH_BIT_BAU_SIZE)
/* Set number of BAUs in previous block, preserving high bit containing
** block status. */
#define SET_PREV_BLOCK_BAUS(HEAD_PTR, N_BAUS) \
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
h_ptr->previous_block_size &= HIGH_BIT_BAU_SIZE; \
h_ptr->previous_block_size |= (N_BAUS); }
/* Convert pointer to pointer record of block to pointer to block's head
** record. */
#define PTR_REC_TO_HEAD(PTR_REC_PTR) \
((head_record *) AAUS_BACKWARD(PTR_REC_PTR, HEAD_AAUS))
/* Convert pointer to block head to pointer to block's pointer record. */
#define HEAD_TO_PTR_REC(HEAD_PTR) \
((ptr_record *) AAUS_FORWARD(HEAD_PTR, HEAD_AAUS))
/* Returns non-zero if block is allocated. */
#define IS_BLOCK_ALLOCATED(HEAD_PTR) \
(((((head_record *) (HEAD_PTR))->block_size | \
((head_record *) (HEAD_PTR))->previous_block_size) & \
HIGH_BIT_BAU_SIZE) == 0)
#define MARK_BLOCK_ALLOCATED(HEAD_PTR) \
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
h_ptr->block_size &= ~HIGH_BIT_BAU_SIZE; \
h_ptr->previous_block_size &= ~HIGH_BIT_BAU_SIZE; }
/* Mark a block as free when it is not the first block in a bin (and
** therefore not a node in the AVL tree). */
#define MARK_SUCCESSIVE_BLOCK_IN_FREE_BIN(HEAD_PTR) \
{ register head_record *h_ptr = (head_record *) (HEAD_PTR); \
h_ptr->block_size |= HIGH_BIT_BAU_SIZE; }
/* Prototypes for internal functions implemented in one file and called in
** another.
*/
void U(into_free_collection)(U(descriptor) *desc, head_record *head_ptr);
void U(out_of_free_collection)(U(descriptor) *desc, head_record *head_ptr);
void * U(alloc_from_bin)(
U(descriptor) *desc, ptr_record *bin_front_ptr, U(size_bau) n_baus);
#ifdef HMM_AUDIT_FAIL
/* Simply contains a reference to the HMM_AUDIT_FAIL macro and a
** dummy return. */
int U(audit_block_fail_dummy_return)(void);
/* More sickness needed because C has no inline function (yes, it's the
** "use the comma operator like a semicolon" thing.)
*/
/* Auditing a block consists of checking that the size in its head
** matches the previous block size in the head of the next block. */
#define AUDIT_BLOCK_AS_EXPR(HEAD_PTR) \
((BLOCK_BAUS(HEAD_PTR) == \
PREV_BLOCK_BAUS(BAUS_FORWARD(HEAD_PTR, BLOCK_BAUS(HEAD_PTR)))) ? \
0 : U(audit_block_fail_dummy_return)())
#define AUDIT_BLOCK(HEAD_PTR) \
{ void *h_ptr = (HEAD_PTR); AUDIT_BLOCK_AS_EXPR(h_ptr); }
#endif
/* Interface to AVL tree generic package instantiation. */
#define AVL_UNIQUE(BASE) U(avl_ ## BASE)
#define AVL_HANDLE ptr_record *
#define AVL_KEY U(size_bau)
#define AVL_MAX_DEPTH 64
#include "cavl_if.h"
#endif /* Include once. */

View file

@ -0,0 +1,561 @@
#define __ON2_MEM_C__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "on2_mem.h"
#define INCLUDE_MEMORY_MANAGER 0 //include heap manager functionality
#define INCLUDE_MEM_TRACKER 0 //include xon2_* calls in the lib
#define INCLUDE_MEM_CHECKS 1 //include some basic safety checks in
//on2_memcpy, _memset, and _memmove
#if INCLUDE_MEM_TRACKER
# include "on2_mem_tracker.h"
# if ON2_MEM_TRACKER_VERSION_CHIEF != 2
# error "on2_mem requires memory tracker version 2 to track memory usage"
# endif
#endif
#define ADDRESS_STORAGE_SIZE sizeof(size_t)
#if defined(VXWORKS)
# define DEFAULT_ALIGNMENT 32 //default addr alignment to use in
//calls to on2_* functions other
//than on2_memalign
#else
# define DEFAULT_ALIGNMENT 1
#endif
#if INCLUDE_MEM_TRACKER
# define TRY_BOUNDS_CHECK 1 //when set to 1 pads each allocation,
//integrity can be checked using
//on2_MemoryTrackerCheckIntegrity
//or on free by defining
//TRY_BOUNDS_CHECK_ON_FREE
#else
# define TRY_BOUNDS_CHECK 0
#endif
#if TRY_BOUNDS_CHECK
# define TRY_BOUNDS_CHECK_ON_FREE 0 //checks mem integrity on every
//free, very expensive
# define BOUNDS_CHECK_VALUE 0xdeadbeef //value stored before/after ea.
//mem addr for bounds checking
# define BOUNDS_CHECK_PAD_SIZE 32 //size of the padding before and
//after ea allocation to be filled
//with BOUNDS_CHECK_VALUE.
//this should be a multiple of 4
#else
# define BOUNDS_CHECK_VALUE 0
# define BOUNDS_CHECK_PAD_SIZE 0
#endif
unsigned long g_AllocCount = 0;
#if INCLUDE_MEMORY_MANAGER
# include "heapmm.h"
# include "hmm_intrnl.h"
# define SHIFT_HMM_ADDR_ALIGN_UNIT 5
# define TOTAL_MEMORY_TO_ALLOCATE 20971520 // 20 * 1024 * 1024
//# define TOTAL_MEMORY_TO_ALLOCATE 10485100 // 10 * 1024 * 1024
//# define TOTAL_MEMORY_TO_ALLOCATE 16777216 // 16 * 1024 * 1024
# define MM_DYNAMIC_MEMORY 1
# if MM_DYNAMIC_MEMORY
unsigned char* g_p_mng_memory_raw = NULL;
unsigned char* g_p_mng_memory = NULL;
# else
unsigned char g_p_mng_memory[TOTAL_MEMORY_TO_ALLOCATE];
# endif
size_t g_mm_memory_size = TOTAL_MEMORY_TO_ALLOCATE;
hmm_descriptor hmm_d;
int g_mngMemoryAllocated = 0;
static int On2_MM_CreateHeapMemory();
static void* On2_MM_realloc(void* memblk, size_t size);
#endif //INCLUDE_MEMORY_MANAGER
unsigned int on2_mem_get_version()
{
unsigned int ver = ((unsigned int)(unsigned char)ON2_MEM_VERSION_CHIEF << 24 |
(unsigned int)(unsigned char)ON2_MEM_VERSION_MAJOR << 16 |
(unsigned int)(unsigned char)ON2_MEM_VERSION_MINOR << 8 |
(unsigned int)(unsigned char)ON2_MEM_VERSION_PATCH);
return ver;
}
int on2_mem_set_heap_size(size_t size)
{
int ret = -1;
#if INCLUDE_MEMORY_MANAGER
#if MM_DYNAMIC_MEMORY
if(!g_mngMemoryAllocated && size) {
g_mm_memory_size = size;
ret = 0;
} else
ret = -3;
#else
ret = -2;
#endif
#else
(void)size;
#endif
return ret;
}
void* on2_memalign(size_t align, size_t size)
{
void* addr,
* x = NULL;
#if INCLUDE_MEMORY_MANAGER
int number_aau;
if (On2_MM_CreateHeapMemory() < 0)
{
printf("[on2][mm] ERROR xon2_memalign() Couldn't create memory for Heap.\n");
}
number_aau = ((size + align + ADDRESS_STORAGE_SIZE) >>
SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
addr = hmm_alloc(&hmm_d, number_aau);
#else
addr = malloc(size + align + ADDRESS_STORAGE_SIZE);
#endif //INCLUDE_MEMORY_MANAGER
if(addr) {
ptrdiff_t align_ = align;
x = (void*)(((size_t)
((unsigned char*)addr + ADDRESS_STORAGE_SIZE) + (align_ - 1)) & (size_t)-align_);
/* save the actual malloc address */
((size_t*)x)[-1] = (size_t)addr;
}
return x;
}
void* on2_malloc(size_t size)
{
return on2_memalign(DEFAULT_ALIGNMENT, size);
}
void* on2_calloc(size_t num, size_t size)
{
void *x;
x = on2_memalign(DEFAULT_ALIGNMENT, num*size);
if(x)
memset(x, 0, num*size);
return x;
}
void* on2_realloc(void* memblk, size_t size)
{
void* addr,
* new_addr = NULL;
int align = DEFAULT_ALIGNMENT;
/*
The realloc() function changes the size of the object pointed to by
ptr to the size specified by size, and returns a pointer to the
possibly moved block. The contents are unchanged up to the lesser
of the new and old sizes. If ptr is null, realloc() behaves like
malloc() for the specified size. If size is zero (0) and ptr is
not a null pointer, the object pointed to is freed.
*/
if(!memblk)
new_addr = on2_malloc(size);
else if (!size)
on2_free(memblk);
else
{
addr = (void*)(((size_t*)memblk)[-1]);
memblk = NULL;
#if INCLUDE_MEMORY_MANAGER
new_addr = On2_MM_realloc(addr, size + align + ADDRESS_STORAGE_SIZE);
#else
new_addr = realloc(addr, size + align + ADDRESS_STORAGE_SIZE);
#endif
if(new_addr) {
addr = new_addr;
new_addr = (void*)(((size_t)
((unsigned char*)new_addr + ADDRESS_STORAGE_SIZE) + (align - 1)) &
(size_t)-align);
/* save the actual malloc address */
((size_t*)new_addr)[-1] = (size_t)addr;
}
}
return new_addr;
}
void on2_free(void* memblk)
{
if(memblk) {
void* addr = (void*)(((size_t*)memblk)[-1]);
#if INCLUDE_MEMORY_MANAGER
hmm_free(&hmm_d, addr);
#else
free(addr);
#endif
}
}
#if INCLUDE_MEM_TRACKER
void* xon2_memalign(size_t align, size_t size, char* file, int line)
{
#if TRY_BOUNDS_CHECK
unsigned char *xBounds;
#endif
void *x;
if (g_AllocCount == 0)
{
int iRv = on2_MemoryTrackerInit(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE);
if (iRv < 0)
{
printf("ERROR xon2_malloc MEM_TRACK_USAGE error on2_MemoryTrackerInit().\n");
}
}
#if TRY_BOUNDS_CHECK
{
int i;
unsigned int tempme = BOUNDS_CHECK_VALUE;
xBounds = on2_memalign(align, size + (BOUNDS_CHECK_PAD_SIZE * 2));
for (i=0;i<BOUNDS_CHECK_PAD_SIZE;i+=sizeof(unsigned int))
{
memcpy(xBounds+i, &tempme, sizeof(unsigned int));
memcpy(xBounds + size + BOUNDS_CHECK_PAD_SIZE + i, &tempme, sizeof(unsigned int));
}
x = (void*)(xBounds + BOUNDS_CHECK_PAD_SIZE);
}
#else
x = on2_memalign(align, size);
#endif //TRY_BOUNDS_CHECK
g_AllocCount++;
on2_MemoryTrackerAdd((size_t)x, size, file, line);
return x;
}
void* xon2_malloc(size_t size, char *file, int line)
{
return xon2_memalign(DEFAULT_ALIGNMENT, size, file, line);
}
void* xon2_calloc(size_t num, size_t size, char *file, int line)
{
void* x = xon2_memalign(DEFAULT_ALIGNMENT, num*size, file, line);
if(x)
memset(x, 0, num*size);
return x;
}
void* xon2_realloc(void* memblk, size_t size, char *file, int line)
{
struct MemBlock* p = NULL;
int orig_size = 0,
orig_line = 0;
char* orig_file = NULL;
#if TRY_BOUNDS_CHECK
unsigned char *xBounds = memblk ?
(unsigned char*)memblk - BOUNDS_CHECK_PAD_SIZE :
NULL;
#endif
void *x;
if (g_AllocCount == 0)
{
if (!on2_MemoryTrackerInit(BOUNDS_CHECK_PAD_SIZE, BOUNDS_CHECK_VALUE))
{
printf("ERROR xon2_malloc MEM_TRACK_USAGE error on2_MemoryTrackerInit().\n");
}
}
if (p = on2_MemoryTrackerFind((size_t)memblk))
{
orig_size = p->size;
orig_file = p->file;
orig_line = p->line;
}
#if TRY_BOUNDS_CHECK_ON_FREE
on2_MemoryTrackerCheckIntegrity(file, line);
#endif
//have to do this regardless of success, because
//the memory that does get realloc'd may change
//the bounds values of this block
on2_MemoryTrackerRemove((size_t)memblk);
#if TRY_BOUNDS_CHECK
{
xBounds = on2_realloc(xBounds, size + (BOUNDS_CHECK_PAD_SIZE * 2));
if (xBounds)
{
int i;
unsigned int tempme = BOUNDS_CHECK_VALUE;
for (i=0;i<BOUNDS_CHECK_PAD_SIZE;i+=sizeof(unsigned int))
{
memcpy(xBounds+i, &tempme, 4);
memcpy(xBounds + size + BOUNDS_CHECK_PAD_SIZE + i, &tempme, 4);
}
x = (void*)(xBounds + BOUNDS_CHECK_PAD_SIZE);
}
else
x = NULL;
}
#else
x = on2_realloc(memblk, size);
#endif //TRY_BOUNDS_CHECK
if (x)
on2_MemoryTrackerAdd((size_t)x, size, file, line);
else
on2_MemoryTrackerAdd((size_t)memblk, orig_size, orig_file, orig_line);
return x;
}
void xon2_free(void *pAddress, char *file, int line)
{
#if TRY_BOUNDS_CHECK
unsigned char *pBoundsAddress = (unsigned char*)pAddress;
pBoundsAddress -= BOUNDS_CHECK_PAD_SIZE;
#endif
#if !TRY_BOUNDS_CHECK_ON_FREE
(void)file; (void)line;
#endif
if(pAddress)
{
g_AllocCount--;
#if TRY_BOUNDS_CHECK_ON_FREE
on2_MemoryTrackerCheckIntegrity(file, line);
#endif
//if the addr isn't found in the list, assume it was allocated via
//on2_ calls not xon2_, therefore it does not contain any padding
if (on2_MemoryTrackerRemove((size_t)pAddress) == -2)
pBoundsAddress = pAddress;
#if TRY_BOUNDS_CHECK
on2_free(pBoundsAddress);
#else
on2_free(pAddress);
#endif
}
}
#endif /*INCLUDE_MEM_TRACKER*/
#if INCLUDE_MEM_CHECKS
#if defined(VXWORKS)
/* This function is only used to get a stack trace of the player
object so we can se where we are having a problem. */
int getMyTT(int task)
{
tt(task);
return 0;
}
#endif
#endif
void * on2_memcpy(void *dest, const void *source, size_t length)
{
#if INCLUDE_MEM_CHECKS
if (((intptr_t)dest < 0x4000) || ((intptr_t)source < 0x4000))
{
printf("WARNING: on2_memcpy dest:0x%p source:0x%p len:%d\n", dest, source, length);
#if defined(VXWORKS)
sp(getMyTT, taskIdSelf(), 0, 0, 0, 0, 0, 0, 0, 0);
on2Timer_Sleep(10000);
#endif
}
#endif
return memcpy(dest, source, length);
}
void * on2_memset(void *dest, int val, size_t length)
{
#if INCLUDE_MEM_CHECKS
if ((intptr_t)dest < 0x4000)
{
printf("WARNING: on2_memset dest:0x%p val:%d len:%d\n", dest, val, length);
#if defined(VXWORKS)
sp(getMyTT, taskIdSelf(), 0, 0, 0, 0, 0, 0, 0, 0);
on2Timer_Sleep(10000);
#endif
}
#endif
return memset(dest, val, length);
}
void * on2_memmove(void *dest, const void *src, size_t count)
{
#if INCLUDE_MEM_CHECKS
if (((intptr_t)dest < 0x4000) || ((intptr_t)src < 0x4000))
{
printf("WARNING: on2_memmove dest:0x%p src:0x%p count:%d\n", dest, src, count);
#if defined(VXWORKS)
sp(getMyTT, taskIdSelf(), 0, 0, 0, 0, 0, 0, 0, 0);
on2Timer_Sleep(10000);
#endif
}
#endif
return memmove(dest, src, count);
}
#if INCLUDE_MEMORY_MANAGER
static int On2_MM_CreateHeapMemory()
{
int iRv = 0;
if (!g_mngMemoryAllocated)
{
#if MM_DYNAMIC_MEMORY
g_p_mng_memory_raw =
(unsigned char*)malloc(g_mm_memory_size + HMM_ADDR_ALIGN_UNIT);
if (g_p_mng_memory_raw)
{
g_p_mng_memory = (unsigned char*)((((unsigned int)g_p_mng_memory_raw) +
HMM_ADDR_ALIGN_UNIT-1) &
-(int)HMM_ADDR_ALIGN_UNIT);
printf("[on2][mm] total memory size:%d g_p_mng_memory_raw:0x%x g_p_mng_memory:0x%x\n"
, g_mm_memory_size + HMM_ADDR_ALIGN_UNIT
, (unsigned int)g_p_mng_memory_raw
, (unsigned int)g_p_mng_memory);
}
else
{
printf("[on2][mm] Couldn't allocate memory:%d for on2 memory manager.\n"
, g_mm_memory_size);
iRv = -1;
}
if (g_p_mng_memory)
#endif
{
int chunkSize = 0;
g_mngMemoryAllocated = 1;
hmm_init(&hmm_d);
chunkSize = g_mm_memory_size >> SHIFT_HMM_ADDR_ALIGN_UNIT;
chunkSize -= DUMMY_END_BLOCK_BAUS;
printf("[on2][mm] memory size:%d for on2 memory manager. g_p_mng_memory:0x%x chunkSize:%d\n"
, g_mm_memory_size
, (unsigned int)g_p_mng_memory
, chunkSize);
hmm_new_chunk(&hmm_d, (void*)g_p_mng_memory, chunkSize);
}
#if MM_DYNAMIC_MEMORY
else
{
printf("[on2][mm] Couldn't allocate memory:%d for on2 memory manager.\n"
, g_mm_memory_size);
iRv = -1;
}
#endif
}
return iRv;
}
static void* On2_MM_realloc(void* memblk, size_t size)
{
void* pRet = NULL;
if (On2_MM_CreateHeapMemory() < 0)
{
printf("[on2][mm] ERROR On2_MM_realloc() Couldn't create memory for Heap.\n");
}
else
{
int iRv = 0;
int old_num_aaus;
int new_num_aaus;
old_num_aaus = hmm_true_size(memblk);
new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
if (old_num_aaus == new_num_aaus)
{
pRet = memblk;
}
else
{
iRv = hmm_resize(&hmm_d, memblk, new_num_aaus);
if (iRv == 0)
{
pRet = memblk;
}
else
{
/* Error. Try to malloc and then copy data. */
void* pFromMalloc;
new_num_aaus = (size >> SHIFT_HMM_ADDR_ALIGN_UNIT) + 1;
pFromMalloc = hmm_alloc(&hmm_d, new_num_aaus);
if (pFromMalloc)
{
on2_memcpy(pFromMalloc, memblk, size);
hmm_free(&hmm_d, memblk);
pRet = pFromMalloc;
}
}
}
}
return pRet;
}
#endif //INCLUDE_MEMORY_MANAGER

View file

@ -0,0 +1,197 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
0CC4DD1E0BB7930400837D4E /* on2_mem.c in Sources */ = {isa = PBXBuildFile; fileRef = 0CC4DD1D0BB7930400837D4E /* on2_mem.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
0CC4DD1D0BB7930400837D4E /* on2_mem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = on2_mem.c; sourceTree = "<group>"; };
D2AAC046055464E500DB518D /* libon2_mem.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libon2_mem.a; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D289987405E68DCB004EDB86 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* on2_mem */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6A0FF2B0290797F04C91782 /* Documentation */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = on2_mem;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
0CC4DD1D0BB7930400837D4E /* on2_mem.c */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
D2AAC046055464E500DB518D /* libon2_mem.a */,
);
name = Products;
sourceTree = "<group>";
};
C6A0FF2B0290797F04C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
D2AAC043055464E500DB518D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
D2AAC045055464E500DB518D /* on2_mem */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "on2_mem" */;
buildPhases = (
D2AAC043055464E500DB518D /* Headers */,
D2AAC044055464E500DB518D /* Sources */,
D289987405E68DCB004EDB86 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = on2_mem;
productName = on2_mem;
productReference = D2AAC046055464E500DB518D /* libon2_mem.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "on2_mem" */;
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* on2_mem */;
projectDirPath = "";
targets = (
D2AAC045055464E500DB518D /* on2_mem */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
D2AAC044055464E500DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0CC4DD1E0BB7930400837D4E /* on2_mem.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB91EC08733DB70010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = on2_mem;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB91ED08733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = on2_mem;
};
name = Release;
};
1DEB91F008733DB70010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = build;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
SYMROOT = ../../../../lib/osx;
USER_HEADER_SEARCH_PATHS = include;
};
name = Debug;
};
1DEB91F108733DB70010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = build;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
SYMROOT = ../../../../lib/osx;
USER_HEADER_SEARCH_PATHS = include;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB91EB08733DB70010E9CD /* Build configuration list for PBXNativeTarget "on2_mem" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91EC08733DB70010E9CD /* Debug */,
1DEB91ED08733DB70010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "on2_mem" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB91F008733DB70010E9CD /* Debug */,
1DEB91F108733DB70010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View file

@ -0,0 +1,596 @@
#define __ON2_MEM_TRACKER_C__
/*
on2_mem_tracker.c
jwz 2003-09-30:
Stores a list of addreses, their size, and file and line they came from.
All exposed lib functions are prefaced by on2_ and allow the global list
to be thread safe.
Current supported platforms are:
Linux, Win32, WinCE and VxWorks
Further support can be added by defining the platform specific mutex
in the MemoryTracker struct as well as calls to create/destroy/lock/unlock
the mutex in on2_MemoryTrackerInit/Destroy and MemoryTrackerLockMutex/UnlockMutex
*/
#if defined(LINUX)
#include <pthread.h>
#elif defined(WIN32) || defined(_WIN32_WCE)
#include <windows.h>
#include <winbase.h>
#elif defined(VXWORKS)
#include <semLib.h>
#endif
#include "on2_mem_tracker.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //VXWORKS doesn't have a malloc/memory.h file,
//this should pull in malloc,free,etc.
#include <stdarg.h>
#undef on2_malloc //undefine any on2_mem macros that may affect calls to
#undef on2_free //memory functions in this file
#undef on2_memcpy
#undef on2_memset
struct MemoryTracker
{
struct MemBlock * head,
* tail;
int len,
totalsize;
unsigned int current_allocated,
max_allocated;
#if defined(LINUX)
pthread_mutex_t mutex;
#elif defined(WIN32) || defined(_WIN32_WCE)
HANDLE mutex;
#elif defined(VXWORKS)
SEM_ID mutex;
#else
#error "No mutex type defined for this platform!"
#endif
int padding_size,
pad_value;
};
/* prototypes for internal library functions */
static void memtrack_log(const char* fmt, ...);
static void MemoryTrackerDump();
static void MemoryTrackerCheckIntegrity(char* file, unsigned int line);
static void MemoryTrackerAdd(size_t addr, unsigned int size,
char* file, unsigned int line);
static int MemoryTrackerRemove(size_t addr);
static struct MemBlock* MemoryTrackerFind(size_t addr);
static int MemoryTrackerLockMutex();
static int MemoryTrackerUnlockMutex();
static struct MemoryTracker memtrack; //our global memory allocation list
static int g_bMemTrackerInited = 0; //indicates whether the global list has
//been initialized (1:yes/0:no)
static FILE* g_logfile = NULL;
static int g_logtype = 0;
/*
*
* Exposed library functions
*
*/
/*
on2_MemoryTrackerInit(int padding_size, int pad_value)
padding_size - the size of the padding before and after each mem addr.
Values > 0 indicate that integrity checks can be performed
by inspecting these areas.
pad_value - the initial value within the padding area before and after
each mem addr.
Initializes global memory tracker structure
Allocates the head of the list
*/
int on2_MemoryTrackerInit(int padding_size, int pad_value)
{
if (!g_bMemTrackerInited)
{
if (memtrack.head = (struct MemBlock*)malloc(sizeof(struct MemBlock)))
{
int ret;
memset(memtrack.head, 0, sizeof(struct MemBlock));
memtrack.tail = memtrack.head;
memtrack.current_allocated = 0;
memtrack.max_allocated = 0;
memtrack.padding_size = padding_size;
memtrack.pad_value = pad_value;
#if defined(LINUX)
ret = pthread_mutex_init(&memtrack.mutex,
NULL); /*mutex attributes (NULL=default)*/
#elif defined(WIN32) || defined(_WIN32_WCE)
memtrack.mutex = CreateMutex(NULL, /*security attributes*/
FALSE, /*we don't want initial ownership*/
NULL); /*mutex name*/
ret = !memtrack.mutex;
#elif defined(VXWORKS)
memtrack.mutex = semBCreate(SEM_Q_FIFO, /*SEM_Q_FIFO non-priority based mutex*/
SEM_FULL); /*SEM_FULL initial state is unlocked*/
ret = !memtrack.mutex;
#endif
if (ret)
{
memtrack_log("on2_MemoryTrackerInit: Error creating mutex!\n");
free(memtrack.head);
memtrack.head = NULL;
}
else
{
memtrack_log("Memory Tracker init'd, v."on2_mem_tracker_version"\n");
g_bMemTrackerInited = 1;
}
}
}
return g_bMemTrackerInited;
}
/*
on2_MemoryTrackerDestroy()
If our global struct was initialized zeros out all its members,
frees memory and destroys it's mutex
*/
void on2_MemoryTrackerDestroy()
{
if (!MemoryTrackerLockMutex())
{
struct MemBlock* p = memtrack.head,
* p2 = memtrack.head;
MemoryTrackerDump();
while(p)
{
p2 = p;
p = p->next;
free(p2);
}
memtrack.head = NULL;
memtrack.tail = NULL;
memtrack.len = 0;
memtrack.current_allocated = 0;
memtrack.max_allocated = 0;
if(!g_logtype && g_logfile && g_logfile != stderr) {
fclose(g_logfile);
g_logfile = NULL;
}
MemoryTrackerUnlockMutex();
g_bMemTrackerInited = 0;
}
}
/*
on2_MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line)
addr - memory address to be added to list
size - size of addr
file - the file addr was referenced from
line - the line in file addr was referenced from
Adds memory address addr, it's size, file and line it came from
to the global list via the thread safe internal library function
*/
void on2_MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line)
{
MemoryTrackerAdd(addr, size, file, line);
}
/*
on2_MemoryTrackerRemove(size_t addr)
addr - memory address to be removed from list
Removes addr from the global list via the thread safe
internal remove function
Return:
Same as described for MemoryTrackerRemove
*/
int on2_MemoryTrackerRemove(size_t addr)
{
return MemoryTrackerRemove(addr);
}
/*
on2_MemoryTrackerFind(size_t addr)
addr - address to be found in list
Return:
If found, pointer to the memory block that matches addr
NULL otherwise
*/
struct MemBlock* on2_MemoryTrackerFind(size_t addr)
{
struct MemBlock* p = NULL;
if (!MemoryTrackerLockMutex())
{
p = MemoryTrackerFind(addr);
MemoryTrackerUnlockMutex();
}
return p;
}
/*
on2_MemoryTrackerDump()
Locks the memory tracker's mutex and calls the internal
library function to dump the current contents of the
global memory allocation list
*/
void on2_MemoryTrackerDump()
{
if (!MemoryTrackerLockMutex())
{
MemoryTrackerDump();
MemoryTrackerUnlockMutex();
}
}
/*
on2_MemoryTrackerCheckIntegrity(char* file, unsigned int line)
file - The file name where the check was placed
line - The line in file where the check was placed
Locks the memory tracker's mutex and calls the internal
integrity check function to inspect every address in the global
memory allocation list
*/
void on2_MemoryTrackerCheckIntegrity(char* file, unsigned int line)
{
if (!MemoryTrackerLockMutex())
{
MemoryTrackerCheckIntegrity(file, line);
MemoryTrackerUnlockMutex();
}
}
/*
on2_MemoryTrackerSetLogType
Sets the logging type for the memory tracker. Based on the value it will
direct its output to the appropriate place.
Return:
0: on success
-1: if the logging type could not be set, because the value was invalid
or because a file could not be opened
*/
int on2_MemoryTrackerSetLogType(int type, char* option)
{
int ret = -1;
switch(type) {
case 0:
g_logtype = 0;
if(!option) {
g_logfile = stderr;
ret = 0;
} else {
if (g_logfile = fopen(option, "w"))
ret = 0;
}
break;
#if defined(WIN32) && !defined(_WIN32_WCE)
case 1:
g_logtype = type;
ret = 0;
break;
#endif
default:
break;
}
//output the version to the new logging destination
if(!ret)
memtrack_log("Memory Tracker init'd, v."on2_mem_tracker_version"\n");
return ret;
}
/*
*
* END - Exposed library functions
*
*/
/*
*
* Internal library functions
*
*/
static void memtrack_log(const char* fmt, ...)
{
va_list list;
va_start(list, fmt);
switch(g_logtype) {
case 0:
if (g_logfile) {
vfprintf(g_logfile, fmt, list);
fflush(g_logfile);
}
break;
#if defined(WIN32) && !defined(_WIN32_WCE)
case 1:
{
char temp[1024];
_vsnprintf(temp, sizeof(temp)/sizeof(char)-1, fmt, list);
OutputDebugString(temp);
}
break;
#endif
default:
break;
}
va_end(list);
}
/*
MemoryTrackerDump()
Dumps the current contents of the global memory allocation list
*/
static void MemoryTrackerDump()
{
int i = 0;
struct MemBlock* p = (memtrack.head ? memtrack.head->next : NULL);
memtrack_log("Currently Allocated= %d; Max allocated= %d\n",
memtrack.current_allocated, memtrack.max_allocated);
while(p)
{
memtrack_log("memblocks[%d].addr= 0x%.8x, memblocks[%d].size= %d, file: %s, line: %d\n", i,
p->addr, i, p->size,
p->file, p->line);
p = p->next;
++i;
}
}
/*
MemoryTrackerCheckIntegrity(char* file, unsigned int file)
file - the file name where the check was placed
line - the line in file where the check was placed
If a padding_size was supplied to on2_MemoryTrackerInit()
this function will ea. addr in the list verifying that
addr-padding_size and addr+padding_size is filled with pad_value
*/
static void MemoryTrackerCheckIntegrity(char* file, unsigned int line)
{
if (memtrack.padding_size)
{
int i,
index = 0;
unsigned int * pShowMe,
* pShowMe2;
unsigned int tempme = memtrack.pad_value,
dead1,
dead2;
unsigned char *xBounds;
struct MemBlock* p = memtrack.head->next;
while (p)
{
xBounds = (unsigned char*)p->addr;
//back up ON2_BYTE_ALIGNMENT
xBounds -= memtrack.padding_size;
for (i=0;i<memtrack.padding_size;i+=sizeof(unsigned int))
{
pShowMe = (unsigned int*)(xBounds+i);
pShowMe2 = (unsigned int*)(xBounds + p->size + memtrack.padding_size + i);
memcpy(&dead1, pShowMe, sizeof(unsigned int));
memcpy(&dead2, pShowMe2, sizeof(unsigned int));
if ((dead1 != tempme) || (dead2 != tempme))
{
memtrack_log("\n[on2_mem integrity check failed]:\n"
" index[%d] {%s:%d} addr=0x%x, size= %d,"
" file: %s, line: %d c0:0x%x c1:0x%x\n",
index, file, line, p->addr, p->size, p->file,
p->line, dead1, dead2);
}
}
++index;
p = p->next;
}
}
}
/*
MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line)
Adds an address (addr), it's size, file and line number to our list.
Adjusts the total bytes allocated and max bytes allocated if necessary.
If memory cannot be allocated the list will be destroyed.
*/
void MemoryTrackerAdd(size_t addr, unsigned int size,
char * file, unsigned int line)
{
if (!MemoryTrackerLockMutex())
{
struct MemBlock* p;
p = malloc(sizeof(struct MemBlock));
if (p)
{
p->prev = memtrack.tail;
p->prev->next = p;
p->addr = addr;
p->size = size;
p->line = line;
p->file = file;
p->next = NULL;
memtrack.tail = p;
memtrack.current_allocated += size;
if (memtrack.current_allocated > memtrack.max_allocated)
memtrack.max_allocated = memtrack.current_allocated;
MemoryTrackerUnlockMutex();
}
else
{
memtrack_log("MemoryTrackerAdd: error allocating memory!\n");
MemoryTrackerUnlockMutex();
on2_MemoryTrackerDestroy();
}
}
}
/*
MemoryTrackerRemove(size_t addr)
Removes an address and its corresponding size (if they exist)
from the memory tracker list and adjusts the current number
of bytes allocated.
Return:
0: on success
-1: if the mutex could not be locked
-2: if the addr was not found in the list
*/
int MemoryTrackerRemove(size_t addr)
{
int ret = -1;
if (!MemoryTrackerLockMutex())
{
struct MemBlock* p;
if (p = MemoryTrackerFind(addr))
{
memtrack.current_allocated -= p->size;
p->prev->next = p->next;
if (p->next)
p->next->prev = p->prev;
else
memtrack.tail = p->prev;
ret = 0;
free(p);
}
else
{
memtrack_log("MemoryTrackerRemove(): addr not found in list, 0x%.8x\n", addr);
ret = -2;
}
MemoryTrackerUnlockMutex();
}
return ret;
}
/*
MemoryTrackerFind(size_t addr)
Finds an address in our addrs list
NOTE: the mutex MUST be locked in the other internal
functions before calling this one. This avoids
the need for repeated locking and unlocking as in Remove
Returns: pointer to the mem block if found, NULL otherwise
*/
static struct MemBlock* MemoryTrackerFind(size_t addr)
{
struct MemBlock* p = NULL;
if (memtrack.head)
{
p = memtrack.head->next;
while(p && (p->addr != addr))
p = p->next;
}
return p;
}
/*
MemoryTrackerLockMutex()
Locks the memory tracker mutex with a platform specific call
Returns:
0: Success
<0: Failure, either the mutex was not initialized
or the call to lock the mutex failed
*/
static int MemoryTrackerLockMutex()
{
int ret = -1;
if (g_bMemTrackerInited)
{
#if defined(LINUX)
ret = pthread_mutex_lock(&memtrack.mutex);
#elif defined(WIN32) || defined(_WIN32_WCE)
ret = WaitForSingleObject(memtrack.mutex, INFINITE);
#elif defined(VXWORKS)
ret = semTake(memtrack.mutex, WAIT_FOREVER);
#endif
if (ret)
{
memtrack_log("MemoryTrackerLockMutex: mutex lock failed\n");
}
}
return ret;
}
/*
MemoryTrackerUnlockMutex()
Unlocks the memory tracker mutex with a platform specific call
Returns:
0: Success
<0: Failure, either the mutex was not initialized
or the call to unlock the mutex failed
*/
static int MemoryTrackerUnlockMutex()
{
int ret = -1;
if (g_bMemTrackerInited)
{
#if defined(LINUX)
ret = pthread_mutex_unlock(&memtrack.mutex);
#elif defined(WIN32) || defined(_WIN32_WCE)
ret = !ReleaseMutex(memtrack.mutex);
#elif defined(VXWORKS)
ret = semGive(memtrack.mutex);
#endif
if (ret)
{
memtrack_log("MemoryTrackerUnlockMutex: mutex unlock failed\n");
}
}
return ret;
}

View file

@ -0,0 +1,410 @@
#include "circlebuffer.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* memory copy */
#include "duck_mem.h"
/* this is just a debugging trick so that we can "see" the free space */
void* circleread_memcpy(void* dst, void* src, int64_t count);
void* circleread_memcpy(void* dst, void* src, int64_t count)
{
return duck_memcpy64(dst, src, count);
}
void CircleReport(const CircleBuffer_t* cb, const char* title)
{
printf("-----(%s)------\n", title);
printf("max Size cb = %ld\n", cb->bufSize);
printf("fills at = %ld\n", cb->bufSize * cb->percent / 100 );
printf("Current amount = %ld, level = %ld\n", cb->count, cb->count * 100 / cb->bufSize);
}
int ForwardBuffer(CircleBuffer_t* cb, int64_t len)
{
if (len >= (int64_t)cb->count)
return -1;
if ( (cb->head + len) < cb->bufSize )
cb->head += (int)len;
else
cb->head = (int)len - (cb->bufSize - cb->head);
cb->count -= (int)len;
return 0;
}
int RewindBuffer(CircleBuffer_t* cb, int64_t len)
{
if (len >= (int64_t)(cb->bufSize - cb->count) )
return -1; /* not enough history in buffer ! */
if (cb->head <= (size_t)len)
{
if (cb->wrapped == 0)
return -1;
cb->head = cb->bufSize - ((int)len - cb->head);
cb->count += (int)len;
return 0;
}
else
{
cb->head -= (int)len;
cb->count += (int)len;
}
return 0;
}
void destroyCircleBuffer(CircleBuffer_t* cb)
{
assert(cb);
if (cb->buffer)
free(cb->buffer);
if (cb->maxChunk)
free(cb->maxChunk);
}
int resetCircleBuffer(CircleBuffer_t* cb)
{
cb->count = 0;
cb->bytesConsumed = 0;
cb->wrapped = 0;
cb->starvedBytes = 0;
cb->starvedRequests = 0;
return 0;
}
int initCircleBuffer(
CircleBuffer_t* cb,
size_t countRecords,
int percent,
size_t maxChunk,
FuncLock_t lock,
FuncLock_t unlock
)
{
assert(cb);
cb->buffer = (unsigned char * ) calloc(1, countRecords);
cb->maxChunk = (unsigned char *) calloc(1, maxChunk);
cb->maxChunkLen = maxChunk;
if (cb->buffer)
{
cb->head = cb->count = 0;
cb->balance = 0;
cb->bufSize = countRecords;
cb->bytesConsumed = 0;
cb->muted = false;
cb->percent = percent;
cb->wrapped = 0;
cb->lock = lock;
cb->unlock = unlock;
return 0;
}
else
{
return -1; /* error */
}
}
/* return zero if plenty of room and success */
/*-------------------------------------------*/
/* free space nested in the middle of the buffer is consider endSpace */
/* and when free space nested in middle, startSpace is considered to be zero */
/*---------------------------------------------------------------------------*/
int addToCircleBuffer(CircleBuffer_t* cb, void* data, size_t requestSpace)
{
int64_t freeSpace; /* count total free space in buffer */
int64_t head = cb->head; /* offset start of valid data */
int64_t tail = (cb->head + cb->count) % cb->bufSize; /* offest first free byte after valid data */
int64_t endSpace;
freeSpace = cb->bufSize - cb->count;
/* if not enough room to do the add */
/*----------------------------------*/
if (requestSpace > freeSpace)
{
assert(0);
return CB_FULL;
}
endSpace = cb->bufSize - tail;
if (tail >= head && requestSpace > endSpace) /* additional data write will wrap */
{
duck_memcpy64(&cb->buffer[tail], data, endSpace);
duck_memcpy64(
cb->buffer,
(unsigned char *)data+endSpace,
requestSpace - endSpace);
}
else /* existing data wrapped around from end of buffer through beginning of buffer. */
{
memcpy(&cb->buffer[tail], data, requestSpace);
}
cb->count += requestSpace;
cb->balance += 1;
return 0; /* -1 will mean error,m zero is OK */
}
/* get info need so we can write direct as in memcpy into the circle buffer */
/*--------------------------------------------------------------------------*/
void FreeWrapless(const CircleBuffer_t* cb, void* handle, int64_t* sizeWrapless)
{
int64_t tail = (cb->head + cb->count) % cb->bufSize;
if ((cb->head + cb->count) < cb->bufSize)
{
*((void **) handle) = &cb->buffer[tail];
*sizeWrapless = (cb->bufSize -(cb->head + cb->count));
}
else
{
*((void **) handle) = &cb->buffer[tail];
*sizeWrapless = (cb->bufSize - cb->count);
}
}
/* Please clone this sucker from readFromCircleBuffer */
int accessCircleBuffer(CircleBuffer_t* cb, void* handle1, size_t requestSize)
{
int64_t head = cb->head;
int64_t tail = (cb->head + cb->count) % cb->bufSize;
void** handle = (void **) handle1;
void* dest = *handle;
if (requestSize <= 0)
{
return requestSize;
}
if (cb->count < requestSize)
{
return -1;
}
if (tail > head) /* the data does not wrap ! */
{
*handle = &cb->buffer[head];
}
else /* the current data does wrap */
{
/* but our read does not wrap */
if (head + requestSize < cb->bufSize)
{
*handle = &cb->buffer[head];
}
else if (head + requestSize == cb->bufSize)
{
*handle = &cb->buffer[head];
}
else /* our read will wrap ! */
{
int64_t temp = cb->bufSize - head;
dest = cb->maxChunk;
assert(cb->maxChunkLen >= requestSize);
circleread_memcpy(
dest,
&cb->buffer[head],
temp);
circleread_memcpy(
((unsigned char *) dest) + temp,
cb->buffer,
requestSize - temp);
*handle = dest;
}
}
cb->head = (cb->head + requestSize) % cb->bufSize;
cb->count -= requestSize;
cb->bytesConsumed += requestSize;
cb->balance -= 1;
return requestSize; /* records (16 bit or maybe other in future) */
}
/* return count read , or -1 if not enough data */
/*----------------------------------------------*/
int readFromCircleBuffer(CircleBuffer_t* cb, void* dest, size_t requestSize)
{
int64_t head = cb->head;
int64_t tail = (cb->head + cb->count) % cb->bufSize;
if (cb->count < requestSize)
{
requestSize = cb->count; /* Give them what we have */
}
if (requestSize <= 0)
{
return (int)requestSize;
}
if (tail > head) /* the data does not wrap ! */
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
}
else /* the current data does wrap */
{
/* but our read does not wrap */
if (head + requestSize < cb->bufSize)
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
}
else if (head + requestSize == cb->bufSize)
{
circleread_memcpy(dest, &cb->buffer[head], requestSize);
memset(&cb->buffer[head], 0, (size_t)requestSize); /* optional, debug */
}
else /* our read will wrap ! */
{
int64_t temp = cb->bufSize - head;
circleread_memcpy(
dest,
&cb->buffer[head],
temp);
circleread_memcpy(
((unsigned char *) dest) + temp,
cb->buffer,
requestSize - temp);
}
}
cb->head = (cb->head + requestSize) % cb->bufSize;
cb->count -= requestSize;
cb->bytesConsumed += requestSize;
cb->balance -= 1;
return (int)requestSize; /* records (16 bit or maybe other in future) */
}
void testCircleBuffer()
{
CircleBuffer_t temp;
size_t bufSize = 256;
const size_t maxInput = 256*3;
size_t count = 0;
size_t t;
int i;
const int maxRandom = 32;
size_t chunkOut = 30;
CircleRecord_t data[256*3];
initCircleBuffer(&temp, bufSize, 75, 256, 0, 0);
/* who cares ... take the default seed value. */
while (count < maxInput || temp.count > chunkOut)
{
t = rand();
/* for whatever reason this seems to be a 16 bit random number */
t = t / ( 2 << (16 - 7) ) ;
for(i = 0; i < (int)t; i++)
{
data[i] = (unsigned char ) ( count + i );
}
if (
((temp.bufSize - temp.count) >= t*sizeof(short)+1) &&
(count < (maxInput - maxRandom))
) /* add 1 to keep buffer being completely filled */
{
int64_t tail = (temp.head + temp.count) % temp.bufSize;
addToCircleBuffer(&temp, data, t);
printf("Add to buffer count = %ld. head = %ld, tail = %ld\n", t, temp.head, tail);
count += t;
}
else /* not enough space in buffer, try to empty some out */
{
int r;
r = readFromCircleBuffer(&temp, data, chunkOut);
if (r >= 0)
{
int64_t tail = (temp.head + temp.count) % temp.bufSize;
for(i = 0; i < r; i++)
printf("%ld ", data[i]);
printf("\nRead from buffer. head = %ld, tail = %ld\n", temp.head, tail);
}
}
} /* while we have not accumulated a large eough test ... */
}
int CirclePercent(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize);
}
int CircleAtLevel(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize) >= cb->percent;
}
int CircleOverLevel(CircleBuffer_t* cb)
{
return (int)(cb->count * 100 / cb->bufSize) > cb->percent;
}

View file

@ -0,0 +1,99 @@
#if !defined(_circlebuffer_h)
#define _circlebuffer_h
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(_WIN32)
typedef __int64 int64_t;
#elif defined(__POWERPC) || defined(__APPLE)
#include <ppc/types.h>
#else
typedef long long int64_t;
#endif
#if !defined(_WIN32)
#pragma bool on
#endif
typedef unsigned char CircleRecord_t;
typedef void (*FuncLock_t)() ;
/* assume that assert, alerts, messages to go off before this ever is allowed to fill */
/*------------------------------------------------------------------------------------*/
typedef struct CircleBuf_tt
{
size_t head; /* points to start of usable data in buffer */
size_t count;
size_t bufSize;
int64_t bytesConsumed;
size_t recordSize;
size_t userData; /* might store actual recordsize */
int balance;
CircleRecord_t* buffer; /* 10 seconds of 16 bit stereo nice quality */
unsigned char* maxChunk;
size_t maxChunkLen;
int percent; /* level where buffer considered stable */
int wrapped; /* non-zero if data has wrapped at least once */
int muted;
FuncLock_t lock; /* in case there could be competition for any members */
FuncLock_t unlock; /* in case there could be competition for any members */
int starvedBytes; /* how many bytes we had to "conjure up" because we were empty (debug) */
int starvedRequests; /* how many request we honored when we have been in a starved state (debug) */
} CircleBuffer_t;
void testCircleBuffer(void);
void destroyCircleBuffer(CircleBuffer_t* cb);
int initCircleBuffer(CircleBuffer_t* cb, size_t size, int percent, size_t maxChunk, FuncLock_t lock, FuncLock_t unlock);
int addToCircleBuffer(CircleBuffer_t* cb, void* data, size_t count);
int readFromCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
int accessCircleBuffer(CircleBuffer_t* cb, void* dest, size_t count);
void FreeWrapless(const CircleBuffer_t* cb, void* handle, size_t* sizeWrapless);
int resetCircleBuffer(CircleBuffer_t* cb);
int RewindBuffer(CircleBuffer_t* cb, int64_t len);
int ForwardBuffer(CircleBuffer_t* cb, int64_t len);
void CircleReport(const CircleBuffer_t* cb, const char* title);
int CirclePercent(CircleBuffer_t* cb);
int CircleAtLevel(CircleBuffer_t* cb);
int CircleOverLevel(CircleBuffer_t* cb);
typedef enum {
CB_NOERR = 0, /* OK */
CB_FULL = -1, /* Buffer overflow */
CB_MAX_LEVEL = -2, /* Buffer is over target full level (percent) */
CB_MIN_LEVEL = -3, /* Buffer is under target min level (percent) */
CB_EMPTY = -4 /* Buffer is empty */
} CB_Err_t;
#if defined(__cplusplus)
}
#endif
#endif

View file

@ -0,0 +1,130 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include "duck_io.h"
#include "duck_io_http.h"
#include "duck_io_file.h"
#include "duck_hfb.h"
#include <assert.h>
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
int duck_readFinished(int han, int flag)
{
(void)han;
(void)flag;
return 1;
}
bool g_isHttp = false;
int duck_open(const char *name, unsigned long userData)
{
if (strstr(name, "http://"))
return duck_open_http(name, userData);
else
return duck_open_file(name, userData);
}
void duck_close(int handle)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
duck_close_http(handle);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
duck_close_file(handle);
else
assert(0);
}
int duck_read(int handle,unsigned char *buffer,int bytes)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_read_http(handle, buffer, bytes);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_read_file(handle, buffer, bytes);
else
{
assert(0);
return -1;
}
}
int duck_read_blocking(int handle,unsigned char *buffer,int bytes)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_read_blocking_http(handle, buffer, bytes);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_read_file(handle, buffer, bytes);
else
{
assert(0);
return -1;
}
}
int64_t duck_seek(int handle,int64_t offset,int origin)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_seek_http(handle, offset, origin);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_seek_file(handle, offset, origin);
else
{
assert(0);
return -1;
}
}
int duck_name(int handle, char name[], size_t maxLen)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_name_http(handle, name, maxLen);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_name_file(handle, name, maxLen);
else
{
assert(0);
return -1;
}
}
int64_t duck_available_data(int handle)
{
unsigned long schemeCC = *((unsigned long *) handle);
if (schemeCC == MAKE_FOUR_CC('h','t','t','p'))
return duck_available_data_http(handle);
else if (schemeCC == MAKE_FOUR_CC('f','i','l','e'))
return duck_available_data_file(handle);
else
{
assert(0);
return -1;
}
}

View file

@ -0,0 +1,224 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#if defined(_WIN32)
#include <io.h>
#endif
#include "duck_io_file.h"
#include "duck_hfb.h"
#include "duck_io.h"
#include "duck_mem.h"
#include <assert.h>
#if defined (__cplusplus)
extern "C" {
#endif
#if defined (__cplusplus)
}
#endif
//int read_count;
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
typedef struct
{
unsigned long scheme; /* contains FILE */
#if defined(_WIN32)
int fileDescriptor; /* used to be the handle */
#else
FILE* fileDescriptor; /* used to be the handle */
#endif
char fname[512];
int64_t fileLength;
char errorString[256];
SAL_ERR lastErrorCode;
} FileScheme_t;
/* Add the decoration to avoid name collisions in the case where we want to include */
/* a forking version of duck_io that calls duck_io_file or duck_io_http */
/* The user of this service should not need to compile and link all three files */
/* duck_io (abstract forker) duck_io_file and duck_io_http. */
#define DECORATE(x) x##_file
/* Sets an error code and message */
static int SetError(int handle, SAL_ERR code, const char* appendMsg)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
const char* decode = SalErrText(code);
if (decode)
{
strcpy(fileObj->errorString, decode);
fileObj->lastErrorCode = code;
if (appendMsg)
{
strcat(fileObj->errorString, " : ");
strcat(fileObj->errorString, appendMsg);
}
return code;
}
return SAL_ERROR; // DEFAULT ERROR
}
int DECORATE(duck_open)(const char *name, unsigned long userData)
{
FileScheme_t* const fileObj = (FileScheme_t *) duck_calloc(1,sizeof(FileScheme_t), DMEM_GENERAL);
const ReOpen_t* const openData = (ReOpen_t*) userData;
fileObj->scheme = MAKE_FOUR_CC('f','i','l','e');
assert(name);
assert(strlen(name) < sizeof(fileObj->fname));
strcpy(fileObj->fname,name);
#if defined(_WIN32)
fileObj->fileDescriptor = _open(name, _O_RDONLY | _O_BINARY);
if(fileObj->fileDescriptor == -1)
return SetError((int)fileObj, SAL_ERR_FILE_OPEN_FAILED, 0);
#else
fileObj->fileDescriptor = fopen(name, "rb");
if(fileObj->fileDescriptor == 0)
return SetError((int)fileObj, SAL_ERR_FILE_OPEN_FAILED, 0);;
#endif
fileObj->fileLength = duck_seek((int) fileObj, 0, SEEK_END);
duck_seek((int) fileObj, 0, SEEK_SET);
if(openData)
duck_seek_file((int) fileObj, openData->offset, SEEK_SET);
return (int)fileObj;
}
void DECORATE(duck_close)(int handle)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
#if defined(_WIN32)
_close(fileObj->fileDescriptor);
#else
fclose(fileObj->fileDescriptor);
#endif
if (fileObj)
{
duck_free(fileObj);
fileObj = 0;
}
}
int DECORATE(duck_read_blocking)(int handle,unsigned char *buffer,int bytes)
{
return DECORATE(duck_read)(handle, buffer, bytes);
}
int DECORATE(duck_read)(int handle,unsigned char *buffer,int bytes)
{
int x;
FileScheme_t* fileObj = (FileScheme_t *) handle;
if (buffer == NULL){
duck_seek_file((int ) fileObj->fileDescriptor,bytes,SEEK_CUR);
return bytes;
}
if (bytes == 0)
return 0;
#if defined(_WIN32)
x = _read(fileObj->fileDescriptor, buffer, (unsigned int) bytes);
if (x == -1L)
{
assert(0);
}
#else
x = fread(buffer, sizeof(char) , (size_t) bytes, fileObj->fileDescriptor);
if (x < bytes)
{
assert(x == bytes);
}
#endif
return x ;
}
int64_t DECORATE(duck_seek)(int handle, int64_t offset, int origin)
{
#if defined(_WIN32)
int64_t tellNo = 0;
FileScheme_t* fileObj = (FileScheme_t *) handle;
_lseeki64(fileObj->fileDescriptor,offset,origin);
tellNo = _telli64(fileObj->fileDescriptor);
return tellNo ;
#else
int64_t tellNo = 0;
FileScheme_t* fileObj = 0;
assert(sizeof(off_t) == sizeof(int64_t));
fileObj = (FileScheme_t *) handle;
fseeko(fileObj->fileDescriptor,(off_t) offset,origin);
tellNo = (int64_t) ftello(fileObj->fileDescriptor);
return tellNo ;
#endif
}
int DECORATE(duck_name)(int handle, char fname[], size_t maxLen)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
if (strlen(fileObj->fname) < maxLen)
strcpy(fname, fileObj->fname);
else
return -1;
return 0;
}
int64_t DECORATE(duck_available_data)(int handle)
{
FileScheme_t* fileObj = (FileScheme_t *) handle;
#if defined(_WIN32)
return fileObj->fileLength - _telli64(fileObj->fileDescriptor);
#else
return fileObj->fileLength - (int64_t) ftello(fileObj->fileDescriptor);
#endif
}

View file

@ -0,0 +1,902 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#ifdef _WIN32
#pragma warning(push,3)
#endif
#include "duck_io_http.h"
#include "duck_mem.h"
#include "on2_timer.h"
#include "circlebuffer.h"
#include "duck_io.h"
#include <errno.h>
#ifdef _WIN32
#include <winsock2.h>
#else
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
extern "C" {
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
}
#endif
#include <sstream>
#include <limits.h>
#define DEFAULT_CBSIZE 512 * 1024
#define DECORATE(x) x##_http
int duck_sal_fill(void * handle, bool blocking, size_t maxFill);
//#include "debug.h" // This can be removed
#ifdef _WIN32
#pragma warning(pop)
#pragma warning(disable:4706) /* assignment in conditional expression */
#pragma warning(disable:4514) /* matt made me do it */
const char i64Fmt[] = "%I64d";
#else
const char i64Fmt[] = "%lld";
int WSAGetLastError()
{
return -1;
}
#endif
#define MAKE_FOUR_CC(b1, b2, b3, b4 ) \
((b4 << 24) | (b3 << 16) | (b2 << 8) | (b1 << 0))
typedef struct _DuckHttp_temp
{
unsigned long scheme;
std::string url;
std::string urlExtended;
#if defined(_WIN32)
SOCKET socket;
#else
int socket;
#endif
SAL_ERR lastErrorCode;
std::ostringstream errorString;
/* milliseconds to wait before disconnecting from server */
unsigned int timeOut;
/* Assuming 2k is the max size of an http header */
char httpHeader[2 * 1024];
int64_t contentLen; // Size of the movie
int headerSize; // Size of the http header
int xtraData; // Amout of movie data recv'd from the http header recv
int64_t totalRead; // Position in file
CircleBuffer_t cBuffer;
int cbSize; // Circular buffer size
} DuckHttp_t;
/* Returns size of movie as parsed from the http header */
int64_t duck_content_len(void* handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
if (httpObj == 0)
return -1;
return httpObj->contentLen;
}
void* duck_get_buffer(void *handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return (void *) &httpObj->cBuffer;
}
/* Checks to see if any errors occured in recv */
int isDataAvailable(int bytesReceived)
{
(void ) bytesReceived; // for warning supression
#ifdef WIN32
if (WSAGetLastError() == 10035) // No data is available right now, try again later
return 0;
#else
int x = errno;
if(x == EAGAIN)
{
return 0;
}
else if (x == 0)
{
assert(bytesReceived != -1);
return 1;
}
else
{
assert(0);
}
#endif
return 1;
}
/* Sets an error code and message */
static int SetError(DuckHttp_t* httpObj, SAL_ERR code, const char* appendMsg)
{
const char* decode = SalErrText(code);
if (decode)
{
httpObj->errorString.str("");
httpObj->errorString << decode;
httpObj->lastErrorCode = code;
if (appendMsg)
httpObj->errorString << " : " << appendMsg;
return code;
}
return SAL_ERROR; // Default error
}
static int64_t http_atoi(const char* str)
{
int64_t temp = 0;
size_t len = 0;
while(str[len] >= '0' && str[len] <= '9')
len++;
for(size_t i = 0; i < len; i++)
temp = temp * 10 + (str[i] - '0');
return temp;
}
/* Parses url for a parameter */
inline bool get_url_parameter(const std::string url, std::string& parameter)
{
std::string temp = url;
size_t strPos;
strPos = temp.find(parameter.c_str());
if (strPos == std::string::npos)
{
return false;
}
else
{
temp = temp.substr(strPos + parameter.length() + 1);
size_t i = 0;
for(i = 0; i < temp.length(); i++)
{
if (temp[i] == '&')
temp[i] = '\0';
}
parameter = temp.c_str();
return true;
}
}
#if !defined(__cplusplus)
#error
#endif
char* duck_init_http(char *url)
{
std::string strTime = "timeout";
std::string strBuff = "buffer";
DuckHttp_t* httpObj = new (DuckHttp_t);
assert(httpObj);
httpObj->scheme = MAKE_FOUR_CC('h','t','t','p');
httpObj->urlExtended = url;
if (get_url_parameter(url, strTime))
sscanf(strTime.c_str(),"%d", &httpObj->timeOut);
else
httpObj->timeOut = INT_MAX; // Wait "forever" is default
if (get_url_parameter(url, strBuff))
{
sscanf(strBuff.c_str(), "%d", &httpObj->cbSize);
// Convert kilobytes into bytes
httpObj->cbSize *= 1024;
}
else
httpObj->cbSize = DEFAULT_CBSIZE;
for(size_t i = 0; i < strlen(url); i++)
{
if (url[i] == '?')
url[i] = '\0';
}
httpObj->url = url;
httpObj->contentLen = 0;
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2), &wsaData))
{
std::ostringstream temp;
temp << " : " << WSAGetLastError();
SetError(httpObj,SAL_ERR_WSASTARTUP,temp.str().c_str());
return 0;
}
#endif
return (char *) httpObj;
}
/* Might need to reduce timeout after initial buffering */
/*------------------------------------------------------*/
void duck_http_timeout(int handle, unsigned long milliseconds)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
httpObj->timeOut = milliseconds;
}
int DECORATE(duck_open)(const char* src, unsigned long userData)
{
struct sockaddr_in sa_in;
struct sockaddr* const psa = (struct sockaddr*)&sa_in;
struct hostent* host;
std::ostringstream buf1;
unsigned short port = 0;
int input;
char* endOfHttpHeader = "\r\n\r\n";
char* strContentLen = "Content-Length: ";
char* strPos;
on2Timer start;
(void) userData;
unsigned long block = 1;
DuckHttp_t* httpObj;
ReOpen_t* reOpenData = (ReOpen_t*) userData;
if(reOpenData == 0 || reOpenData->blocking || reOpenData->offset == 0)
httpObj = (DuckHttp_t *) duck_init_http((char *) src);
else
httpObj = (DuckHttp_t *) src;
if(!reOpenData) // if we're not doing a re-open
httpObj->totalRead = 0;
else
httpObj->totalRead = reOpenData->offset;
std::stringbuf path;
std::stringbuf server;
std::istringstream is(httpObj->url);
is.ignore(strlen("http://"), '\0');
// Check if a port is specified
for(size_t i = strlen("http://"); i < httpObj->url.length(); i++)
{
if(httpObj->url[i] == ':')
{
port = 1;
break;
} else if(httpObj->url[i] == '/') break;
}
if(port)
{
std::stringbuf strPort;
is.get(server,':');/* get the server */
is.ignore(1, '\0');
is.get(strPort, '/');
port = (unsigned short)http_atoi(strPort.str().c_str());
}
else
{
is.get(server,'/');/* get the server */
port = 80; // default http port
}
assert(server.str().length() > 0);
is.ignore(1, '\0'); /* get the path */
is.get(path, '\0');
/* Wrap up the send message */
buf1 << "GET " << "/" << path.str() << " HTTP/1.1 " << "\r\n";
buf1 << "Host:" << server.str().c_str() << "\r\n" ;
if (reOpenData)
{
char number[64];
sprintf(number, i64Fmt, reOpenData->offset);
buf1 << "Range: bytes=" << number << "-" ;
buf1 << " \r\n" ;
}
buf1 << "\r\n";
if ((httpObj->socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
fprintf(stderr, "duck_open: SAL_ERR_SOCKET_CREATE\n");
SetError(httpObj,SAL_ERR_SOCKET_CREATE, 0);
duck_exit_http((int)httpObj);
return SAL_ERR_SOCKET_CREATE;
}
sa_in.sin_family = AF_INET;
sa_in.sin_port = htons(port);
if (!(host = gethostbyname(server.str().c_str())))
{
fprintf(stderr, "duck_open: SAL_ERR_RESOLVING_HOSTNAME\n");
SetError(httpObj,SAL_ERR_RESOLVING_HOSTNAME,0);
duck_exit_http((int)httpObj);
return SAL_ERR_RESOLVING_HOSTNAME;
}
duck_memcpy(&sa_in.sin_addr, host->h_addr_list[0], sizeof(struct in_addr));
if (connect(httpObj->socket, psa, sizeof(sa_in) ) != 0)
{
fprintf(stderr, "duck_open: SAL_ERR_SERVER_CONNECTION\n");
SetError(httpObj,SAL_ERR_SERVER_CONNECTION,0);
duck_exit_http((int)httpObj);
return SAL_ERR_SERVER_CONNECTION;
}
/* connected */
if (send(httpObj->socket, buf1.str().c_str(), strlen(buf1.str().c_str()), 0) < 0)
{
fprintf(stderr, "duck_open: SAL_ERR_SENDING_DATA\n");
SetError(httpObj,SAL_ERR_SENDING_DATA,0);
duck_exit_http((int)httpObj);
return SAL_ERR_SENDING_DATA;
}
on2Timer_Init(&start);
on2Timer_Start(&start);
duck_memset(httpObj->httpHeader, 0, sizeof(httpObj->httpHeader));
/* Get the HTTP header EMH 2-14-03 */
/* Assuming we get all the header info in the 1st good recv */
do
{
unsigned long delta = on2Timer_GetCurrentElapsedMilli(&start);
if (delta > httpObj->timeOut)
{
return SetError(httpObj,SAL_ERR_CONNECTION_TIMEOUT,0);
}
input = recv(httpObj->socket, httpObj->httpHeader, sizeof(httpObj->httpHeader), 0);
} while (!strstr(httpObj->httpHeader, endOfHttpHeader));
#ifdef _WIN32
ioctlsocket(httpObj->socket, FIONBIO, &block); /* Set the socket to non-blocking */
#else
if (ioctl(httpObj->socket, FIONBIO, &block)) /* Set the socket to non-blocking */
{
assert(0);
}
#endif
strPos = strstr(httpObj->httpHeader, endOfHttpHeader);
strPos += strlen(endOfHttpHeader);
httpObj->headerSize = (int)strPos - (int)httpObj->httpHeader;
httpObj->xtraData = input - httpObj->headerSize; // Amount of GOOD data grabbed with the HTTP header
if (strstr(httpObj->httpHeader, "404") && strstr(httpObj->httpHeader, "Not Found"))
{
fprintf(stderr, "duck_open: SAL_ERR_404_FILE_NOT_FOUND\n");
SetError(httpObj,SAL_ERR_404_FILE_NOT_FOUND,0);
duck_exit_http((int)httpObj);
return SAL_ERR_404_FILE_NOT_FOUND;
}
strPos = strstr(httpObj->httpHeader, strContentLen);
if (!strPos)
{
fprintf(stderr, "duck_open: SAL_ERR_PARSING_HTTP_HEADER\n");
SetError(httpObj,SAL_ERR_PARSING_HTTP_HEADER,0);
duck_exit_http((int)httpObj);
return SAL_ERR_PARSING_HTTP_HEADER;
}
strPos += strlen(strContentLen);
if((*strPos >= '0') && (*strPos <= '9'))
{
httpObj->contentLen = http_atoi(strPos);
}
else
{
fprintf(stderr, "duck_open: SAL_ERR_PARSING_CONTENT_LEN\n");
SetError(httpObj,SAL_ERR_PARSING_CONTENT_LEN,0);
duck_exit_http((int)httpObj);
return SAL_ERR_PARSING_CONTENT_LEN;
}
int rv;
rv = initCircleBuffer(&httpObj->cBuffer, httpObj->cbSize, 75,
httpObj->cbSize/4, /* max chunk */ 0, 0);
if (rv < 0)
assert(0);
addToCircleBuffer(&httpObj->cBuffer,
httpObj->httpHeader + httpObj->headerSize,
(size_t) httpObj->xtraData);
bool blocking = true;
/*
// Block only if we're not doing a re-open
userData ? blocking = false : blocking = true;
*/
if(reOpenData)
blocking = (reOpenData->blocking != 0);
if (duck_sal_fill((void *) httpObj, blocking, 0) < 0)
{
fprintf(stderr, "duck_open: SAL_ERR_RECEIVING_DATA\n");
duck_close_http((int)httpObj);
return -1;
}
return (int) httpObj;
}
void DECORATE(duck_close)(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
#if defined(_WIN32)
closesocket(httpObj->socket); // Close the old socket
#else
close(httpObj->socket);
#endif
destroyCircleBuffer(&httpObj->cBuffer);
duck_exit_http(handle);
}
void duck_exit_http(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
//delete httpObj->cBuffer;
delete httpObj;
#ifdef _WIN32
WSACleanup();
#endif
}
/* Read data off of the socket directly into the circular buffer */
inline int recv_circular (void* handle, size_t maxBytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int bytesRead = 0;
int totalRead = 0;
size_t tail = (httpObj->cBuffer.head + httpObj->cBuffer.count) % httpObj->cBuffer.bufSize;
size_t head = httpObj->cBuffer.head;
size_t freeSpace = httpObj->cBuffer.bufSize - httpObj->cBuffer.count;
size_t endSpace = httpObj->cBuffer.bufSize - tail;
size_t least;
if (tail >= head && maxBytes > endSpace) /* additional data write will wrap */
{
/* try to fill to end of buffer */
bytesRead = recv(httpObj->socket, (char*)httpObj->cBuffer.buffer + tail, (int)endSpace, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
maxBytes -= bytesRead;
freeSpace = httpObj->cBuffer.bufSize - httpObj->cBuffer.count;
if((size_t)bytesRead < maxBytes && (size_t)bytesRead == endSpace) /* filled to end and more to read */
{
httpObj->cBuffer.wrapped = 1;
least = (maxBytes < freeSpace) ? maxBytes : freeSpace;
bytesRead = recv(httpObj->socket, (char *)httpObj->cBuffer.buffer, (int)least, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
}
}
else /* existing data wrapped around from end of buffer through beginning of buffer. */
{
if (tail < head)
httpObj->cBuffer.wrapped = 1;
least = (maxBytes < freeSpace) ? maxBytes : freeSpace;
bytesRead = recv(httpObj->socket, (char*)httpObj->cBuffer.buffer + tail, (int)least, 0);
if (bytesRead < 0)
{
if (isDataAvailable((int)bytesRead) == 0)
return 0; // Try again later...
else
return (int)bytesRead; // Error
}
totalRead += bytesRead;
httpObj->cBuffer.count += bytesRead;
}
return (int)totalRead;
}
/* Re-charge the circular buffer */
int duck_sal_fill(void * handle, bool blocking, size_t maxFill)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
on2Timer start;
int bytesRead = 0;
int totalRead = 0;
int fillLevel = httpObj->cBuffer.bufSize * httpObj->cBuffer.percent / 100;
int fillSpace = fillLevel - httpObj->cBuffer.count;
if(maxFill)
{
// Charge twice as much as was read
maxFill *=2;
// Take the lesser of the two
fillSpace = ((int)maxFill < fillSpace) ? maxFill : fillSpace;
}
on2Timer_Init ( &start );
on2Timer_Start ( &start );
while ((httpObj->cBuffer.count < (size_t)fillLevel) && ((int)httpObj->cBuffer.count < httpObj->contentLen))
{
unsigned long delta = on2Timer_GetCurrentElapsedMilli(&start);
if (delta > httpObj->timeOut)
{
std::ostringstream temp;
temp << "Bytes received = " << totalRead;
//return -1;
return SetError(httpObj, SAL_ERR_CONNECTION_TIMEOUT, temp.str().c_str());
}
bytesRead = recv_circular(handle, fillSpace);
#if defined(__APPLE__) || defined(__POWERPC__)
if (bytesRead == 0 && blocking) /* please give some time to the SOCKET thread / OS . */
usleep(1000*2);
#endif
if (bytesRead < 0)
{
std::ostringstream temp;
temp << " : WSAGetLastError = " << WSAGetLastError();
SetError(httpObj,SAL_ERR_SERVER_CONNECTION,temp.str().c_str());
return bytesRead;
}
totalRead += bytesRead;
if (blocking == 0) /* we only want one recv done */
return totalRead;
}
return totalRead;
}
int DECORATE(duck_read)(int handle,unsigned char *buffer, int bytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int input;
if (bytes < 0)
return -1;
assert(httpObj);
assert(buffer);
input = readFromCircleBuffer(&httpObj->cBuffer, buffer, bytes);
if (input >= 1)
{
httpObj->totalRead += input;
}
bool blocking = false;
if (duck_sal_fill((void *)handle, blocking, bytes) < 0)
{
return -1; // The socket probably disconnected
}
return input;
}
int DECORATE(duck_read_blocking)(int handle,unsigned char *buffer, int bytes)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
int input;
int amountRead = 0;
if (bytes < 0)
return -1;
assert(httpObj);
assert(buffer);
while (amountRead < bytes)
{
input = readFromCircleBuffer(
&httpObj->cBuffer,
buffer + amountRead,
bytes - amountRead);
if (input < 0)
return input;
else
{
amountRead += input;
httpObj->totalRead += input;
}
bool blocking = false;
if (duck_sal_fill((void *)handle, blocking, bytes) < 0)
{
return -1; // The socket probably disconnected
}
}
return amountRead;
}
int64_t DECORATE(duck_seek)(int handle, int64_t offset,int origin)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
//printf("seeking to offset = %ld, origin = %ld\n", offset, origin);
if (offset < 0)
{
fprintf(stderr, "Trying to seek backwards with offset = %d\n", offset);
assert(0);
}
if (origin == SEEK_END)
{
fprintf(stderr, "SEEK_END is not supported\n", offset);
assert(0);
}
if (origin == SEEK_SET)
{
if ( offset > httpObj->totalRead &&
ForwardBuffer(&httpObj->cBuffer, (offset - httpObj->totalRead)) == 0
) /* forward small jump */
{
// We've eaten away at the buffer so re-charge it.
duck_sal_fill((void *)handle, false, (int)(offset - httpObj->totalRead));
httpObj->totalRead = offset;
return httpObj->totalRead;
}
else if ( offset < httpObj->totalRead &&
RewindBuffer(&httpObj->cBuffer, (httpObj->totalRead - offset)) == 0
) /* backwards small jump */
{
httpObj->totalRead = offset;
return httpObj->totalRead;
}
else
httpObj->totalRead = offset;
}
if (origin == SEEK_CUR)
{
if (!offset) // They just want the current pos
return httpObj->totalRead;
httpObj->totalRead += offset;
if(ForwardBuffer(&httpObj->cBuffer, offset) == 0)
{
duck_sal_fill((void *)handle, false, (size_t)offset); // We've eaten away at the buffer so re-charge it.
return httpObj->totalRead;
}
}
#if defined(_WIN32)
closesocket(httpObj->socket); // Close the old socket
#else
close(httpObj->socket);
#endif
destroyCircleBuffer(&httpObj->cBuffer);
ReOpen_t openData;
openData.offset = httpObj->totalRead;
openData.blocking = 0;
// Reconnect to http server
if( duck_open_http((char* )handle, (unsigned long)&openData) < 0)
{
char err[256];
SAL_ERR errCode;
duck_sal_error_http((void*)handle, &errCode, err, sizeof(err));
assert(0);
return -1;
}
return httpObj->totalRead;
}
int64_t duck_tell(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return httpObj->totalRead;
}
/* Return the amount of data in the circular buffer */
int duck_sal_buff_percent(void* handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return 100 * httpObj->cBuffer.count / httpObj->cBuffer.bufSize;
}
int64_t DECORATE(duck_available_data)(int handle)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
return httpObj->cBuffer.count;
}
/* Checks the last error */
int DECORATE(duck_sal_error)(void* handle, SAL_ERR* lastErrorCode, char buffer[], size_t maxLen)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
*lastErrorCode = httpObj->lastErrorCode;
if (httpObj->errorString.str().length() <= maxLen)
{
strcpy(buffer, httpObj->errorString.str().c_str());
return 0;
}
else
return -1;
}
int DECORATE(duck_name)(int handle, char url[], size_t maxLen)
{
DuckHttp_t* httpObj = (DuckHttp_t *) handle;
if (httpObj->urlExtended.length() <= maxLen)
strcpy(url, httpObj->urlExtended.c_str());
else
return -1;
return 0;
}

View file

@ -0,0 +1,110 @@
#include "on2_timer.h"
#if defined(WIN32)
#include <windows.h>
#include <mmsystem.h>
#else
#include <sys/time.h>
#endif
#if defined( WIN32 )
const unsigned long MAX_BEFORE_ROLLOVER = (1000 * 60 * 60 * 24);
#else
const unsigned long MAX_BEFORE_ROLLOVER = 0xFFFFFFFF;
#endif
// full day in milliseconds
const unsigned long kDuckFullDayMilli = 86400000;
void
on2Timer_Init ( on2Timer* pTimer )
{
pTimer->elapsedMilli = 0;
pTimer->baseMilli = 0;
}
/* The DeInit function was in danger of trying to free statically allocated timers goofy */
unsigned long
on2Timer_Start ( on2Timer* pTimer )
{
pTimer->baseMilli = on2Timer_GetCurrentTimeMilli();
pTimer->elapsedMilli = 0;
return pTimer->baseMilli;
}
unsigned long
on2Timer_Stop ( on2Timer* pTimer )
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
if(currentMilli >= pTimer->baseMilli)
{
pTimer->elapsedMilli = currentMilli - pTimer->baseMilli;
return pTimer->elapsedMilli;
}
// rollover condition, get milli before rollover, add to current milli
// I think if there is a rollover during timing on win32 this will cause a crash
// when the addition of currentMilli and rollMilli results in overflowing the size of
// and unsigned long int
else
{
unsigned long rollMilli = MAX_BEFORE_ROLLOVER - pTimer->baseMilli;
pTimer->elapsedMilli = currentMilli + rollMilli;
return pTimer->elapsedMilli;
}
}
unsigned long
on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer )
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
if(currentMilli >= pTimer->baseMilli)
{
return ( currentMilli - pTimer->baseMilli );
}
// rollover condition, get milli before rollover, add to current milli
else
{
unsigned long rollMilli = MAX_BEFORE_ROLLOVER - pTimer->baseMilli;
return ( currentMilli + rollMilli );
}
}
unsigned long
on2Timer_GetCurrentTimeSeconds ()
{
unsigned long currentMilli = on2Timer_GetCurrentTimeMilli();
return currentMilli / 1000;
}
unsigned long
on2Timer_GetCurrentTimeMilli ()
{
#if !defined(WIN32)
unsigned long currentMilli;
struct timeval tv;
struct timezone tz;
gettimeofday ( &tv, &tz );
currentMilli = (tv.tv_sec * 1000) + (tv.tv_usec/1000);
return currentMilli;
#else
return timeGetTime();
#endif
}
int
on2Timer_Sleep( int msec )
{
#ifdef _WIN32
Sleep( msec );
#endif
return 0;
}

View file

@ -0,0 +1,85 @@
#ifndef _ON2_TIMER_H_
#define _ON2_TIMER_H_
/************************************************************************/
/* on2Timer: cross-platform timer, works on win32 and linux so far */
/* started: August 14, 2001 */
/* codemonkey: TJF */
/************************************************************************/
#include <stdio.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct on2Timer_ {
unsigned long baseMilli;
unsigned long elapsedMilli;
} on2Timer;
/****************************************************************/
/* void on2Timer_Init ( on2Timer* pTimer ) */
/* initialize an allocated timer's members to 0 */
/****************************************************************/
void on2Timer_Init ( on2Timer* pTimer );
/****************************************************************/
/* unsigned long on2Timer_Start ( on2Timer* pTimer ) */
/* start a timer: sets baseTime to currentTime in milliseconds */
/****************************************************************/
unsigned long on2Timer_Start ( on2Timer* pTimer );
/****************************************************************/
/* unsigned long on2Timer_Stop ( on2Timer* pTimer ) */
/* stop a timer: sets elapsed time and accounts for rollover */
/****************************************************************/
unsigned long on2Timer_Stop ( on2Timer* pTimer );
/********************************************************************************/
/* unsigned long on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer ) */
/* get current elapsed time: returns elapsed time and accounts for rollover */
/********************************************************************************/
unsigned long on2Timer_GetCurrentElapsedMilli ( on2Timer* pTimer );
/********************************************************************************/
/* unsigned long on2Timer_GetMilliBeforeRollover ( unsigned long baseMilli ) */
/* returns milliseconds elapsed since rollover occurred */
/********************************************************************************/
unsigned long on2Timer_GetMilliBeforeRollover ( unsigned long baseMilli );
/****************************************************************/
/* unsigned long on2Timer_GetCurrentTimeSeconds ( void ) */
/* returns seconds since midnight */
/****************************************************************/
unsigned long on2Timer_GetCurrentTimeSeconds ( void );
/****************************************************************/
/* unsigned long on2Timer_GetCurrentTimeMilli ( void ) */
/* returns milliseconds since midnight */
/****************************************************************/
unsigned long on2Timer_GetCurrentTimeMilli ( void );
/****************************************************************/
/* void on2Timer_DeInit ( on2Timer* pTimer ); */
/* on2_free's a pointer to a on2Timer struct, for the lazy ;-) */
/****************************************************************/
void on2Timer_DeInit ( on2Timer* pTimer );
/****************************************************************/
/* void on2Timer_Sleep ( int msec ); */
/* Sleeps for the passed in number of milliseconds */
/****************************************************************/
int on2Timer_Sleep( int msec );
#if defined(__cplusplus)
}
#endif
#endif /* #ifndef _ON2_TIMER_H_ */

View file

@ -0,0 +1,228 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="sal"
ProjectGUID="{7C45701D-CD78-4C6A-A551-C62952E163A6}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\include,..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
PrecompiledHeaderFile=".\..\..\..\ObjectCode\sal\Release/sal.pch"
AssemblerListingLocation="..\..\..\ObjectCode\sal\Release/"
ObjectFile="..\..\..\ObjectCode\sal\Release/"
ProgramDataBaseFileName="..\..\..\ObjectCode\sal\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\include,..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\..\..\..\ObjectCode\sal\debug/sal.pch"
AssemblerListingLocation="..\..\..\ObjectCode\sal\debug/"
ObjectFile="..\..\..\ObjectCode\sal\debug/"
ProgramDataBaseFileName="..\..\..\ObjectCode\sal\debug/"
WarningLevel="4"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="win32"
>
<File
RelativePath="win32\duck_io32.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
<File
RelativePath="win32\duck_mem.c"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="generic"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -0,0 +1,106 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include "duck_io.h"
#include "duck_hfb.h"
#include <assert.h>
int read_count;
int duck_readFinished(int han, int flag)
{
return 1;
}
int duck_open(const char *name, unsigned long userData)
{
int f;
FILE *fp;
unsigned long x;
read_count = 0;
fp = fopen(name, "rb");
if (!fp)
assert(0);
x = (unsigned long ) fp;
/* high bit is set, the cast is a bad idea ! */
if (x & 0x90000000)
assert(0);
f = (int ) x;
return f;
}
void duck_close(int handle)
{
fclose((FILE *) handle);
}
static long totalRead = 0;
static long tellNo = 0;
long duck_read(int handle,unsigned char *buffer,long bytes)
{
int x;
if (buffer == NULL){
duck_seek(handle,bytes,SEEK_CUR);
return bytes;
}
tellNo = ftell((FILE *) handle);
if (bytes == 0)
return 0;
x = fread(buffer,sizeof(char) ,bytes, (FILE *) handle);
if (feof((FILE *) handle) && (x != (int ) bytes))
return -1;
totalRead += x;
if (x == -1L)
assert(0);
return x ;
}
long duck_seek(int handle,long offset,int origin)
{
long x = fseek((FILE *) handle,offset,origin);
tellNo = ftell((FILE *) handle);
return tellNo ;
}

View file

@ -0,0 +1,70 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include "duck_io.h"
int duck_open(const char *name, unsigned long userData)
{
char filename[255];
(void) userData;
if(name[strlen(name)-4] != '.') { /*no extension, try .AVI */
sprintf(filename,"%s.AVI",name);
//f = open(filename,O_BINARY|O_RDONLY);
//return(f);
}else
strcpy(filename,name);
//return(open(filename,O_BINARY|O_RDONLY));
return (int)CreateFile(filename,GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_NO_BUFFERING,NULL);
}
void duck_close(int handle)
{
//close(handle);
CloseHandle((void *)handle);
}
long duck_read(int handle,unsigned char *buffer,long bytes)
{
DWORD bytesRead;
if (buffer == NULL){
duck_seek(handle,bytes,SEEK_CUR);
return bytes;
}
ReadFile((void *)handle,buffer,bytes,&bytesRead,NULL);
//return(read(handle,buffer,bytes));
return bytesRead;
}
int64_t duck_seek(int handle,int64_t offset,int origin)
{
//return(lseek(handle,offset,origin));
return(SetFilePointer((HANDLE) handle,(LONG)offset,NULL,origin));
}
int duck_readFinished(int han, int flag)
{
(void)han; // not used;
(void)flag; // not used;
return 1;
}
void set_iofuncs()
{
// HFB_Setopen(duck_open);
// HFB_Setclose(duck_close);
// HFB_Setread(duck_read);
// HFB_Setseek(duck_seek);
}

View file

@ -0,0 +1,132 @@
/***********************************************\
??? duck_mem.c
\***********************************************/
#pragma warning(disable:4786)
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include <malloc.h>
#include "duck_mem.h"
#include "duck_io.h"
//#include "duck_hfb.h"
#include "duck_dxl.h"
//#define CHECK_MEM
#ifdef CHECK_MEM
#include <map>
#include "debug.h"
#endif
#ifdef CHECK_MEM
struct comp
{
bool operator()(void* v1, void* v2) const
{
return v1 < v2;
}
};
#endif
#ifdef CHECK_MEM
std::map<void*, size_t, struct comp> pointers;
int g_allocs = 0;
int g_frees = 0;
#endif
void *duck_memmove( void *dst, const void *src, size_t length )
{
return memmove(dst, src, length);
}
void *duck_malloc(size_t size, dmemType foo)
{
void *temp = malloc(size);
#ifdef CHECK_MEM
g_allocs++;
TRACE("a=%d\t%d\n", g_allocs, (int)temp);
pointers[temp] = size;
#endif
return temp;
}
void *duck_memset( void *dest, int c, size_t count )
{
return((void *) memset(dest, c, count));
}
void *duck_calloc(size_t n,size_t size, dmemType foo)
{
void *temp = calloc(n, size);
#ifdef CHECK_MEM
g_allocs++;
TRACE("a=%d\t%d\n", g_allocs, (int)temp);
pointers[temp] = size;
#endif
return temp;
}
void duck_free(void *old_blk)
{
#ifdef CHECK_MEM
g_frees++;
TRACE("f=%d\t%d\n", g_frees, (int)old_blk);
if(!pointers.erase(old_blk))
assert(0);
#endif
free(old_blk);
}
void* duck_realloc(void *src, size_t newSize, size_t oldSize)
{
void *temp;
if(newSize <= oldSize)
return src;
#ifdef CHECK_MEM
temp = duck_malloc(newSize, DMEM_GENERAL);
duck_memcpy(temp, src, oldSize);
duck_free(src);
#else
temp = realloc(src, newSize);
#endif
return temp;
}
void *duck_memcpy(void *dest, const void *source, size_t length)
{
return memcpy(dest,source,length);
}
void *duck_memcpy64(void *dest, const void *source, int64_t length)
{
/* Not fully 64 bit compliant */
return memcpy(dest,source,(size_t)length);
}
int duck_strcmp(const char *one, const char *two)
{
return strcmp(one, two);
}
void set_memfuncs()
{
#if defined(DXV_DLL)
DXV_Setmalloc(malloc);
DXV_Setcalloc(calloc);
DXV_Setfree(free);
#endif
#if defined(HFB_DLL)
HFB_Setmalloc(malloc);
HFB_Setcalloc(calloc);
HFB_Setfree(free);
#endif
}

View file

@ -0,0 +1,19 @@
/***********************************************\
??? duck_io.c
\***********************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <windows.h>
#include "duck_io.h"
#include "duck_hfb.h"
int duck_strcmp(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}