Sample Components/ExportPICS.c

/*
    File:       ExportPICS.c
 
    Written by: Peter Hoddie
 
    Copyright:  © 1992 by Apple Computer, Inc., all rights reserved.
 
*/
 
#include <Resources.h>
#include <SysEqu.h>
#include <Movies.h>
#include <QuickTimeComponents.h>
 
typedef struct {
    ComponentInstance       self;
} ExportPICSGlobalsRecord, *ExportPICSGlobals;
 
pascal ComponentResult ExportPICSDispatcher( ComponentParameters *params, Handle store );
pascal ComponentResult ExportPICSOpen(ExportPICSGlobals store, ComponentInstance self);
pascal ComponentResult ExportPICSClose(ExportPICSGlobals store, ComponentInstance self);
pascal ComponentResult ExportPICSCanDo( ExportPICSGlobals store, short ftnNumber );
pascal ComponentResult ExportPICSVersion( ExportPICSGlobals store );
 
pascal ComponentResult ExportPICSToFile(ExportPICSGlobals store, const FSSpec *theFile, 
                Movie m, Track onlyThisTrack, TimeValue startTime, TimeValue duration);
 
// entry point for all Component Manager requests
pascal ComponentResult ExportPICSDispatcher(ComponentParameters *params, Handle storage)
{
    OSErr err = badComponentSelector;
    ComponentFunction componentProc = 0;
 
    switch (params->what) {
        case kComponentOpenSelect: componentProc = ExportPICSOpen; break;
        case kComponentCloseSelect: componentProc = ExportPICSClose; break;
        case kComponentCanDoSelect: componentProc = ExportPICSCanDo; break;
        case kComponentVersionSelect: componentProc = ExportPICSVersion; break;
        case kMovieExportToFileSelect: componentProc = ExportPICSToFile; break;
    }
 
    if (componentProc)
        err = CallComponentFunctionWithStorage(storage, params, componentProc);
 
    return err;
}
 
pascal ComponentResult ExportPICSCanDo( ExportPICSGlobals store, short ftnNumber )
{
    switch (ftnNumber) {
        case kComponentOpenSelect:
        case kComponentCloseSelect:
        case kComponentCanDoSelect:
        case kComponentVersionSelect:
        case kMovieExportToFileSelect:
            return true;
            break;
        default:
            return false;
            break;
    }
}
 
pascal ComponentResult ExportPICSVersion( ExportPICSGlobals store )
{
    return 0x00010001;
}
 
pascal ComponentResult ExportPICSOpen(ExportPICSGlobals store, ComponentInstance self)
{
    OSErr err;
 
    store = (ExportPICSGlobals)NewPtrClear(sizeof(ExportPICSGlobalsRecord));
    if (err = MemError()) goto bail;
    store->self = self;
 
    SetComponentInstanceStorage(self, (Handle)store);
bail:
    return err;
}
 
pascal ComponentResult ExportPICSClose(ExportPICSGlobals store, ComponentInstance self)
{
    if (store) DisposPtr((Ptr)store);
 
    return noErr;
}
 
pascal ComponentResult ExportPICSToFile(ExportPICSGlobals store, const FSSpec *theFile, 
                Movie m, Track onlyThisTrack, TimeValue startTime, TimeValue duration)
{
    OSErr err = noErr;
    short resRef = 0;
    short saveResRef = CurResFile();
    short resID = 128;
    PicHandle thePict = nil;
 
    // open up the resource fork of the PICS file (the caller is responsible
    //  for creating the file)
    resRef = FSpOpenResFile(theFile, fsRdWrPerm);
    if (err = ResError()) goto bail;
    UseResFile(resRef);
 
    // iterate through the movie time segment we were given
    while (startTime < duration) {
        Byte c = 0;
 
        if (onlyThisTrack)
            thePict = GetTrackPict(onlyThisTrack, startTime);
        else
            thePict = GetMoviePict(m, startTime);
 
        if (!thePict) continue;
 
        // add a frame to the PICS file
        AddResource((Handle)thePict, 'PICT', resID++, &c);
        err = ResError();
        WriteResource((Handle)thePict);
        DetachResource((Handle)thePict);
        KillPicture(thePict);
        thePict = nil;
        if (err) break;
 
        // find the time of the next frame
        do {
            TimeValue nextTime;
 
            if (onlyThisTrack)
                GetTrackNextInterestingTime(onlyThisTrack, nextTimeMediaSample, startTime, 
                        kFix1, &nextTime, nil);
            else {
                OSType mediaType = VisualMediaCharacteristic;
    
                GetMovieNextInterestingTime(m, nextTimeMediaSample, 1, &mediaType, 
                        startTime, kFix1, &nextTime, nil);
            }
            if (GetMoviesError()) goto bail;
 
            if (nextTime != startTime) {
                startTime = nextTime;
                break;
            }
        } while (++startTime < duration);
    }
 
bail:
    if (thePict) KillPicture(thePict);
    if (resRef) CloseResFile(resRef);
    UseResFile(saveResRef);
    return err;
}