Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
QTMovieFromProcs.c
////////// |
// |
// File: QTMovieFromProcs.c |
// |
// Contains: Sample code for creating a QuickTime movie using application-defined procedures. |
// |
// Written by: Tim Monroe |
// Based on sample code in the QuickTime 3.0 Reference document. |
// |
// Copyright: © 1998-1999 by Apple Computer, Inc., all rights reserved. |
// |
// Change History (most recent first): |
// |
// <8> 03/32/00 rtm removed calls to Standard File Package (FSSpec now passed in); |
// made changes to run under CarbonLib |
// <7> 02/09/99 rtm minor tweaks; verified on Windows and Mac; added more comments |
// <6> 02/05/99 rtm added code to enumerate all components that can export-by-procs |
// add their names to the Test menu, and use the selected exporter |
// <5> 02/02/99 rtm reworked prompt and filename handling to remove "\p" sequences |
// <4> 11/11/98 rtm minor tweaks; added more comments |
// <3> 11/06/98 rtm incorporated settings file code from QTHintMovies.c |
// <2> 10/19/98 rtm further work; works fine on Mac and Windows |
// <1> 10/16/98 rtm first file |
// |
// QuickTime 3.0 provides functions that allow you to create a movie using data supplied by one or more |
// application-defined procedures. In particular, you use the function MovieExportAddDataSource to add a |
// track-generating procedure and you use the function MovieExportFromProceduresToDataRef to do the actual |
// movie exporting. |
// |
// In this example, we will create a QuickTime movie with a video track and an audio track; we generate the |
// video track by drawing a series of individual frames, and we generate the audio track by generating |
// 10 seconds of silence. |
// |
// This sample code finds all movie export components that can export using application-defined procedures, |
// adds their names to a menu, and then calls the appropriate exporter when the user selects a menu item. The |
// only real interesting code in the QTMenu_ functions is the code that enumerates the available exporters |
// that can export-by-procedures. |
// |
// This sample code snippet also illustrates how to configure the movie export component, using either |
// MovieExportDoUserDialog to display the component's settings dialog or MovieExportSetSettingsFromAtomContainer |
// to restore some previously-saved settings from an atom container. Note that any settings configured by the |
// user or by a call to MovieExportSetSettingsFromAtomContainer may be overridden by the settings returned by |
// your track property callback function (in this sample, the functions QTMoovProcs_AudioTrackPropertyProc and |
// QTMoovProcs_VideoTrackPropertyProc). |
// |
////////// |
#include "QTMovieFromProcs.h" |
// global variables |
QTMoovProcsAudioDataRec gAudioDataRec; |
QTMoovProcsVideoDataRec gVideoDataRec; |
MovieExportGetPropertyUPP gAudioPropProcUPP = NULL; |
MovieExportGetDataUPP gAudioDataProcUPP = NULL; |
MovieExportGetPropertyUPP gVideoPropProcUPP = NULL; |
MovieExportGetDataUPP gVideoDataProcUPP = NULL; |
QTProcExportersInfo gExporterInfo; |
extern ConstStr255Param gSettingsFileName; |
#if TARGET_OS_WIN32 |
extern HWND ghWnd; // the MDI frame window; this window has the menu bar |
#include "ComResource.h" |
#endif |
////////// |
// |
// QTMoovProcs_CreateMovieFromProcs |
// Create a QuickTime movie using audio- and video-data generating procedures. |
// |
////////// |
OSErr QTMoovProcs_CreateMovieFromProcs (FSSpecPtr theOutputFile, MovieExportComponent theExporter, Boolean thePromptUser) |
{ |
Handle myDataRef = NULL; |
FSSpec myPrefsFile; |
OSErr myErr = userCanceledErr; |
if (theOutputFile == NULL) |
goto bail; |
// add sources of audio and video data to the movie exporter; |
// we ignore errors here, since some exporters might be audio-only or video-only |
myErr = QTMoovProcs_AddAudioSourceToExporter(theExporter); |
myErr = QTMoovProcs_AddVideoSourceToExporter(theExporter); |
// create a data reference for the output movie file |
myDataRef = NewHandle(sizeof(Handle)); |
if (myDataRef == NULL) |
goto bail; |
QTNewAlias(theOutputFile, (AliasHandle *)&myDataRef, true); |
// get the preferences file for this application |
QTMoovProcs_GetPrefsFileSpec(&myPrefsFile, (void *)(theOutputFile)); |
// read existing movie exporter settings from a file; if we aren't going to prompt |
// the user for exporter settings, these stored settings will be used; otherwise, |
// these stored settings will be used as initial values in the settings dialog box |
QTUtils_GetExporterSettingsFromFile(theExporter, &myPrefsFile); |
if (thePromptUser) { |
Boolean myCancelled = false; |
// display a dialog box to prompt the user for desired movie exporter settings |
myErr = MovieExportDoUserDialog(theExporter, NULL, NULL, 0, 0, &myCancelled); |
if (myCancelled) |
goto bail; |
// save the existing settings into our preferences file |
QTUtils_SaveExporterSettingsInFile(theExporter, &myPrefsFile); |
} |
// export the audio and video data to the data reference |
myErr = MovieExportFromProceduresToDataRef(theExporter, myDataRef, rAliasType); |
bail: |
// dispose of the routine descriptors |
DisposeMovieExportGetPropertyUPP(gAudioPropProcUPP); |
DisposeMovieExportGetDataUPP(gAudioDataProcUPP); |
DisposeMovieExportGetPropertyUPP(gVideoPropProcUPP); |
DisposeMovieExportGetDataUPP(gVideoDataProcUPP); |
// dispose of any memory that we allocated before or during the export operation |
if (myDataRef != NULL) |
DisposeHandle(myDataRef); |
if (gAudioDataRec.fSoundData != NULL) |
DisposePtr(gAudioDataRec.fSoundData); |
if (gAudioDataRec.fSoundDescription != NULL) |
DisposeHandle((Handle)gAudioDataRec.fSoundDescription); |
if (gVideoDataRec.fGWorld != NULL) |
DisposeGWorld(gVideoDataRec.fGWorld); |
if (gVideoDataRec.fImageDescription != NULL) |
DisposeHandle((Handle)gVideoDataRec.fImageDescription); |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_AddAudioSourceToExporter |
// Attach a source for audio data to the specified movie exporter. |
// |
////////// |
OSErr QTMoovProcs_AddAudioSourceToExporter (MovieExportComponent theExporter) |
{ |
SoundDescriptionPtr mySoundDescPtr = NULL; |
short myIndex; |
OSErr myErr = memFullErr; |
// create a buffer to hold the audio data |
gAudioDataRec.fSoundData = NewPtrClear(kSoundBufferSize); |
if (gAudioDataRec.fSoundData == NULL) |
goto bail; |
// our sound data format is 8-bit, offset binary, where a sample point is an 8-bit value |
// in the range 0 to 255 (0x00 to 0xFF); for silence, set all sample points to 128 (0x80) |
for (myIndex = 0; myIndex < kSoundBufferSize; myIndex++) |
gAudioDataRec.fSoundData[myIndex] = (UInt8)128; |
// create and configure a sound description record |
gAudioDataRec.fSoundDescription = (SoundDescriptionHandle)NewHandleClear(sizeof(SoundDescription)); |
if (gAudioDataRec.fSoundDescription == NULL) |
goto bail; |
mySoundDescPtr = *(gAudioDataRec.fSoundDescription); |
mySoundDescPtr->descSize = sizeof(SoundDescription); |
mySoundDescPtr->dataFormat = k8BitOffsetBinaryFormat; |
mySoundDescPtr->numChannels = 1; |
mySoundDescPtr->sampleSize = 8; |
mySoundDescPtr->sampleRate = kAudioSampleRate << 16; |
// create UPPs for the two app-defined export functions |
gAudioPropProcUPP = NewMovieExportGetPropertyUPP(QTMoovProcs_AudioTrackPropertyProc); |
gAudioDataProcUPP = NewMovieExportGetDataUPP(QTMoovProcs_AudioTrackDataProc); |
myErr = MovieExportAddDataSource(theExporter, |
SoundMediaType, |
kAudioSampleRate, |
&gAudioDataRec.fTrackID, |
gAudioPropProcUPP, |
gAudioDataProcUPP, |
&gAudioDataRec); |
bail: |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_AddVideoSourceToExporter |
// Attach a source for video data to the specified movie exporter. |
// |
////////// |
OSErr QTMoovProcs_AddVideoSourceToExporter (MovieExportComponent theExporter) |
{ |
OSErr myErr = noErr; |
gVideoDataRec.fGWorld = NULL; |
gVideoDataRec.fImageDescription = NULL; |
// create UPPs for the two app-defined export functions |
gVideoPropProcUPP = NewMovieExportGetPropertyUPP(QTMoovProcs_VideoTrackPropertyProc); |
gVideoDataProcUPP = NewMovieExportGetDataUPP(QTMoovProcs_VideoTrackDataProc); |
myErr = MovieExportAddDataSource(theExporter, |
VideoMediaType, |
kVideoSampleRate, |
&gVideoDataRec.fTrackID, |
gVideoPropProcUPP, |
gVideoDataProcUPP, |
&gVideoDataRec); |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_AudioTrackPropertyProc |
// Handle requests for information about the output audio data. |
// |
////////// |
PASCAL_RTN OSErr QTMoovProcs_AudioTrackPropertyProc (void *theRefcon, long theTrackID, OSType thePropertyType, void *thePropertyValue) |
{ |
#pragma unused(theRefcon, theTrackID) |
OSErr myErr = noErr; |
switch (thePropertyType) { |
case scSoundSampleRateType: |
*(Fixed *)thePropertyValue = 32000L << 16; |
break; |
default: |
myErr = paramErr; // non-zero value means: use default value provided by export component |
break; |
} |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_AudioTrackDataProc |
// Provide the output audio data. |
// |
////////// |
PASCAL_RTN OSErr QTMoovProcs_AudioTrackDataProc (void *theRefcon, MovieExportGetDataParams *theParams) |
{ |
QTMoovProcsAudioDataRecPtr myAudioDataRecPtr; |
OSErr myErr = noErr; |
myAudioDataRecPtr = (QTMoovProcsAudioDataRecPtr)theRefcon; |
// end the data after desired length of movie |
if (theParams->requestedTime > kAudioSampleRate * kMovieLengthInSeconds) |
return(eofErr); |
theParams->actualTime = theParams->requestedTime; |
theParams->dataPtr = myAudioDataRecPtr->fSoundData; |
theParams->dataSize = kSoundBufferSize; |
theParams->desc = (SampleDescriptionHandle)(myAudioDataRecPtr->fSoundDescription); |
theParams->descType = SoundMediaType; |
theParams->descSeed = 1; |
theParams->actualSampleCount = kSoundBufferSize; |
theParams->durationPerSample = 1; |
theParams->sampleFlags = 0L; |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_VideoTrackPropertyProc |
// Handle requests for information about the output video data. |
// |
////////// |
PASCAL_RTN OSErr QTMoovProcs_VideoTrackPropertyProc (void *theRefcon, long theTrackID, OSType thePropertyType, void *thePropertyValue) |
{ |
#pragma unused(theRefcon, theTrackID) |
OSErr myErr = noErr; |
switch (thePropertyType) { |
case movieExportWidth: |
*(Fixed *)thePropertyValue = kVideoFrameWidth << 16; |
break; |
case movieExportHeight: |
*(Fixed *)thePropertyValue = kVideoFrameHeight << 16; |
break; |
case scSpatialSettingsType: { |
SCSpatialSettings *mySpatialSettings = thePropertyValue; |
mySpatialSettings->codecType = kJPEGCodecType; |
mySpatialSettings->codec = 0; |
mySpatialSettings->depth = 0; |
mySpatialSettings->spatialQuality = codecNormalQuality; |
} |
break; |
default: |
myErr = paramErr; // non-zero value means: use default value provided by export component |
break; |
} |
return(myErr); |
} |
////////// |
// |
// QTMoovProcs_VideoTrackDataProc |
// Provide the output audio data. |
// |
////////// |
PASCAL_RTN OSErr QTMoovProcs_VideoTrackDataProc (void *theRefcon, MovieExportGetDataParams *theParams) |
{ |
QTMoovProcsVideoDataRecPtr myVideoDataRecPtr; |
PixMapHandle myPixMap = NULL; |
Rect myRect; |
CGrafPtr myOldPort = NULL; |
GDHandle myOldDevice = NULL; |
Str255 myString; |
static long myFrameNum = 0; |
OSErr myErr = noErr; |
myVideoDataRecPtr = (QTMoovProcsVideoDataRecPtr)theRefcon; |
// end the data after desired length of movie |
if (theParams->requestedTime > kVideoSampleRate * kMovieLengthInSeconds) |
return(eofErr); |
// set the size of the video frame |
MacSetRect(&myRect, 0, 0, kVideoFrameWidth, kVideoFrameHeight); |
// if we haven't allocated a GWorld yet, do so now |
if (myVideoDataRecPtr->fGWorld == NULL) { |
NewGWorld(&(myVideoDataRecPtr->fGWorld), 32, &myRect, NULL, NULL, (GWorldFlags)0); |
if (myVideoDataRecPtr->fGWorld == NULL) |
return(memFullErr); |
myPixMap = GetGWorldPixMap(myVideoDataRecPtr->fGWorld); |
if (myPixMap == NULL) |
return(memFullErr); |
LockPixels(myPixMap); |
myErr = MakeImageDescriptionForPixMap(myPixMap, &(myVideoDataRecPtr->fImageDescription)); |
if (myErr != noErr) |
goto bail; |
} |
GetGWorld(&myOldPort, &myOldDevice); |
SetGWorld(myVideoDataRecPtr->fGWorld, NULL); |
// draw a frame: white rectangle with black frame number centered horizontally in frame |
EraseRect(&myRect); |
ForeColor(whiteColor); |
PaintRect(&myRect); |
ForeColor(blackColor); |
NumToString(++myFrameNum, myString); |
MoveTo((short)(myRect.right / 2) - (StringWidth(myString) / 2), (short)(myRect.bottom / 2)); |
TextSize((short)(myRect.bottom / 4)); |
DrawString(myString); |
theParams->actualTime = theParams->requestedTime; |
theParams->dataPtr = GetPixBaseAddr(GetGWorldPixMap(myVideoDataRecPtr->fGWorld)); |
theParams->dataSize = (**(myVideoDataRecPtr->fImageDescription)).dataSize; |
theParams->desc = (SampleDescriptionHandle)(myVideoDataRecPtr->fImageDescription); |
theParams->descType = VideoMediaType; |
theParams->descSeed = 1; |
theParams->actualSampleCount = 1; |
theParams->durationPerSample = kVideoFrameDuration; |
theParams->sampleFlags = 0L; |
bail: |
// restore the original graphics port and device |
SetGWorld(myOldPort, myOldDevice); |
return(myErr); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Menu utilities. |
// |
// Use these functions to add component names to a menu and to handle user selections in that menu. These |
// exist mainly to illustrate how to find all movie export components that can export using application- |
// defined procedures. |
// |
// It's useful to remember that Macintosh menu items are numbered from 1, whereas Windows menu items are |
// numbered from 0. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTMenu_InitializeTestMenu |
// Initialize the Test menu; add component names to it. |
// |
////////// |
OSErr QTMenu_InitializeTestMenu (void) |
{ |
short myIndex; |
short myNumItems; |
#if TARGET_OS_MAC |
gExporterInfo.fTestMenuHandle = GetMenuHandle(kTestMenuID); |
// remove any existing menu items |
myNumItems = CountMenuItems(gExporterInfo.fTestMenuHandle); |
for (myIndex = 0; myIndex < myNumItems; myIndex++) |
DeleteMenuItem(gExporterInfo.fTestMenuHandle, 1); |
#elif TARGET_OS_WIN32 |
gExporterInfo.fTestMenuHandle = GetSubMenu(GetMenu(ghWnd), WINDOWMENU - 1); |
// remove any existing menu items |
myNumItems = GetMenuItemCount(gExporterInfo.fTestMenuHandle); |
for (myIndex = 0; myIndex < myNumItems; myIndex++) |
RemoveMenu(gExporterInfo.fTestMenuHandle, 0, MF_BYPOSITION); |
#endif |
gExporterInfo.fNextAvailIndex = 0; |
// add names of all components that can export-by-procedures to Test menu |
QTMenu_AddComponentNamesToMenu(); |
return(noErr); |
} |
////////// |
// |
// QTMenu_AddComponentNamesToMenu |
// Add the name of all movie export components that can export-by-procedures to the Test menu. |
// |
////////// |
OSErr QTMenu_AddComponentNamesToMenu (void) |
{ |
Component myComponent = NULL; |
Handle myCompName = NewHandleClear(0); |
ComponentDescription myCompDesc; |
// find all movie export components that can export-by-procedures |
do { |
myCompDesc.componentType = MovieExportType; |
myCompDesc.componentSubType = 0; |
myCompDesc.componentManufacturer = 0; |
myCompDesc.componentFlags = canMovieExportFromProcedures; |
myCompDesc.componentFlagsMask = canMovieExportFromProcedures; |
myComponent = FindNextComponent(myComponent, &myCompDesc); |
if (myComponent != NULL) { |
// get the component information |
GetComponentInfo(myComponent, &myCompDesc, myCompName, NULL, NULL); |
// add the component's name to the menu |
#if TARGET_OS_MAC |
MacAppendMenu(gExporterInfo.fTestMenuHandle, (StringPtr)*myCompName); |
#elif TARGET_OS_WIN32 |
AppendMenu(gExporterInfo.fTestMenuHandle, MF_STRING | MF_ENABLED, MENU_IDENTIFIER(kTestMenu, gExporterInfo.fNextAvailIndex + 1), p2cstr((StringPtr)*myCompName)); |
#endif |
// keep track of this component |
gExporterInfo.fComponentType[gExporterInfo.fNextAvailIndex] = myCompDesc.componentType; |
gExporterInfo.fComponentSubType[gExporterInfo.fNextAvailIndex] = myCompDesc.componentSubType; |
gExporterInfo.fComponentManufacturer[gExporterInfo.fNextAvailIndex] = myCompDesc.componentManufacturer; |
gExporterInfo.fNextAvailIndex++; |
} |
} while (myComponent != NULL); |
if (myCompName != NULL) |
DisposeHandle(myCompName); |
return(noErr); |
} |
////////// |
// |
// QTMenu_HandleTestMenu |
// Handle user selection of items in the Test menu. |
// |
////////// |
OSErr QTMenu_HandleTestMenu (UInt16 theMenuItem) |
{ |
MovieExportComponent myExporter = NULL; |
ComponentDescription myCompDesc; |
short myIndex; |
OSErr myErr = noErr; |
myIndex = MENU_ITEM(theMenuItem) - 1; |
if ((myIndex < 0) || (myIndex >= gExporterInfo.fNextAvailIndex)) |
return(paramErr); |
myCompDesc.componentType = gExporterInfo.fComponentType[myIndex]; |
myCompDesc.componentSubType = gExporterInfo.fComponentSubType[myIndex]; |
myCompDesc.componentManufacturer = gExporterInfo.fComponentManufacturer[myIndex]; |
myCompDesc.componentFlags = canMovieExportFromProcedures; |
myCompDesc.componentFlagsMask = canMovieExportFromProcedures; |
// open the selected movie export component |
myExporter = OpenComponent(FindNextComponent(NULL, &myCompDesc)); |
if (myExporter == NULL) |
return(badComponentType); |
// create the movie using application-defined procedures |
myErr = QTMoovProcs_CreateMovieFromProcs(myExporter, true); |
// close the movie export component |
if (myExporter != NULL) |
CloseComponent(myExporter); |
return(myErr); |
} |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
// |
// Settings utilities. |
// |
// Use these functions to save/retrieve movie exporter settings into/from a preferences file. |
// |
/////////////////////////////////////////////////////////////////////////////////////////////////////////// |
////////// |
// |
// QTMoovProcs_GetPrefsFileSpec |
// Fill in the specified FSSpec with info about this application's preferences file. |
// |
// The theRefCon parameter is a pointer to some application-specific data, which you |
// might use to find the preferences file; here, we assume it's a pointer to an FSSpec |
// for the output hinted file. We'll specify a preferences file in the same folder as |
// the hinted file that has the name specified by the global variable gSettingsFileName. |
// |
////////// |
OSErr QTMoovProcs_GetPrefsFileSpec (FSSpecPtr thePrefsSpecPtr, void *theRefCon) |
{ |
FSSpecPtr myFSSpecPtr = (FSSpecPtr)theRefCon; |
OSErr myErr = noErr; |
if (myFSSpecPtr == NULL) |
return(paramErr); |
myErr = FSMakeFSSpec(myFSSpecPtr->vRefNum, myFSSpecPtr->parID, gSettingsFileName, thePrefsSpecPtr); |
return(myErr); |
} |
////////// |
// |
// QTUtils_SaveExporterSettingsInFile |
// Get the current settings of the specified movie exporter and save them into a file. |
// |
////////// |
OSErr QTUtils_SaveExporterSettingsInFile (MovieExportComponent theExporter, FSSpecPtr theFSSpecPtr) |
{ |
QTAtomContainer myContainer = NULL; |
ComponentResult myErr = noErr; |
myErr = MovieExportGetSettingsAsAtomContainer(theExporter, &myContainer); |
if (myErr != noErr) |
goto bail; |
myErr = QTUtils_WriteHandleToFile((Handle)myContainer, theFSSpecPtr); |
bail: |
if (myContainer != NULL) |
QTDisposeAtomContainer(myContainer); |
return((OSErr)myErr); |
} |
////////// |
// |
// QTUtils_GetExporterSettingsFromFile |
// Read the movie exporter settings saved in the specified file. |
// |
////////// |
OSErr QTUtils_GetExporterSettingsFromFile (MovieExportComponent theExporter, FSSpecPtr theFSSpecPtr) |
{ |
Handle myHandle = NULL; |
ComponentResult myErr = fnfErr; // assume we cannot find the file |
myHandle = QTUtils_ReadHandleFromFile(theFSSpecPtr); |
if (myHandle == NULL) |
goto bail; |
myErr = MovieExportSetSettingsFromAtomContainer(theExporter, (QTAtomContainer)myHandle); |
bail: |
if (myHandle != NULL) |
DisposeHandle(myHandle); |
return((OSErr)myErr); |
} |
////////// |
// |
// QTUtils_WriteHandleToFile |
// Write the data in the specified handle into the specified file; |
// if the file already exists, it is overwritten. |
// |
////////// |
OSErr QTUtils_WriteHandleToFile (Handle theHandle, FSSpecPtr theFSSpecPtr) |
{ |
short myRefNum = 0; |
#if TARGET_OS_MAC |
short myVolNum; |
#endif |
long mySize = 0; |
OSErr myErr = paramErr; |
if (theHandle == NULL) |
goto bail; |
mySize = GetHandleSize(theHandle); |
if (mySize == 0) |
goto bail; |
HLock(theHandle); |
// delete the file; |
// if it doesn't exist yet, we'll get an error (fnfErr), which we just ignore |
myErr = FSpDelete(theFSSpecPtr); |
// create and open the file |
myErr = FSpCreate(theFSSpecPtr, kSettingsFileCreator, kSettingsFileType, smSystemScript); |
if (myErr == noErr) |
myErr = FSpOpenDF(theFSSpecPtr, fsRdWrPerm, &myRefNum); |
// position the file mark to the beginning of the file and write the data |
if (myErr == noErr) |
myErr = SetFPos(myRefNum, fsFromStart, 0); |
if (myErr == noErr) |
myErr = FSWrite(myRefNum, &mySize, *theHandle); |
if (myErr == noErr) |
myErr = SetFPos(myRefNum, fsFromStart, mySize); |
// resize the file to the number of bytes written |
if (myErr == noErr) |
myErr = SetEOF(myRefNum, mySize); |
// close the file |
if (myErr == noErr) |
myErr = FSClose(myRefNum); |
#if TARGET_OS_MAC |
// flush the volume |
if (myErr == noErr) |
myErr = GetVRefNum(myRefNum, &myVolNum); |
if (myErr == noErr) |
myErr = FlushVol(NULL, myVolNum); |
#endif |
bail: |
HUnlock(theHandle); |
return(myErr); |
} |
////////// |
// |
// QTUtils_ReadHandleFromFile |
// Read the data in the specified file into a new handle. |
// |
////////// |
Handle QTUtils_ReadHandleFromFile (FSSpecPtr theFSSpecPtr) |
{ |
Handle myHandle = NULL; |
short myRefNum = 0; |
long mySize = 0; |
OSErr myErr = noErr; |
// open the file |
myErr = FSpOpenDF(theFSSpecPtr, fsRdWrPerm, &myRefNum); |
if (myErr == noErr) |
myErr = SetFPos(myRefNum, fsFromStart, 0); |
// get the size of the file data |
if (myErr == noErr) |
myErr = GetEOF(myRefNum, &mySize); |
// allocate a new handle |
if (myErr == noErr) |
myHandle = NewHandleClear(mySize); |
if (myHandle == NULL) |
goto bail; |
HLock(myHandle); |
// read the data from the file into the handle |
if (myErr == noErr) |
myErr = FSRead(myRefNum, &mySize, *myHandle); |
bail: |
HUnlock(myHandle); |
if (myRefNum != 0) |
FSClose(myRefNum); |
return(myHandle); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14