// Create the 'pasp' atom for video tracks. No guesswork required. // References http://www.uwasa.fi/~f76998/video/conversion/ void set_track_clean_aperture_ext(ImageDescriptionHandle imgDesc, Fixed displayW, Fixed displayH, Fixed pixelW, Fixed pixelH) { if (displayW == pixelW && displayH == pixelH) return; AVRational dar, invPixelSize, sar; dar = (AVRational) { displayW, displayH }; invPixelSize = (AVRational) { pixelH, pixelW }; sar = av_mul_q(dar, invPixelSize); av_reduce(&sar.num, &sar.den, sar.num, sar.den, fixed1); if (sar.num == sar.den) return; PixelAspectRatioImageDescriptionExtension **pasp = (PixelAspectRatioImageDescriptionExtension**)NewHandle(sizeof(PixelAspectRatioImageDescriptionExtension)); **pasp = (PixelAspectRatioImageDescriptionExtension) { EndianU32_NtoB(sar.num), EndianU32_NtoB(sar.den) }; AddImageDescriptionExtension(imgDesc, (Handle)pasp, kPixelAspectRatioImageDescriptionExtension); DisposeHandle((Handle)pasp); }
int process_first_packet__flac(StreamInfo *si, ogg_page *op, ogg_packet *opckt) { unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo), EndianS32_NtoB(ogg_page_serialno(op)) }; unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead) - 13), EndianU32_NtoB(kCookieTypeFLACStreaminfo) }; UInt32 sib = EndianU32_BtoN(* (UInt32 *) (((char *)opckt->packet) + 27)); si->si_flac.metablocks = (SInt32) EndianU16_BtoN(* (UInt16 *) (((char *)opckt->packet) + 7)); sib >>= 4; si->si_flac.bps = (sib & 0x1f) + 1; sib >>= 5; si->numChannels = (sib & 0x07) + 1; si->rate = (sib >> 3) & 0xfffff; //si->lastMediaInserted = 0; si->mediaLength = 0; dbg_printf("! -- - flac_first_packet: ch: %d, rate: %ld, bps: %ld\n", si->numChannels, si->rate, si->si_flac.bps); PtrAndHand(serialnoatom, si->soundDescExtension, sizeof(serialnoatom)); //check errors? PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors? PtrAndHand((((char *)opckt->packet) + 13), si->soundDescExtension, opckt->bytes - 13); //check errors? si->si_flac.state = kFStateReadingComments; return 0; };
OSErr QTDR_CreateTrackInRAM (Movie theMovie) { Track myTrack = NULL; Media myMedia = NULL; Handle myDataRef = NULL; unsigned long myAtomHeader[2]; OSErr myErr = noErr; if (theMovie == NULL) return(paramErr); myDataRef = NewHandleClear(sizeof(Handle) + sizeof(char)); if (myDataRef == NULL) return(MemError()); myAtomHeader[0] = EndianU32_NtoB(sizeof(myAtomHeader)); myAtomHeader[1] = EndianU32_NtoB(kDataRefExtensionInitializationData); myErr = PtrAndHand(myAtomHeader, myDataRef, sizeof(myAtomHeader)); if (myErr != noErr) goto bail; // create the movie track and media myTrack = NewMovieTrack(theMovie, FixRatio(kVideoTrackWidth, 1), FixRatio(kVideoTrackHeight, 1), kNoVolume); myErr = GetMoviesError(); if (myErr != noErr) goto bail; myMedia = NewTrackMedia(myTrack, VideoMediaType, kVideoTimeScale, myDataRef, HandleDataHandlerSubType); myErr = GetMoviesError(); if (myErr != noErr) goto bail; // create the media samples myErr = BeginMediaEdits(myMedia); if (myErr != noErr) goto bail; myErr = QTDR_AddVideoSamplesToMedia(myMedia, kVideoTrackWidth, kVideoTrackHeight); if (myErr != noErr) goto bail; myErr = EndMediaEdits(myMedia); if (myErr != noErr) goto bail; // add the media to the track myErr = InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); bail: if (myDataRef != NULL) DisposeHandle(myDataRef); return(myErr); }
static uint16 get_short_event_parm(EventRef evt, EventParamName n, EventParamType t) { uint16 r = NULL; OSStatus e = GetEventParameter(evt, n, t, NULL, sizeof(r), NULL, &r); uint32 nb = EndianU32_NtoB(n); if (e) lprintf("scalar event parm failed: %4.4s, %d\n", (char*)&n, e); return r; }
Handle QTDR_MakeResourceDataRef (FSSpecPtr theFile, OSType theResType, SInt16 theResID) { Handle myDataRef = NULL; OSType myResType; SInt16 myResID; OSErr myErr = noErr; myDataRef = QTDR_MakeFileDataRef(theFile); if (myDataRef == NULL) goto bail; // append the resource type and ID to the data reference myResType = EndianU32_NtoB(theResType); myResID = EndianS16_NtoB(theResID); myErr = PtrAndHand(&myResType, myDataRef, sizeof(myResType)); if (myErr == noErr) myErr = PtrAndHand(&myResID, myDataRef, sizeof(myResID)); bail: if (myErr != noErr) { if (myDataRef != NULL) DisposeHandle(myDataRef); myDataRef = NULL; } return(myDataRef); }
void QTTarg_SetTrackProperties (Media theMedia, UInt32 theIdleFrequency) { QTAtomContainer myTrackProperties; RGBColor myBackgroundColor; Boolean hasActions; UInt32 myFrequency; OSErr myErr = noErr; // add a background color to the sprite track myBackgroundColor.red = EndianU16_NtoB(0xffff); myBackgroundColor.green = EndianU16_NtoB(0xffff); myBackgroundColor.blue = EndianU16_NtoB(0xffff); myErr = QTNewAtomContainer(&myTrackProperties); if (myErr == noErr) { QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyBackgroundColor, 1, 1, sizeof(myBackgroundColor), &myBackgroundColor, NULL); // tell the movie controller that this sprite track has actions hasActions = true; QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(hasActions), &hasActions, NULL); // tell the sprite track to generate QTIdleEvents myFrequency = EndianU32_NtoB(theIdleFrequency); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL); SetMediaPropertyAtom(theMedia, myTrackProperties); QTDisposeAtomContainer(myTrackProperties); } }
void CAAudioFileConverter::WriteCAFInfo() { FSRef fsref; AudioFileID afid = 0; CAFSourceInfo info; UInt32 size; try { XThrowIfError(FSPathMakeRef((UInt8 *)mParams.input.filePath, &fsref, NULL), "couldn't locate input file"); XThrowIfError(AudioFileOpen(&fsref, fsRdPerm, 0, &afid), "couldn't open input file"); size = sizeof(AudioFileTypeID); XThrowIfError(AudioFileGetProperty(afid, kAudioFilePropertyFileFormat, &size, &info.filetype), "couldn't get input file's format"); AudioFileClose(afid); afid = 0; XThrowIfError(FSPathMakeRef((UInt8 *)mOutName, &fsref, NULL), "couldn't locate output file"); XThrowIfError(AudioFileOpen(&fsref, fsRdWrPerm, 0, &afid), "couldn't open output file"); const char *srcFilename = strrchr(mParams.input.filePath, '/'); if (srcFilename++ == NULL) srcFilename = mParams.input.filePath; ASBD_NtoB(&mSrcFormat, (AudioStreamBasicDescription *)info.asbd); int namelen = std::min(kMaxFilename-1, (int)strlen(srcFilename)); memcpy(info.filename, srcFilename, namelen); info.filename[namelen++] = 0; info.filetype = EndianU32_NtoB(info.filetype); XThrowIfError(AudioFileSetUserData(afid, 'srcI', 0, offsetof(CAFSourceInfo, filename) + namelen, &info), "couldn't set CAF file's source info chunk"); AudioFileClose(afid); } catch (...) { if (afid) AudioFileClose(afid); throw; } }
static void* get_scalar_event_parm(EventRef evt, EventParamName n, EventParamType t) { void* r = NULL; OSStatus e = GetEventParameter(evt, n, t, NULL, sizeof(r), NULL, &r); if (e == noErr || e == -9870) return r; uint32 nb = EndianU32_NtoB(n); lprintf("scalar event parm failed: %4.4s, %d\n", (char*)&n, e); return r; }
OSErr QTDR_AddInitDataDataRefExtension (Handle theDataRef, Ptr theInitDataPtr) { unsigned long myAtomHeader[2]; OSErr myErr = noErr; if (theInitDataPtr == NULL) return(paramErr); myAtomHeader[0] = EndianU32_NtoB(sizeof(myAtomHeader) + GetPtrSize(theInitDataPtr)); myAtomHeader[1] = EndianU32_NtoB(kDataRefExtensionInitializationData); myErr = PtrAndHand(myAtomHeader, theDataRef, sizeof(myAtomHeader)); if (myErr == noErr) myErr = PtrAndHand(theInitDataPtr, theDataRef, GetPtrSize(theInitDataPtr)); return(myErr); }
OSErr QTDR_AddMIMETypeDataRefExtension (Handle theDataRef, StringPtr theMIMEType) { unsigned long myAtomHeader[2]; OSErr myErr = noErr; if (theMIMEType == NULL) return(paramErr); myAtomHeader[0] = EndianU32_NtoB(sizeof(myAtomHeader) + theMIMEType[0] + 1); myAtomHeader[1] = EndianU32_NtoB(kDataRefExtensionMIMEType); myErr = PtrAndHand(myAtomHeader, theDataRef, sizeof(myAtomHeader)); if (myErr == noErr) myErr = PtrAndHand(theMIMEType, theDataRef, theMIMEType[0] + 1); return(myErr); }
OSErr QTDR_AddMacOSFileTypeDataRefExtension (Handle theDataRef, OSType theType) { unsigned long myAtomHeader[2]; OSType myType; OSErr myErr = noErr; myAtomHeader[0] = EndianU32_NtoB(sizeof(myAtomHeader) + sizeof(theType)); myAtomHeader[1] = EndianU32_NtoB(kDataRefExtensionMacOSFileType); myType = EndianU32_NtoB(theType); myErr = PtrAndHand(myAtomHeader, theDataRef, sizeof(myAtomHeader)); if (myErr == noErr) myErr = PtrAndHand(&myType, theDataRef, sizeof(myType)); return(myErr); }
void print_event(EventRef evt) { uint32 cl = EndianU32_NtoB(GetEventClass(evt)); uint32 ki = /*EndianU32_NtoB*/(GetEventKind(evt)); lprintf("Event class: %4.4s kind: %d ", (char*)&cl, ki); lprintf("\tbtn: 0x%x ", get_scalar_event_parm(evt, kEventParamMouseButton, typeMouseButton)); // lprintf("\ttarg: 0x%x\n", get_scalar_event_parm(evt, kEventParamDirectObject, typeWildCard)); lprintf("\ttarg: 0x%x ", get_scalar_event_parm(evt, kEventParamPostTarget, typeEventTargetRef)); lprintf("\twind: 0x%x ", get_scalar_event_parm(evt, kEventParamWindowRef, typeWindowRef)); lprintf("\tgrafport: 0x%x\n", get_scalar_event_parm(evt, kEventParamGrafPort, typeGrafPtr)); }
static void ASBD_NtoB(const AudioStreamBasicDescription *infmt, AudioStreamBasicDescription *outfmt) { *(UInt64 *)&outfmt->mSampleRate = EndianU64_NtoB(*(UInt64 *)&infmt->mSampleRate); outfmt->mFormatID = EndianU32_NtoB(infmt->mFormatID); outfmt->mFormatFlags = EndianU32_NtoB(infmt->mFormatFlags); outfmt->mBytesPerPacket = EndianU32_NtoB(infmt->mBytesPerPacket); outfmt->mFramesPerPacket = EndianU32_NtoB(infmt->mFramesPerPacket); outfmt->mBytesPerFrame = EndianU32_NtoB(infmt->mBytesPerFrame); outfmt->mChannelsPerFrame = EndianU32_NtoB(infmt->mChannelsPerFrame); outfmt->mBitsPerChannel = EndianU32_NtoB(infmt->mBitsPerChannel); }
int process_first_packet__speex(StreamInfo *si, ogg_page *op, ogg_packet *opckt) { unsigned long serialnoatom[3] = { EndianU32_NtoB(sizeof(serialnoatom)), EndianU32_NtoB(kCookieTypeOggSerialNo), EndianS32_NtoB(ogg_page_serialno(op)) }; unsigned long atomhead[2] = { EndianU32_NtoB(opckt->bytes + sizeof(atomhead)), EndianU32_NtoB(kCookieTypeSpeexHeader) }; SpeexHeader *inheader = (SpeexHeader *) opckt->packet; si->si_speex.header.bitrate = EndianS32_LtoN(inheader->bitrate); si->si_speex.header.extra_headers = EndianS32_LtoN(inheader->extra_headers); si->si_speex.header.frame_size = EndianS32_LtoN(inheader->frame_size); si->si_speex.header.frames_per_packet = EndianS32_LtoN(inheader->frames_per_packet); si->si_speex.header.header_size = EndianS32_LtoN(inheader->header_size); si->si_speex.header.mode = EndianS32_LtoN(inheader->mode); si->si_speex.header.mode_bitstream_version = EndianS32_LtoN(inheader->mode_bitstream_version); si->si_speex.header.nb_channels = EndianS32_LtoN(inheader->nb_channels); si->si_speex.header.rate = EndianS32_LtoN(inheader->rate); si->si_speex.header.reserved1 = EndianS32_LtoN(inheader->reserved1); si->si_speex.header.reserved2 = EndianS32_LtoN(inheader->reserved2); si->si_speex.header.speex_version_id = EndianS32_LtoN(inheader->speex_version_id); si->si_speex.header.vbr = EndianS32_LtoN(inheader->vbr); //si->si_speex.header. = EndianS32_LtoN(inheader->); dbg_printf("! -- - speex_first_packet: ch: %d, rate: %ld\n", si->si_speex.header.nb_channels, si->si_speex.header.rate); si->numChannels = si->si_speex.header.nb_channels; si->rate = si->si_speex.header.rate; //si->lastMediaInserted = 0; si->mediaLength = 0; PtrAndHand(serialnoatom, si->soundDescExtension, sizeof(serialnoatom)); //check errors? PtrAndHand(atomhead, si->soundDescExtension, sizeof(atomhead)); //check errors? PtrAndHand(opckt->packet, si->soundDescExtension, opckt->bytes); //check errors? si->si_speex.state = kSStateReadingComments; return 0; };
char *OSTypeToStr(char *buf, OSType t) { char *p = buf; char str[4], *q = str; *(UInt32 *)str = EndianU32_NtoB(t); for (int i = 0; i < 4; ++i) { if (isprint(*q) && *q != '\\') *p++ = *q++; else { sprintf(p, "\\x%02x", *q++); p += 4; } } *p = '\0'; return buf; }
static void set_instrument(MidiEvent *ev) { long instrumentNumber; int ch = ev->channel; channel[ch].program = ev->a; if(drum_part[ch]){ if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 2) // SC-88 Map instrumentNumber = kFirstDrumkit + sc88_drum_kit[ev->a] + 1; else if(play_system_mode == GS_SYSTEM_MODE && channel[ch].bank_lsb == 3) // SC-88Pro Map instrumentNumber = kFirstDrumkit + sc88pro_drum_kit[ev->a] + 1; else instrumentNumber = kFirstDrumkit + ev->a + 1; } else { if(play_system_mode == GS_SYSTEM_MODE) instrumentNumber = kFirstGSInstrument + (channel[ch].bank_msb<<7) + ev->a; else if(play_system_mode == XG_SYSTEM_MODE) instrumentNumber = xg_instrument_number(ch, ev->a); else instrumentNumber = kFirstGMInstrument + ev->a; } if(instrument_number[ch] != instrumentNumber){ NoteRequest nr; long index, part; OSType synthType; Str31 name; SynthesizerConnections connections; MusicComponent mc; instrument_number[ch] = instrumentNumber; if(note_channel[ch] != NULL) NADisposeNoteChannel(gNoteAllocator, note_channel[ch]); nr.info.flags = 0; nr.info.reserved = 0; *(short *)(&nr.info.polyphony) = EndianS16_NtoB(8); // 8 voices poliphonic *(Fixed *)(&nr.info.typicalPolyphony) = EndianU32_NtoB(0x00010000); NAStuffToneDescription(gNoteAllocator, instrumentNumber, &nr.tone); NANewNoteChannel(gNoteAllocator, &nr, ¬e_channel[ch]); NAGetNoteChannelInfo(gNoteAllocator, note_channel[ch], &index, &part); NAGetRegisteredMusicDevice(gNoteAllocator, index, &synthType, name, &connections, &mc); MusicGetPartName(mc, part, name); p2cstrcpy(instrument_name[ch], name); } ctl_prog_event(ch, ev->a); }
void send_movie_changed_notification(Movie movie) { QTAtomContainer container; if(QTNewAtomContainer(&container) == noErr) { QTAtom anAction; OSType whichAction = EndianU32_NtoB(kActionMovieChanged); OSErr err = QTInsertChild(container, kParentAtomIsContainer, kAction, 1, 0, 0, NULL, &anAction); if(err == noErr) err = QTInsertChild(container, anAction, kWhichAction, 1, 0, sizeof(whichAction), &whichAction, NULL); if(err == noErr) MovieExecuteWiredActions(movie, 0, container); QTDisposeAtomContainer(container); } }
// Create the 'nclc' atom for video tracks. Guessed entirely from image size following ffdshow. // FIXME: read H.264 VUI/MPEG2 etc and especially read chroma positioning information. // this needs the parsers working // References: http://developer.apple.com/quicktime/icefloe/dispatch019.html // http://www.mir.com/DMG/chroma.html void set_track_colorspace_ext(ImageDescriptionHandle imgDescHandle, Fixed displayW, Fixed displayH) { ImageDescription *imgDesc = *imgDescHandle; Boolean isHd, isPAL; // otherwise NTSC AVRational palRatio = (AVRational) {5, 4}, displayRatio = (AVRational) { displayW, displayH }; int colorPrimaries, transferFunction, yuvMatrix; isHd = imgDesc->height > 576; isPAL = imgDesc->height == 576 || av_cmp_q(palRatio, displayRatio) == 0; NCLCColorInfoImageDescriptionExtension **nclc = (NCLCColorInfoImageDescriptionExtension**)NewHandle(sizeof(NCLCColorInfoImageDescriptionExtension)); if (isHd) { colorPrimaries = kQTPrimaries_ITU_R709_2; transferFunction = kQTTransferFunction_ITU_R709_2; yuvMatrix = kQTMatrix_ITU_R_709_2; } else if (isPAL) { colorPrimaries = kQTPrimaries_EBU_3213; transferFunction = kQTTransferFunction_ITU_R709_2; yuvMatrix = kQTMatrix_ITU_R_601_4; } else { colorPrimaries = kQTPrimaries_SMPTE_C; transferFunction = kQTTransferFunction_ITU_R709_2; yuvMatrix = kQTMatrix_ITU_R_601_4; } **nclc = (NCLCColorInfoImageDescriptionExtension) { EndianU32_NtoB(kVideoColorInfoImageDescriptionExtensionType), EndianU16_NtoB(colorPrimaries), EndianU16_NtoB(transferFunction), EndianU16_NtoB(yuvMatrix) }; AddImageDescriptionExtension(imgDescHandle, (Handle)nclc, kColorInfoImageDescriptionExtension); DisposeHandle((Handle)nclc); }
static OSErr SpriteUtils_SetImageGroupID (QTAtomContainer theKeySample, QTAtom theImagesContainerAtom, short theImageIndex, long theGroupID) { QTAtom myImageAtom, myImageGroupAtom; OSErr myErr = noErr; myImageAtom = QTFindChildByIndex(theKeySample, theImagesContainerAtom, kSpriteImageAtomType, theImageIndex, NULL); if (myImageAtom == 0) { myErr = cannotFindAtomErr; goto bail; } myImageGroupAtom = QTFindChildByIndex(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, NULL); if (myImageGroupAtom == 0) { myErr = QTInsertChild(theKeySample, myImageAtom, kSpriteImageGroupIDAtomType, 1, 1, 0, NULL, &myImageGroupAtom); if (myErr != noErr) goto bail; } theGroupID = EndianU32_NtoB(theGroupID); myErr = QTSetAtomData(theKeySample, myImageGroupAtom, sizeof(theGroupID), &theGroupID); bail: return(myErr); }
boolean ploticonfromodb (const Rect *r, short align, short transform, bigstring bsadricon) { #if defined (MACVERSION) //bigstring bsadricon = "\psystem.verbs.builtins.Frontier.tools.data.nodeTypes.link.icon.mac"; IconRef iconRef; IconFamilyHandle iconHand; SInt32 theSize; OSStatus theErr; Handle hicon; bigstring bsadriconpart; theErr = noErr; theSize = sizeof(OSType) + sizeof(OSType); newhandle(theSize, (Handle*) &iconHand); //iconHand = (IconFamilyHandle) getnewhandle(theSize, false); if (iconHand == NULL) theErr = memFullErr; if (theErr == noErr) { (*iconHand)->resourceType = EndianU32_NtoB(kIconFamilyType); (*iconHand)->resourceSize = EndianU32_NtoB(theSize); } if (theErr == noErr) { setemptystring(bsadriconpart); copystring(bsadricon, bsadriconpart); pushstring(BIGSTRING("\x05" ".ics4"), bsadriconpart); theErr = loadicondatafromodb(bsadriconpart, BIGSTRING("\x04" "ics4"), &hicon); if (theErr == noErr) { theErr = SetIconFamilyData(iconHand, kSmall4BitData, hicon); disposehandle(hicon); } } if (theErr == noErr) { setemptystring(bsadriconpart); copystring(bsadricon, bsadriconpart); pushstring(BIGSTRING("\x05" ".ics8"), bsadriconpart); theErr = loadicondatafromodb(bsadriconpart, BIGSTRING("\x04" "ics8"), &hicon); if (theErr == noErr) { theErr = SetIconFamilyData(iconHand, kSmall8BitData, hicon); disposehandle(hicon); } } if (theErr == noErr) { setemptystring(bsadriconpart); copystring(bsadricon, bsadriconpart); pushstring(BIGSTRING("\x09" ".icspound"), bsadriconpart); theErr = loadicondatafromodb(bsadriconpart, BIGSTRING("\x08" "icspound"), &hicon); if (theErr == noErr) { theErr = SetIconFamilyData(iconHand, kSmall1BitMask, hicon); disposehandle(hicon); } } if (theErr == noErr) { theErr = GetIconRefFromIconFamilyPtr(*iconHand, GetHandleSize((Handle) iconHand), &iconRef); } if (theErr == noErr) { theErr = PlotIconRef(r, align, transform, kIconServicesNormalUsageFlag, iconRef); } setemptystring(bsadriconpart); ReleaseIconRef(iconRef); disposehandle((Handle) iconHand); return theErr == noErr; #else if defined (WIN95VERSION) return FALSE; #endif }
OSErr QTWired_MakeSpriteDraggable (QTAtomContainer theContainer, QTAtomID theID) { QTAtom mySpriteAtom = 0; QTAtom myEventAtom = 0; QTAtom myActionAtom = 0; QTAtom myParamAtom = 0; QTAtom myConditionalAtom, myExpressionAtom, myOperatorAtom, myOperandAtom, myOperandTypeAtom, myActionListAtom, myParameterAtom; short myOperandIndex; long myAction; QTAtomID myVariableID; float myVariableValue; float myConstantValue; Boolean myIsAbsolute; OSErr myErr = noErr; // find the sprite atom with the specified ID in the specified container mySpriteAtom = QTFindChildByID(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, NULL); if (mySpriteAtom == 0) { // if there is none, insert a new sprite atom into the specified container myErr = QTInsertChild(theContainer, kParentAtomIsContainer, kSpriteAtomType, theID, 1, 0, NULL, &mySpriteAtom); if (myErr != noErr) goto bail; } ////////// // // add a mouse click event handler // ////////// // find the event atom of type kQTEventMouseClick in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClick, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventMouseClick into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClick, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTrackSetVariable); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add parameters to the set variable action: variable ID (QTAtomID) and value (float) myVariableID = EndianU32_NtoB(kMouseStateVariableID); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; myVariableValue = (float)1; EndianUtils_Float_NtoB(&myVariableValue); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, sizeof(myVariableValue), &myVariableValue, NULL); if (myErr != noErr) goto bail; ////////// // // add a mouse click end event handler // ////////// // find the event atom of type kQTEventMouseClick in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClickEnd, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventMouseClick into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventMouseClickEnd, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTrackSetVariable); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add parameters to the set variable action: variable ID (QTAtomID) and value (float) myVariableID = EndianU32_NtoB(kMouseStateVariableID); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; myVariableValue = (float)0; EndianUtils_Float_NtoB(&myVariableValue); myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, sizeof(myVariableValue), &myVariableValue, NULL); if (myErr != noErr) goto bail; ////////// // // add an idle event handler // ////////// // find the event atom of type kQTEventIdle in the sprite atom myEventAtom = QTFindChildByID(theContainer, mySpriteAtom, kQTEventType, kQTEventIdle, NULL); if (myEventAtom == 0) { // if there is none, insert a new event atom of type kQTEventIdle into the sprite atom myErr = QTInsertChild(theContainer, mySpriteAtom, kQTEventType, kQTEventIdle, 1, 0, NULL, &myEventAtom); if (myErr != noErr) goto bail; } // add an action atom to the mouse click event handler myErr = QTInsertChild(theContainer, myEventAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionCase); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; // add a parameter atom to the kActionCase action atom; this will serve as a parent to hold the expression and action atoms myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 1, kFirstParam, 0, NULL, &myParamAtom); if (myErr != noErr) goto bail; // the condition atom myErr = QTInsertChild(theContainer, myParamAtom, kConditionalAtomType, 0, 1, 0, NULL, &myConditionalAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myConditionalAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperatorAtomType, kOperatorEqualTo, 1, 0, NULL, &myOperatorAtom); if (myErr != noErr) goto bail; // add the operands to the operator atom myOperandIndex = 1; myConstantValue = 1; myErr = QTInsertChild(theContainer, myOperatorAtom, kOperandAtomType, 0, myOperandIndex, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandConstant, 1, 1, 0, NULL, &myOperandTypeAtom); if (myErr != noErr) goto bail; EndianUtils_Float_NtoB(&myConstantValue); myErr = QTSetAtomData(theContainer, myOperandTypeAtom, sizeof(myConstantValue), &myConstantValue); myOperandIndex = 2; myVariableID = kMouseStateVariableID; myErr = QTInsertChild(theContainer, myOperatorAtom, kOperandAtomType, 0, myOperandIndex, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandSpriteTrackVariable, 1, 1, 0, NULL, &myOperandTypeAtom); if (myErr != noErr) goto bail; myVariableID = EndianU32_NtoB(myVariableID); myErr = QTInsertChild(theContainer, myOperandTypeAtom, kActionParameter, 1, 1, sizeof(myVariableID), &myVariableID, NULL); if (myErr != noErr) goto bail; // add an action list atom myErr = QTInsertChild(theContainer, myConditionalAtom, kActionListAtomType, 1, 1, 0, NULL, &myActionListAtom); if (myErr != noErr) goto bail; // add sprite translate action myErr = QTInsertChild(theContainer, myActionListAtom, kAction, 0, 0, 0, NULL, &myActionAtom); if (myErr != noErr) goto bail; myAction = EndianU32_NtoB(kActionSpriteTranslate); myErr = QTInsertChild(theContainer, myActionAtom, kWhichAction, 1, 1, sizeof(myAction), &myAction, NULL); if (myErr != noErr) goto bail; ////////// // // add parameters to the translate action: Fixed x, Fixed y, Boolean isAbsolute // ////////// // first parameter: get current mouse position x myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kFirstParam, 0, NULL, &myParameterAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myParameterAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandMouseLocalHLoc, 1, 1, 0, NULL, NULL); if (myErr != noErr) goto bail; // second parameter: get current mouse position y myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kSecondParam, 0, NULL, &myParameterAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myParameterAtom, kExpressionContainerAtomType, 1, 1, 0, NULL, &myExpressionAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myExpressionAtom, kOperandAtomType, 0, 1, 0, NULL, &myOperandAtom); if (myErr != noErr) goto bail; myErr = QTInsertChild(theContainer, myOperandAtom, kOperandMouseLocalVLoc, 1, 1, 0, NULL, NULL); if (myErr != noErr) goto bail; myIsAbsolute = true; myErr = QTInsertChild(theContainer, myActionAtom, kActionParameter, 0, (short)kThirdParam, sizeof(myIsAbsolute), &myIsAbsolute, NULL); bail: return(myErr); }
OSErr QTWired_CreateWiredSpritesMovie (void) { short myResRefNum = 0; short myResID = movieInDataForkResID; Movie myMovie = NULL; Track myTrack; Media myMedia; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kWiredSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kWiredSaveFileName); QTAtomContainer mySample = NULL; QTAtomContainer myActions = NULL; QTAtomContainer myBeginButton, myPrevButton, myNextButton, myEndButton; QTAtomContainer myPenguinOne, myPenguinTwo, myPenguinOneOverride; QTAtomContainer myBeginActionButton, myPrevActionButton, myNextActionButton, myEndActionButton; QTAtomContainer myPenguinOneAction, myPenguinTwoAction; RGBColor myKeyColor; Point myLocation; short isVisible, myLayer, myIndex, myID, i, myDelta; Boolean hasActions; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; OSType myType = FOUR_CHAR_CODE('none'); UInt32 myFrequency; QTAtom myEventAtom; long myLoopingFlags; ModifierTrackGraphicsModeRecord myGraphicsMode; OSErr myErr = noErr; ////////// // // create a new movie file and set its controller type // ////////// // ask the user for the name of the new movie file QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // select the "no controller" movie controller myType = EndianU32_NtoB(myType); SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); ////////// // // create the sprite track and media // ////////// myTrack = NewMovieTrack(myMovie, ((long)kSpriteTrackWidth << 16), ((long)kSpriteTrackHeight << 16), kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0); ////////// // // create a key frame sample containing six sprites and all of their shared images // ////////// // create a new, empty key frame sample myErr = QTNewAtomContainer(&mySample); if (myErr != noErr) goto bail; myKeyColor.red = 0xffff; // white myKeyColor.green = 0xffff; myKeyColor.blue = 0xffff; // add images to the key frame sample SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonUp, &myKeyColor, kGoToBeginningButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToBeginningButtonDown, &myKeyColor, kGoToBeginningButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonUp, &myKeyColor, kGoToEndButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToEndButtonDown, &myKeyColor, kGoToEndButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonUp, &myKeyColor, kGoToPrevButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToPrevButtonDown, &myKeyColor, kGoToPrevButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonUp, &myKeyColor, kGoToNextButtonUpIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kGoToNextButtonDown, &myKeyColor, kGoToNextButtonDownIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinForward, &myKeyColor, kPenguinForwardIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinLeft, &myKeyColor, kPenguinLeftIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinRight, &myKeyColor, kPenguinRightIndex, NULL, NULL); SpriteUtils_AddPICTImageToKeyFrameSample(mySample, kPenguinClosed, &myKeyColor, kPenguinClosedIndex, NULL, NULL); for (myIndex = kPenguinDownRightCycleStartIndex, myID = kWalkDownRightCycleStart; myIndex <= kPenguinDownRightCycleEndIndex; myIndex++, myID++) SpriteUtils_AddPICTImageToKeyFrameSample(mySample, myID, &myKeyColor, myIndex, NULL, NULL); // assign group IDs to the images SpriteUtils_AssignImageGroupIDsToKeyFrame(mySample); ////////// // // add samples to the sprite track's media // ////////// BeginMediaEdits(myMedia); // go to beginning button with no actions myErr = QTNewAtomContainer(&myBeginButton); if (myErr != noErr) goto bail; myLocation.h = (1 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToBeginningButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myBeginButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to previous button with no actions myErr = QTNewAtomContainer(&myPrevButton); if (myErr != noErr) goto bail; myLocation.h = (3 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToPrevButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myPrevButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to next button with no actions myErr = QTNewAtomContainer(&myNextButton); if (myErr != noErr) goto bail; myLocation.h = (5 * kSpriteTrackWidth / 8) - (kNextPrevButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToNextButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myNextButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // go to end button with no actions myErr = QTNewAtomContainer(&myEndButton); if (myErr != noErr) goto bail; myLocation.h = (7 * kSpriteTrackWidth / 8) - (kStartEndButtonWidth / 2); myLocation.v = (4 * kSpriteTrackHeight / 5) - (kStartEndButtonHeight / 2); isVisible = false; myLayer = 1; myIndex = kGoToEndButtonUpIndex; myErr = SpriteUtils_SetSpriteData(myEndButton, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; // first penguin sprite with no actions myErr = QTNewAtomContainer(&myPenguinOne); if (myErr != noErr) goto bail; myLocation.h = (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); isVisible = true; myLayer = 2; myIndex = kPenguinDownRightCycleStartIndex; myGraphicsMode.graphicsMode = blend; myGraphicsMode.opColor.red = myGraphicsMode.opColor.green = myGraphicsMode.opColor.blue = 0x8FFF; // grey myErr = SpriteUtils_SetSpriteData(myPenguinOne, &myLocation, &isVisible, &myLayer, &myIndex, &myGraphicsMode, NULL, myActions); if (myErr != noErr) goto bail; // second penguin sprite with no actions myErr = QTNewAtomContainer(&myPenguinTwo); if (myErr != noErr) goto bail; myLocation.h = (5 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); isVisible = true; myLayer = 3; myIndex = kPenguinForwardIndex; myErr = SpriteUtils_SetSpriteData(myPenguinTwo, &myLocation, &isVisible, &myLayer, &myIndex, NULL, NULL, myActions); if (myErr != noErr) goto bail; ////////// // // add actions to the six sprites // ////////// // add go to beginning button myErr = QTCopyAtom(myBeginButton, kParentAtomIsContainer, &myBeginActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToBeginningButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToBeginningButtonUpIndex, NULL); WiredUtils_AddMovieGoToBeginningAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myBeginActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myBeginActionButton, kGoToBeginningSpriteID); QTDisposeAtomContainer(myBeginActionButton); // add go to prev button myErr = QTCopyAtom(myPrevButton, kParentAtomIsContainer, &myPrevActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToPrevButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToPrevButtonUpIndex, NULL); WiredUtils_AddMovieStepBackwardAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPrevActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myPrevActionButton, kGoToPrevSpriteID); QTDisposeAtomContainer(myPrevActionButton); // add go to next button myErr = QTCopyAtom(myNextButton, kParentAtomIsContainer, &myNextActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToNextButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToNextButtonUpIndex, NULL); WiredUtils_AddMovieStepForwardAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myNextActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myNextActionButton, kGoToNextSpriteID); QTDisposeAtomContainer(myNextActionButton); // add go to end button myErr = QTCopyAtom(myEndButton, kParentAtomIsContainer, &myEndActionButton); if (myErr != noErr) goto bail; WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kGoToEndButtonDownIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kGoToEndButtonUpIndex, NULL); WiredUtils_AddMovieGoToEndAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton); WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, 0, NULL, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myEndActionButton, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, 0, NULL, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myEndActionButton, kGoToEndSpriteID); QTDisposeAtomContainer(myEndActionButton); // add penguin one myErr = QTCopyAtom(myPenguinOne, kParentAtomIsContainer, &myPenguinOneAction); if (myErr != noErr) goto bail; // show the buttons on mouse enter and hide them on mouse exit WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToBeginningSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToPrevSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToNextSpriteID, false, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseEnter, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, true, NULL); WiredUtils_AddSpriteSetVisibleAction(myPenguinOneAction, kParentAtomIsContainer, kQTEventMouseExit, 0, NULL, 0, kTargetSpriteID, (void *)kGoToEndSpriteID, false, NULL); SpriteUtils_AddSpriteToSample(mySample, myPenguinOneAction, kPenguinOneSpriteID); QTWired_AddCursorChangeOnMouseOver(mySample, kPenguinOneSpriteID); QTDisposeAtomContainer(myPenguinOneAction); // add penguin two myErr = QTCopyAtom(myPenguinTwo, kParentAtomIsContainer, &myPenguinTwoAction); if (myErr != noErr) goto bail; // blink when clicked on WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClick, 0, NULL, 0, 0, NULL, kPenguinClosedIndex, NULL); WiredUtils_AddSpriteSetImageIndexAction(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEnd, 0, NULL, 0, 0, NULL, kPenguinForwardIndex, NULL); WiredUtils_AddQTEventAtom(myPenguinTwoAction, kParentAtomIsContainer, kQTEventMouseClickEndTriggerButton, &myEventAtom); // toggle the movie rate and both of the birds' graphics modes QTWired_AddPenguinTwoConditionalActions(myPenguinTwoAction, myEventAtom); QTWired_AddWraparoundMatrixOnIdle(myPenguinTwoAction); SpriteUtils_AddSpriteToSample(mySample, myPenguinTwoAction, kPenguinTwoSpriteID); QTDisposeAtomContainer(myPenguinTwoAction); // add an action for when the key frame is loaded, to set the movie's looping mode to palindrome; // note that this will actually be triggered every time the key frame is reloaded, // so if the operation was expensive we could use a conditional to test if we've already done it myLoopingFlags = loopTimeBase | palindromeLoopTimeBase; WiredUtils_AddMovieSetLoopingFlagsAction(mySample, kParentAtomIsContainer, kQTEventFrameLoaded, myLoopingFlags); // add the key frame sample to the sprite track media // // to add the sample data in a compressed form, you would use a QuickTime DataCodec to perform the // compression; replace the call to the utility AddSpriteSampleToMedia with a call to the utility // AddCompressedSpriteSampleToMedia to do this SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, NULL); //SpriteUtils_AddCompressedSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, true, zlibDataCompressorSubType, NULL); ////////// // // add a few override samples to move penguin one and change its image index // ////////// // original penguin one location myLocation.h = (3 * kSpriteTrackWidth / 8) - (kPenguinWidth / 2); myLocation.v = (kSpriteTrackHeight / 4) - (kPenguinHeight / 2); myDelta = (kSpriteTrackHeight / 2) / kNumOverrideSamples; myIndex = kPenguinDownRightCycleStartIndex; for (i = 1; i <= kNumOverrideSamples; i++) { QTRemoveChildren(mySample, kParentAtomIsContainer); QTNewAtomContainer(&myPenguinOneOverride); myLocation.h += myDelta; myLocation.v += myDelta; myIndex++; if (myIndex > kPenguinDownRightCycleEndIndex) myIndex = kPenguinDownRightCycleStartIndex; SpriteUtils_SetSpriteData(myPenguinOneOverride, &myLocation, NULL, NULL, &myIndex, NULL, NULL, NULL); SpriteUtils_AddSpriteToSample(mySample, myPenguinOneOverride, kPenguinOneSpriteID); SpriteUtils_AddSpriteSampleToMedia(myMedia, mySample, kSpriteMediaFrameDuration, false, NULL); QTDisposeAtomContainer(myPenguinOneOverride); } EndMediaEdits(myMedia); // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// { QTAtomContainer myTrackProperties; RGBColor myBackgroundColor; // add a background color to the sprite track myBackgroundColor.red = EndianU16_NtoB(0x8000); myBackgroundColor.green = EndianU16_NtoB(0); myBackgroundColor.blue = EndianU16_NtoB(0xffff); QTNewAtomContainer(&myTrackProperties); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyBackgroundColor, 1, 1, sizeof(RGBColor), &myBackgroundColor, NULL); // tell the movie controller that this sprite track has actions, Jackson hasActions = true; QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyHasActions, 1, 1, sizeof(hasActions), &hasActions, NULL); // tell the sprite track to generate QTIdleEvents myFrequency = EndianU32_NtoB(2); QTInsertChild(myTrackProperties, 0, kSpriteTrackPropertyQTIdleEventsFrequency, 1, 1, sizeof(myFrequency), &myFrequency, NULL); myErr = SetMediaPropertyAtom(myMedia, myTrackProperties); if (myErr != noErr) goto bail; QTDisposeAtomContainer(myTrackProperties); } ////////// // // finish up // ////////// // add the movie resource to the movie file myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); bail: free(myPrompt); free(myFileName); if (mySample != NULL) QTDisposeAtomContainer(mySample); if (myBeginButton != NULL) QTDisposeAtomContainer(myBeginButton); if (myPrevButton != NULL) QTDisposeAtomContainer(myPrevButton); if (myNextButton != NULL) QTDisposeAtomContainer(myNextButton); if (myEndButton != NULL) QTDisposeAtomContainer(myEndButton); if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myMovie != NULL) DisposeMovie(myMovie); return(myErr); }
void QTVectors_CreateVectorMovie (UInt32 theBuildAtomMethod) { Handle myHandle = NULL; ImageDescriptionHandle mySampleDesc = NULL; short myResRefNum = 0; short myResID = movieInDataForkResID; Movie myMovie = NULL; Track myTrack; Media myMedia; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kVectorSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kVectorSaveMovieFileName); ComponentInstance myComponent; ComponentResult myResult; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; OSErr myErr = noErr; // METHOD ONE: use a raw data stream if (theBuildAtomMethod == kUseRawDataStream) { // kUseRawDataStream: build the vector data using a stream of hard-coded raw data // NOTE: the data in the stream *must* be big-endian, since it's stored in a QuickTime atom container. long myPath[] = { EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveAntialiasControlAtom), EndianU32_NtoB(kCurveAntialiasOn), EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveFillTypeAtom), EndianU32_NtoB(gxEvenOddFill), // a big white enclosing rectangle (600 x 600) EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom), EndianU32_NtoB(0xffffffff), // alpha, red EndianU32_NtoB(0xffffffff), // green, blue // it's white! EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom), EndianU32_NtoB(1), // one contour in path EndianU32_NtoB(4), // four points in path EndianU32_NtoB(0x00000000), // all points are on the curve: it's a rectangle! EndianU32_NtoB(0x00000000), EndianU32_NtoB(0x00000000), // top left EndianU32_NtoB(0x02580000), EndianU32_NtoB(0x00000000), // top right EndianU32_NtoB(0x02580000), EndianU32_NtoB(0x02580000), // bottom right EndianU32_NtoB(0x00000000), EndianU32_NtoB(0x02580000), // bottom left // a black rounded square, centered at 150,150 EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom), EndianU32_NtoB(0x00000000), // alpha, red EndianU32_NtoB(0x00000000), // green, blue // it's black! EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom), EndianU32_NtoB(1), // one contour in path EndianU32_NtoB(4), // four points in path EndianU32_NtoB(0xffffffff), // all points are off the curve: it's a rounded square! EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00C80000), EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00C80000), EndianU32_NtoB(0x00C80000), EndianU32_NtoB(0x00640000), EndianU32_NtoB(0x00C80000), EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveFillTypeAtom), EndianU32_NtoB(gxEvenOddFill), EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurvePenThicknessAtom), EndianU32_NtoB(0x100000), // enable linear gradient for all following atoms EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveGradientTypeAtom), EndianU32_NtoB(kLinearGradient), // define the gradient: red -> green -> red -> blue EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(GradientColorRecord)*4), EndianU32_NtoB(kCurveGradientRecordAtom), EndianU32_NtoB(0xffffffff), // gradient color record 1: EndianU32_NtoB(0x00000000), // red EndianU32_NtoB(0x00000000), // beginning of gradient EndianU32_NtoB(0x77770000), // gradient color record 2: EndianU32_NtoB(0xffff0000), // green EndianU32_NtoB(0x00004000), EndianU32_NtoB(0x3333ffff), // gradient color record 3: EndianU32_NtoB(0x00000000), // red EndianU32_NtoB(0x0000C000), EndianU32_NtoB(0xffff0000), // gradient color record 4: EndianU32_NtoB(0x0000ffff), // blue EndianU32_NtoB(0x00010000), // end of gradient EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)), EndianU32_NtoB(kCurveGradientAngleAtom), EndianU32_NtoB(0x00450000), // gradient at 45û angle // a green rectangle, centered at 40,40, painted with a linear gradient EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom), EndianU32_NtoB(0x00000000), // alpha, red EndianU32_NtoB(0xffff0000), // green, blue // it's green! EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom), EndianU32_NtoB(1), // one contour in path EndianU32_NtoB(4), // four points in path EndianU32_NtoB(0x00000000), // all points are on the curve: it's a rectangle! EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00400000), EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00400000), EndianU32_NtoB(0x00400000), EndianU32_NtoB(0x00100000), EndianU32_NtoB(0x00400000), // disable gradient for all following atoms (since no atom data) EndianU32_NtoB(kSizeOfSizeAndTagFields), EndianU32_NtoB(kCurveGradientRecordAtom), // a red rounded square, centered at 50,50 EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(ARGBColor)), EndianU32_NtoB(kCurveARGBColorAtom), EndianU32_NtoB(0x3333ffff), // alpha, red EndianU32_NtoB(0x00000000), // green, blue // it's red! EndianU32_NtoB(kSizeOfSizeAndTagFields + sizeof(long)*11), EndianU32_NtoB(kCurvePathAtom), EndianU32_NtoB(1L), // one contour in path EndianU32_NtoB(4L), // four points in path EndianU32_NtoB(0xffffffff), // all points are off the curve: it's a rounded square! EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x00460000), EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x00460000), EndianU32_NtoB(0x00460000), EndianU32_NtoB(0x001e0000), EndianU32_NtoB(0x00460000), EndianU32_NtoB(kSizeOfZeroAtomHeader), EndianU32_NtoB(kCurveEndAtom), }; myHandle = NewHandle(sizeof(myPath)); if (myHandle == NULL) goto bail; BlockMove(myPath, *myHandle, sizeof(myPath)); } // end of kUseRawDataStream // METHOD TWO: use the Curve Utilities API if (theBuildAtomMethod == kUseCurveUtilities) { // kUseCurveUtilities: build the vector data using the Curve Utilities API Handle myPath; gxPoint myPoint; long myAtomData[14]; ARGBColor myColor; GradientColorRecord myGradients[4]; // open the vector codec; we'll need it for some subsequent calls myComponent = OpenDefaultComponent(decompressorComponentType, kVectorCodecType); if (myComponent == NULL) goto bail; // create a new, empty vector data stream myResult = CurveCreateVectorStream(myComponent, &myHandle); if (myResult != noErr) goto bail; // now start adding atoms holding the vector data // set antialiasing on myAtomData[0] = EndianU32_NtoB(kCurveAntialiasOn); CurveAddAtomToVectorStream(myComponent, kCurveAntialiasControlAtom, sizeof(long), myAtomData, myHandle); // set fill type myAtomData[0] = EndianU32_NtoB(gxEvenOddFill); CurveAddAtomToVectorStream(myComponent, kCurveFillTypeAtom, sizeof(long), myAtomData, myHandle); // a big white enclosing rectangle (600 x 600) myColor.alpha = EndianU16_NtoB(0xffff); myColor.red = EndianU16_NtoB(0xffff); myColor.green = EndianU16_NtoB(0xffff); myColor.blue = EndianU16_NtoB(0xffff); CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle); #if USE_CURVE_INSERT_POINT_INTO_PATH // create a new, empty path CurveNewPath(myComponent, &myPath); myPoint.x = 0x00000000; myPoint.y = 0x00000000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, true); myPoint.x = 0x02580000; myPoint.y = 0x00000000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, true); myPoint.x = 0x02580000; myPoint.y = 0x02580000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, true); myPoint.x = 0x00000000; myPoint.y = 0x02580000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, true); // add the 'path' atom to the vector data stream CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle); DisposeHandle(myPath); #else myAtomData[0] = EndianU32_NtoB(1L); myAtomData[1] = EndianU32_NtoB(4L); myAtomData[2] = EndianU32_NtoB(0x00000000); myAtomData[3] = EndianU32_NtoB(0x00000000); myAtomData[4] = EndianU32_NtoB(0x00000000); myAtomData[5] = EndianU32_NtoB(0x02580000); myAtomData[6] = EndianU32_NtoB(0x00000000); myAtomData[7] = EndianU32_NtoB(0x02580000); myAtomData[8] = EndianU32_NtoB(0x02580000); myAtomData[9] = EndianU32_NtoB(0x00000000); myAtomData[10] = EndianU32_NtoB(0x02580000); CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle); #endif // a black rounded square, centered at 150,150 myColor.alpha = EndianU16_NtoB(0x0000); myColor.red = EndianU16_NtoB(0x0000); myColor.green = EndianU16_NtoB(0x0000); myColor.blue = EndianU16_NtoB(0x0000); CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle); #if USE_CURVE_INSERT_POINT_INTO_PATH // create a new, empty path CurveNewPath(myComponent, &myPath); myPoint.x = 0x00640000; myPoint.y = 0x00640000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, false); myPoint.x = 0x00C80000; myPoint.y = 0x00640000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, false); myPoint.x = 0x00C80000; myPoint.y = 0x00C80000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, false); myPoint.x = 0x00640000; myPoint.y = 0x00C80000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, false); // add the 'path' atom to the vector data stream CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle); DisposeHandle(myPath); #else myAtomData[0] = EndianU32_NtoB(1L); myAtomData[1] = EndianU32_NtoB(4L); myAtomData[2] = EndianU32_NtoB(0xffffffff); myAtomData[3] = EndianU32_NtoB(0x00640000); myAtomData[4] = EndianU32_NtoB(0x00640000); myAtomData[5] = EndianU32_NtoB(0x00C80000); myAtomData[6] = EndianU32_NtoB(0x00640000); myAtomData[7] = EndianU32_NtoB(0x00C80000); myAtomData[8] = EndianU32_NtoB(0x00C80000); myAtomData[9] = EndianU32_NtoB(0x00640000); myAtomData[10] = EndianU32_NtoB(0x00C80000); CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle); #endif // set fill type myAtomData[0] = EndianU32_NtoB(gxEvenOddFill); CurveAddAtomToVectorStream(myComponent, kCurveFillTypeAtom, sizeof(long), myAtomData, myHandle); // set pen thickness myAtomData[0] = EndianU32_NtoB(0x100000); CurveAddAtomToVectorStream(myComponent, kCurvePenThicknessAtom, sizeof(long), myAtomData, myHandle); // enable linear gradient for all following atoms myAtomData[0] = EndianU32_NtoB(kLinearGradient); CurveAddAtomToVectorStream(myComponent, kCurveGradientTypeAtom, sizeof(long), myAtomData, myHandle); // define the gradient: red -> green -> red -> blue myGradients[0].thisColor.alpha = EndianU16_NtoB(0xffff); myGradients[0].thisColor.red = EndianU16_NtoB(0xffff); myGradients[0].thisColor.green = EndianU16_NtoB(0x0000); myGradients[0].thisColor.blue = EndianU16_NtoB(0x0000); myGradients[0].endingPercentage = EndianU32_NtoB(0x00000000); myGradients[1].thisColor.alpha = EndianU16_NtoB(0x7777); myGradients[1].thisColor.red = EndianU16_NtoB(0x0000); myGradients[1].thisColor.green = EndianU16_NtoB(0xffff); myGradients[1].thisColor.blue = EndianU16_NtoB(0x0000); myGradients[1].endingPercentage = EndianU32_NtoB(0x00004000); myGradients[2].thisColor.alpha = EndianU16_NtoB(0x3333); myGradients[2].thisColor.red = EndianU16_NtoB(0xffff); myGradients[2].thisColor.green = EndianU16_NtoB(0x0000); myGradients[2].thisColor.blue = EndianU16_NtoB(0x0000); myGradients[2].endingPercentage = EndianU32_NtoB(0x0000C000); myGradients[3].thisColor.alpha = EndianU16_NtoB(0xffff); myGradients[3].thisColor.red = EndianU16_NtoB(0x0000); myGradients[3].thisColor.green = EndianU16_NtoB(0x0000); myGradients[3].thisColor.blue = EndianU16_NtoB(0xffff); myGradients[3].endingPercentage = EndianU32_NtoB(0x00010000); CurveAddAtomToVectorStream(myComponent, kCurveGradientRecordAtom, sizeof(GradientColorRecord)*4, myGradients, myHandle); // set gradient angle myAtomData[0] = EndianU32_NtoB(0x00450000); CurveAddAtomToVectorStream(myComponent, kCurveGradientAngleAtom, sizeof(long), myAtomData, myHandle); // a green rectangle, centered at 40,40, painted with a linear gradient myColor.alpha = EndianU16_NtoB(0x0000); myColor.red = EndianU16_NtoB(0x0000); myColor.green = EndianU16_NtoB(0xffff); myColor.blue = EndianU16_NtoB(0x0000); CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle); #if USE_CURVE_INSERT_POINT_INTO_PATH // create a new, empty path CurveNewPath(myComponent, &myPath); myPoint.x = 0x00100000; myPoint.y = 0x00100000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, true); myPoint.x = 0x00400000; myPoint.y = 0x00100000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, true); myPoint.x = 0x00400000; myPoint.y = 0x00400000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, true); myPoint.x = 0x00100000; myPoint.y = 0x00400000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, true); // add the 'path' atom to the vector data stream CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle); DisposeHandle(myPath); #else myAtomData[0] = EndianU32_NtoB(1L); myAtomData[1] = EndianU32_NtoB(4L); myAtomData[2] = EndianU32_NtoB(0x00000000); myAtomData[3] = EndianU32_NtoB(0x00100000); myAtomData[4] = EndianU32_NtoB(0x00100000); myAtomData[5] = EndianU32_NtoB(0x00400000); myAtomData[6] = EndianU32_NtoB(0x00100000); myAtomData[7] = EndianU32_NtoB(0x00400000); myAtomData[8] = EndianU32_NtoB(0x00400000); myAtomData[9] = EndianU32_NtoB(0x00100000); myAtomData[10] = EndianU32_NtoB(0x00400000); CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle); #endif // disable gradient for all following atoms (since no atom data) CurveAddAtomToVectorStream(myComponent, kCurveGradientTypeAtom, 0, NULL, myHandle); // a red rounded square, centered at 50,50 myColor.alpha = EndianU16_NtoB(0x3333); myColor.red = EndianU16_NtoB(0xffff); myColor.green = EndianU16_NtoB(0x0000); myColor.blue = EndianU16_NtoB(0x0000); CurveAddAtomToVectorStream(myComponent, kCurveARGBColorAtom, sizeof(ARGBColor), &myColor, myHandle); #if USE_CURVE_INSERT_POINT_INTO_PATH // create a new, empty path CurveNewPath(myComponent, &myPath); myPoint.x = 0x001e0000; myPoint.y = 0x001e0000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 0, false); myPoint.x = 0x00460000; myPoint.y = 0x001e0000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 1, false); myPoint.x = 0x00460000; myPoint.y = 0x00460000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 2, false); myPoint.x = 0x001e0000; myPoint.y = 0x00460000; CurveInsertPointIntoPath(myComponent, &myPoint, myPath, 0, 3, false); // add the 'path' atom to the vector data stream CurveAddPathAtomToVectorStream(myComponent, myPath, myHandle); DisposeHandle(myPath); #else myAtomData[0] = EndianU32_NtoB(1L); myAtomData[1] = EndianU32_NtoB(4L); myAtomData[2] = EndianU32_NtoB(0xffffffff); myAtomData[3] = EndianU32_NtoB(0x001e0000); myAtomData[4] = EndianU32_NtoB(0x001e0000); myAtomData[5] = EndianU32_NtoB(0x00460000); myAtomData[6] = EndianU32_NtoB(0x001e0000); myAtomData[7] = EndianU32_NtoB(0x00460000); myAtomData[8] = EndianU32_NtoB(0x00460000); myAtomData[9] = EndianU32_NtoB(0x001e0000); myAtomData[10] = EndianU32_NtoB(0x00460000); CurveAddAtomToVectorStream(myComponent, kCurvePathAtom, sizeof(long)*11, myAtomData, myHandle); #endif // add the 'zero' atom to the vector data stream CurveAddZeroAtomToVectorStream(myComponent, myHandle); } // end of kUseCurveUtilities // create the image description mySampleDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); if (mySampleDesc == NULL) goto bail; // fill in the fields of the image description (**mySampleDesc).idSize = sizeof(ImageDescription); (**mySampleDesc).cType = kVectorCodecType; (**mySampleDesc).vendor = kAppleManufacturer; (**mySampleDesc).temporalQuality = codecNormalQuality; (**mySampleDesc).spatialQuality = codecNormalQuality; (**mySampleDesc).width = 300; (**mySampleDesc).height = 300; (**mySampleDesc).hRes = 72L << 16; (**mySampleDesc).vRes = 72L << 16; (**mySampleDesc).dataSize = 0L; (**mySampleDesc).frameCount = 1; (**mySampleDesc).depth = 0; (**mySampleDesc).clutID = -1; // prompt user for new file name QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smCurrentScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // create the vector track and media myTrack = NewMovieTrack(myMovie, FixDiv(300, 1), FixDiv(300, 1), kNoVolume); myMedia = NewTrackMedia(myTrack, VideoMediaType, 600, NULL, 0); // create the vector media sample BeginMediaEdits(myMedia); myErr = AddMediaSample(myMedia, myHandle, 0, GetHandleSize(myHandle), 600, (SampleDescriptionHandle)mySampleDesc, 1, 0, NULL); if (myErr != noErr) goto bail; EndMediaEdits(myMedia); // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); AddMovieResource(myMovie, myResRefNum, &myResID, NULL); bail: free(myPrompt); free(myFileName); if (mySampleDesc != NULL) DisposeHandle((Handle)mySampleDesc); if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myHandle != NULL) DisposeHandle(myHandle); if (myMovie != NULL) DisposeMovie(myMovie); if (myComponent != NULL) CloseComponent(myComponent); }
int main(int argc, const char * argv[]) { #if TARGET_OS_MAC { thread_extended_policy_data_t theFixedPolicy; theFixedPolicy.timeshare = false; // set to true for a non-fixed thread thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT); // We keep a reference to the spawning thread's priority around (initialized in the constructor), // and set the importance of the child thread relative to the spawning thread's priority. thread_precedence_policy_data_t thePrecedencePolicy; thePrecedencePolicy.importance = 63 - 36; thread_policy_set(pthread_mach_thread_np(pthread_self()), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT); } #endif // These are the variables that are set up from the input parsing char* srcFilePath = NULL; char* auPresetFile = NULL; OSType manu, subType, type = 0; UInt32 numFrames = 4096; for (int i = 1; i < argc; ++i) { if (strcmp (argv[i], "-au") == 0) { if ( (i + 3) < argc ) { StrToOSType (argv[i + 1], type); StrToOSType (argv[i + 2], subType); StrToOSType (argv[i + 3], manu); i += 3; } else { printf ("Which Audio Unit:\n%s", usageStr); exit(1); } } else if (strcmp (argv[i], "-i") == 0) { srcFilePath = const_cast<char*>(argv[++i]); } else if (strcmp (argv[i], "-p") == 0) { auPresetFile = const_cast<char*>(argv[++i]); } else if (strcmp (argv[i], "-f") == 0) { sscanf(argv[++i], "%ld", &numFrames); } else { printf ("%s\n", usageStr); exit(1); } } if (!type || !srcFilePath) { printf ("%s\n", usageStr); exit(1); } CAComponentDescription desc(type, subType, manu); CFPropertyListRef presetDict = ReadPresetFromPresetFile(auPresetFile); #pragma mark - #pragma mark __ The driving code #pragma mark - try { CAComponent comp(desc); // CAAUProcessor's constructor throws... so make sure the component is valid if (comp.IsValid() == false) { printf ("Can't Find Component\n"); desc.Print(); exit(1); } CAAUProcessor processor(comp); processor.AU().Comp().Print(); CAAudioFile srcFile; srcFile.Open(srcFilePath); UInt64 numInputSamples = srcFile.GetNumberFrames(); Float64 inputSecs = (numInputSamples / srcFile.GetFileDataFormat().mSampleRate); CAStreamBasicDescription procFormat (srcFile.GetFileDataFormat()); procFormat.SetCanonical (srcFile.GetFileDataFormat().NumberChannels(), false); printf ("Processing file: %s, %.1f secs [proc: %ld frames]\n", srcFilePath, inputSecs, numFrames); #if VERBOSE printf("\t"); procFormat.Print(); #endif srcFile.SetClientFormat (procFormat); AUOutputBL outputList(procFormat); // read the entire file into memory ReadBuffer* readBuf = new ReadBuffer; readBuf->readData = new AUOutputBL(procFormat); readBuf->totalInputFrames = numInputSamples; readBuf->readData->Allocate (numInputSamples); readBuf->readData->Prepare(); UInt32 readSamps = (UInt32)numInputSamples; srcFile.Read (readSamps, readBuf->readData->ABL()); AURenderCallbackStruct inputCallback; inputCallback.inputProc = MemoryInputCallback; inputCallback.inputProcRefCon = readBuf; OSStatus result; require_noerr (result = processor.EstablishInputCallback (inputCallback), home); require_noerr (result = processor.SetMaxFramesPerRender (numFrames), home); require_noerr (result = processor.Initialize (procFormat, numInputSamples), home); if (presetDict) { require_noerr (result = processor.SetAUPreset (presetDict), home); CFRelease (presetDict); } // this does ALL of the preflighting.. could be specialise for an OfflineAU type // to do this piecemeal and do a progress bar by using the OfflineAUPreflight method readBuf->lastInputFrames = 0; require_noerr (result = processor.Preflight (), home); float mean; // now do the processing.... { const int kThrasherSize = 4000000; char* thrasher = new char[kThrasherSize]; bool isDone = false; UInt32 numMeasures = 0; Float64 totalMSqrd = 0; Float64 totalM = 0; int i = 0; int discardResults = 3; // this is the render loop while (!isDone) { bool isSilence, postProcess; outputList.Prepare(); // have to do this every time... readBuf->lastInputFrames = 0; sLastReadTime = 0; memset (thrasher, numMeasures, kThrasherSize); UInt64 now = CAHostTimeBase::GetTheCurrentTime(); require_noerr (result = processor.Render (outputList.ABL(), numFrames, isSilence, &isDone, &postProcess), home); UInt64 renderTime = (CAHostTimeBase::GetTheCurrentTime() - now); if (i++ < discardResults) continue; if (!readBuf->lastInputFrames) break; Float64 renderTimeSecs = CAHostTimeBase::ConvertToNanos (renderTime - sLastReadTime) / 1.0e9; Float64 cpuTime = (renderTimeSecs / (readBuf->lastInputFrames / procFormat.mSampleRate)) * 100.; numMeasures++; totalMSqrd += (cpuTime * cpuTime); totalM += cpuTime; if (cpuTime > sMaxTime) sMaxTime = cpuTime; if (cpuTime < sMinTime) sMinTime = cpuTime; #if VERBOSE // printf ("current measure: %.2f\n", cpuTime); if (numMeasures % 5 == 0) { Float64 mean = totalM / numMeasures; // stdDev = (sum of Xsquared -((sum of X)*(sum of X)/N)) / (N-1)) Float64 stdDev = sqrt ((totalMSqrd - ((totalM * totalM) / numMeasures)) / (numMeasures-1.0)); printf ("ave: %.2f, min: %.2f, max: %.2f, stdev: %.2f, numMeasures: %ld, current: %f\n", mean, sMinTime, sMaxTime, stdDev, numMeasures, cpuTime); } #endif } delete [] thrasher; mean = totalM / numMeasures; // stdDev = (sum of Xsquared -((sum of X)*(sum of X)/N)) / (N-1)) Float64 stdDev = sqrt ((totalMSqrd - ((totalM * totalM) / numMeasures)) / (numMeasures-1.0)); printf ("ave: %.2f, min: %.2f, max: %.2f, sd: %.2f, sd / mean: %.2f%%\n", mean, sMinTime, sMaxTime, stdDev, (stdDev / mean * 100.)); } // we don't care about post-processing home: if (result) { printf ("Exit with bad result:%ld\n", result); exit(result); } if (readBuf) { delete readBuf->readData; delete readBuf; } CFStringRef str = comp.GetCompName(); UInt32 compNameLen = CFStringGetLength (str); CFStringRef presetName = NULL; if (auPresetFile) { CFPropertyListRef dict; if (processor.AU().GetAUPreset (dict) == noErr) { presetName = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)dict, CFSTR("name")); CFRelease (dict); } } UInt32 presetLen = presetName ? CFStringGetLength(presetName) : 0; UInt32 groupID = comp.Desc().componentSubType; char* cstr = (char*)malloc (compNameLen + presetLen + 2 + 1); CFStringGetCString (str, cstr, (CFStringGetLength (str) + 1), kCFStringEncodingASCII); if (presetName) { cstr[compNameLen] = ':'; cstr[compNameLen+1] = ':'; CFStringGetCString (presetName, cstr + compNameLen + 2, (CFStringGetLength (presetName) + 1), kCFStringEncodingASCII); int len = strlen(cstr); for (int i = 0; i < len; ++i) groupID += cstr[i]; } PerfResult("AU Profile", EndianU32_NtoB(groupID), cstr, mean, "%realtime"); free (cstr); } catch (CAXException &e) { char buf[256]; printf("Error: %s (%s)\n", e.mOperation, e.FormatError(buf)); exit(1); } catch (...) { printf("An unknown error occurred\n"); exit(1); } return 0; }
void QTEffects_RespondToDialogSelection (OSErr theErr) { Boolean myDialogWasCancelled = false; short myResID = movieInDataForkResID; UInt16 myMovieIter; short mySrcMovieRefNum = 0; Movie myPrevSrcMovie = NULL; Track myPrevSrcTrack = NULL; Movie myNextSrcMovie = NULL; Track myNextSrcTrack = NULL; short myDestMovieRefNum = 0; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kEffectsSaveMoviePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kEffectsSaveMovieFileName); Movie myDestMovie = NULL; Fixed myDestMovieWidth, myDestMovieHeight; ImageDescriptionHandle myDesc = NULL; Track videoTrackFX, videoTrackA, videoTrackB; Media videoMediaFX, videoMediaA, videoMediaB; TimeValue myCurrentDuration = 0; TimeValue myReturnedDuration; Boolean isFirstTransition = true; TimeValue myMediaTransitionDuration; TimeValue myMediaFXStartTime, myMediaFXDuration; OSType myEffectCode; long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; long myLong; OSErr myErr = noErr; // standard parameter box has been dismissed, so remember that fact gEffectsDialog = 0L; myDialogWasCancelled = (theErr == userCanceledErr); // we're finished with the effect list and movie posters QTDisposeAtomContainer(gEffectList); if (gPosterA != NULL) KillPicture(gPosterA); if (gPosterB != NULL) KillPicture(gPosterB); // when the sign says stop, then stop if (myDialogWasCancelled) goto bail; // add atoms naming the sources to gEffectSample myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 1, 0, sizeof(myLong), &myLong, NULL); myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(gEffectSample, kParentAtomIsContainer, kEffectSourceName, 2, 0, sizeof(myLong), &myLong, NULL); // extract the 'what' atom to find out what kind of effect it is { QTAtom myEffectAtom; QTAtomID myEffectAtomID; long myEffectCodeSize; Ptr myEffectCodePtr; myEffectAtom = QTFindChildByIndex(gEffectSample, kParentAtomIsContainer, kParameterWhatName, kParameterWhatID, &myEffectAtomID); myErr = QTLockContainer(gEffectSample); BailError(myErr); myErr = QTGetAtomDataPtr(gEffectSample, myEffectAtom, &myEffectCodeSize, &myEffectCodePtr); BailError(myErr); if (myEffectCodeSize != sizeof(OSType)) { myErr = paramErr; goto bail; } myEffectCode = *(OSType *)myEffectCodePtr; // "tsk" myEffectCode = EndianU32_BtoN(myEffectCode); // because the data is read from an atom container myErr = QTUnlockContainer(gEffectSample); BailError(myErr); } // ask the user for the name of the new movie file QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); if (!myIsSelected) goto bail; // deal with user cancelling // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), 0, myFlags, &myDestMovieRefNum, &myDestMovie); BailError(myErr); // open the first file as a movie; call the first movie myPrevSrcMovie myErr = OpenMovieFile(&gSpecList[0], &mySrcMovieRefNum, fsRdPerm); BailError(myErr); myErr = NewMovieFromFile(&myPrevSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL); BailError(myErr); myErr = CloseMovieFile(mySrcMovieRefNum); BailError(myErr); // if the movie is shorter than kMinimumDuration, scale it to that length SetMovieTimeScale(myPrevSrcMovie, kTimeScale); myErr = QTEffects_GetFirstVideoTrackInMovie(myPrevSrcMovie, &myPrevSrcTrack); BailNil(myPrevSrcTrack); if (GetTrackDuration(myPrevSrcTrack) < kMinimumDuration) { myErr = ScaleTrackSegment(myPrevSrcTrack, 0, GetTrackDuration(myPrevSrcTrack), kMinimumDuration); BailError(myErr); } // find out how big the first movie is; we'll use it as the size of all our tracks GetTrackDimensions(myPrevSrcTrack, &myDestMovieWidth, &myDestMovieHeight); #if USES_MAKE_IMAGE_DESC_FOR_EFFECT // create a new sample description for the effect, // which is just an image description specifying the effect and its dimensions myErr = MakeImageDescriptionForEffect(myEffectCode, &myDesc); if (myErr != noErr) BailError(myErr); #else // create a new sample description for the effect, // which is just an image description specifying the effect and its dimensions myDesc = (ImageDescriptionHandle)NewHandleClear(sizeof(ImageDescription)); BailNil(myDesc); (**myDesc).idSize = sizeof(ImageDescription); (**myDesc).cType = myEffectCode; (**myDesc).hRes = 72L << 16; (**myDesc).vRes = 72L << 16; (**myDesc).dataSize = 0L; (**myDesc).frameCount = 1; (**myDesc).depth = 0; (**myDesc).clutID = -1; #endif // fill in the fields of the sample description (**myDesc).vendor = kAppleManufacturer; (**myDesc).temporalQuality = codecNormalQuality; (**myDesc).spatialQuality = codecNormalQuality; (**myDesc).width = FixRound(myDestMovieWidth); (**myDesc).height = FixRound(myDestMovieHeight); // add three video tracks to the destination movie: // - videoTrackFX is where the effects and stills live; it's user-visible. // - videoTrackA is where the "source A"s for effects live; it's hidden by the input map // - videoTrackB is where the "source B"s for effects live; it's hidden by the input map videoTrackFX = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackFX); videoMediaFX = NewTrackMedia(videoTrackFX, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaFX); myErr = BeginMediaEdits(videoMediaFX); BailError(myErr); videoTrackA = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackA); videoMediaA = NewTrackMedia(videoTrackA, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaA); videoTrackB = NewMovieTrack(myDestMovie, myDestMovieWidth, myDestMovieHeight, 0); BailNil(videoTrackB); videoMediaB = NewTrackMedia(videoTrackB, VideoMediaType, kTimeScale, NULL, 0); BailNil(videoMediaB); // create the input map { long myRefIndex1, myRefIndex2; QTAtomContainer myInputMap; QTAtom myInputAtom; OSType myInputType; QTNewAtomContainer(&myInputMap); // first input if (videoTrackA) { AddTrackReference(videoTrackFX, videoTrackA, kTrackModifierReference, &myRefIndex1); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex1, 0, 0, NULL, &myInputAtom); myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); myLong = EndianU32_NtoB(kSourceOneName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // second input if (videoTrackB) { AddTrackReference(videoTrackFX, videoTrackB, kTrackModifierReference, &myRefIndex2); QTInsertChild(myInputMap, kParentAtomIsContainer, kTrackModifierInput, myRefIndex2, 0, 0, NULL, &myInputAtom); myInputType = EndianU32_NtoB(kTrackModifierTypeImage); QTInsertChild(myInputMap, myInputAtom, kTrackModifierType, 1, 0, sizeof(myInputType), &myInputType, NULL); myLong = EndianU32_NtoB(kSourceTwoName); QTInsertChild(myInputMap, myInputAtom, kEffectDataSourceType, 1, 0, sizeof(myLong), &myLong, NULL); } // set that map SetMediaInputMap(GetTrackMedia(videoTrackFX), myInputMap); QTDisposeAtomContainer(myInputMap); } myCurrentDuration = 0; #if MAKE_STILL_SECTIONS // copy the first sample of the first video track of the first movie to videoTrackFX, with duration kStillDuration. myErr = CopyPortionOfTrackToTrack(myPrevSrcTrack, eStartPortion + eMiddlePortion, videoTrackFX, myCurrentDuration, &myReturnedDuration); BailError(myErr); myCurrentDuration += myReturnedDuration; #endif // now process any remaining files myMovieIter = 1; while (myMovieIter < gSpecCount) { // open the next file as a movie; call it nextSourceMovie myErr = OpenMovieFile(&gSpecList[myMovieIter], &mySrcMovieRefNum, fsRdPerm); BailError(myErr); myErr = NewMovieFromFile(&myNextSrcMovie, mySrcMovieRefNum, NULL, NULL, 0, NULL); BailError(myErr); // we're done with the movie file, so close it myErr = CloseMovieFile(mySrcMovieRefNum); BailError(myErr); // if the movie is shorter than kMinimumDuration, scale it to that length SetMovieTimeScale(myNextSrcMovie, kTimeScale); myErr = QTEffects_GetFirstVideoTrackInMovie(myNextSrcMovie, &myNextSrcTrack); BailNil(myNextSrcTrack); if (GetTrackDuration(myNextSrcTrack) < kMinimumDuration) { myErr = ScaleTrackSegment(myNextSrcTrack, 0, GetTrackDuration(myNextSrcTrack), kMinimumDuration); BailError(myErr); } // create a transition effect from the previous source movie's first video sample to the next source movie's first video sample // (the effect should have duration kEffectDuration); // this involves adding one sample to each of the three video tracks: // sample from previous source movie -> videoTrackA myErr = QTEffects_CopyPortionOfTrackToTrack(myPrevSrcTrack, eFinishPortion, videoTrackA, myCurrentDuration, &myReturnedDuration); BailError(myErr); // sample from next source movie -> videoTrackB myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eStartPortion, videoTrackB, myCurrentDuration, &myReturnedDuration); BailError(myErr); // effect sample -> videoTrackFX if (isFirstTransition) { myMediaTransitionDuration = myReturnedDuration; myMediaFXStartTime = GetMediaDuration(videoMediaFX); myErr = AddMediaSample(videoMediaFX, gEffectSample, 0, GetHandleSize(gEffectSample), myMediaTransitionDuration, (SampleDescriptionHandle)myDesc, 1, 0, NULL); BailError(myErr); myMediaFXDuration = GetMediaDuration(videoMediaFX) - myMediaFXStartTime; isFirstTransition = false; } myErr = InsertMediaIntoTrack(videoTrackFX, myCurrentDuration, myMediaFXStartTime, myMediaFXDuration, FixRatio(myReturnedDuration, myMediaTransitionDuration)); BailError(myErr); myCurrentDuration += myReturnedDuration; #if MAKE_STILL_SECTIONS // copy the first video sample of myNextSrcMovie to videoTrackFX, with duration kStillDuration. myErr = QTEffects_CopyPortionOfTrackToTrack(myNextSrcTrack, eMiddlePortion + (myMovieIter + 1 == theSpecCount) ? eFinishPortion : 0, videoTrackFX, myCurrentDuration, &myReturnedDuration); BailError(myErr); myCurrentDuration += myReturnedDuration; #endif // MAKE_STILL_SECTIONS // dispose of previous source movie. DisposeMovie(myPrevSrcMovie); myPrevSrcMovie = myNextSrcMovie; myPrevSrcTrack = myNextSrcTrack; myNextSrcMovie = NULL; myNextSrcTrack = NULL; myMovieIter++; } // while myErr = EndMediaEdits(videoMediaFX); BailError(myErr); myErr = AddMovieResource(myDestMovie, myDestMovieRefNum, &myResID, "\pMovie 1"); BailError(myErr); CloseMovieFile(myDestMovieRefNum); if (myPrevSrcMovie != NULL) DisposeMovie(myPrevSrcMovie); DisposeMovie(myDestMovie); bail: free(myPrompt); free(myFileName); QTDisposeAtomContainer(gEffectSample); DisposeHandle((Handle)myDesc); return; }
OSErr SpriteUtils_AddCompressedSpriteSampleToMedia (Media theMedia, QTAtomContainer theSample, TimeValue theDuration, Boolean isKeyFrame, OSType theDataCompressorType, TimeValue *theSampleTime) { SpriteDescriptionHandle mySampleDesc = NULL; Handle myCompressedSample = NULL; ComponentInstance myComponent = NULL; OSErr myErr = noErr; myErr = OpenADefaultComponent(DataCompressorComponentType, theDataCompressorType, &myComponent); if (myErr != noErr) goto bail; mySampleDesc = (SpriteDescriptionHandle)NewHandleClear(sizeof(SpriteDescription)); if (mySampleDesc == NULL) { myErr = MemError(); goto bail; } if (myComponent != NULL) { UInt32 myCompressBufferSize, myActualCompressedSize, myDecompressSlop = 0; UInt32 myUncompressedSize; SignedByte mySaveState = HGetState(theSample); myErr = (OSErr)DataCodecGetCompressBufferSize(myComponent, GetHandleSize(theSample), &myCompressBufferSize); if (myErr != noErr) goto bail; myCompressedSample = NewHandle(sizeof(UInt32) + myCompressBufferSize); myErr = MemError(); if (myErr != noErr) goto bail; HLockHi(theSample); HLockHi(myCompressedSample); myErr = (OSErr)DataCodecCompress(myComponent, *theSample, GetHandleSize(theSample), *myCompressedSample + sizeof(UInt32), // room for size at beginning myCompressBufferSize, &myActualCompressedSize, &myDecompressSlop); HSetState(theSample, mySaveState); HUnlock(myCompressedSample); if (myErr != noErr) goto bail; SetHandleSize(myCompressedSample, sizeof(UInt32) + myActualCompressedSize); myErr = MemError(); if (myErr != noErr) goto bail; (**mySampleDesc).decompressorType = EndianU32_NtoB(theDataCompressorType); myUncompressedSize = GetHandleSize(theSample); (*(UInt32*) *myCompressedSample) = EndianU32_NtoB(myUncompressedSize); // add uncompressed size at beginning myErr = AddMediaSample(theMedia, (Handle)myCompressedSample, 0, GetHandleSize(myCompressedSample), theDuration, (SampleDescriptionHandle)mySampleDesc, 1, (short)(isKeyFrame ? 0 : mediaSampleNotSync), theSampleTime); } else { myErr = AddMediaSample(theMedia, (Handle)theSample, 0, GetHandleSize(theSample), theDuration, (SampleDescriptionHandle)mySampleDesc, 1, (short)(isKeyFrame ? 0 : mediaSampleNotSync), theSampleTime); } bail: if (myCompressedSample != NULL) DisposeHandle(myCompressedSample); if (mySampleDesc != NULL) DisposeHandle((Handle)mySampleDesc); if (myComponent != NULL) CloseComponent(myComponent); return(myErr); }
OSErr QTTarg_MakeDualVRControllerMovie (void) { Movie myMovie = NULL; Track myTrack = NULL; Media myMedia = NULL; RGBColor myKeyColor; Fixed myWidth, myHeight; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName); long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; short myResRefNum = 0; short myResID = movieInDataForkResID; OSType myType = FOUR_CHAR_CODE('none'); OSErr myErr = noErr; ////////// // // create a new movie file // ////////// // prompt the user for the destination file name QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); myErr = myIsSelected ? noErr : userCanceledErr; if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // select the "no-interface" movie controller myType = EndianU32_NtoB(myType); SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); ////////// // // get some information about the target movie // ////////// myWidth = Long2Fix(kVRControlMovieWidth); myHeight = Long2Fix(kVRControlMovieHeight); ////////// // // create a new sprite track in the target movie // ////////// myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, kVRControlMovieDuration, NULL, 0); myErr = BeginMediaEdits(myMedia); if (myErr != noErr) goto bail; ////////// // // add sprite images and sprites to the sprite track; add actions to the sprites // ////////// QTTarg_AddVRControllerButtonSamplesToMedia(myMedia, kVRControlMovieWidth, kVRControlMovieHeight, kVRControlMovieDuration); ////////// // // insert media into track // ////////// myErr = EndMediaEdits(myMedia); if (myErr != noErr) goto bail; // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// QTTarg_SetTrackProperties(myMedia, 0); // idle as fast as possible myKeyColor.red = myKeyColor.green = myKeyColor.blue = 0xffff; // white MediaSetGraphicsMode(GetMediaHandler(myMedia), transparent, &myKeyColor); ////////// // // add the movie resource to the movie file // ////////// myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); bail: if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myMovie != NULL) DisposeMovie(myMovie); free(myPrompt); free(myFileName); return(myErr); }
OSErr QTTarg_CreateTwinSpritesMovie (void) { Movie myMovie = NULL; Track myTrack = NULL; Media myMedia = NULL; FSSpec myFile; Boolean myIsSelected = false; Boolean myIsReplacing = false; Fixed myHeight = 0; Fixed myWidth = 0; StringPtr myPrompt = QTUtils_ConvertCToPascalString(kSpriteSavePrompt); StringPtr myFileName = QTUtils_ConvertCToPascalString(kSpriteSaveMovieFileName); long myFlags = createMovieFileDeleteCurFile | createMovieFileDontCreateResFile; OSType myType = FOUR_CHAR_CODE('none'); short myResRefNum = 0; short myResID = movieInDataForkResID; OSErr myErr = noErr; ////////// // // create a new movie file // ////////// // prompt the user for the destination file name QTFrame_PutFile(myPrompt, myFileName, &myFile, &myIsSelected, &myIsReplacing); myErr = myIsSelected ? noErr : userCanceledErr; if (!myIsSelected) goto bail; // create a movie file for the destination movie myErr = CreateMovieFile(&myFile, FOUR_CHAR_CODE('TVOD'), smSystemScript, myFlags, &myResRefNum, &myMovie); if (myErr != noErr) goto bail; // select the "no-interface" movie controller myType = EndianU32_NtoB(myType); SetUserDataItem(GetMovieUserData(myMovie), &myType, sizeof(myType), kUserDataMovieControllerType, 1); ////////// // // create the sprite track and media // ////////// myWidth = Long2Fix(kIconSpriteTrackWidth); myHeight = Long2Fix(kIconSpriteTrackHeight); myTrack = NewMovieTrack(myMovie, myWidth, myHeight, kNoVolume); myMedia = NewTrackMedia(myTrack, SpriteMediaType, kSpriteMediaTimeScale, NULL, 0); myErr = BeginMediaEdits(myMedia); if (myErr != noErr) goto bail; ////////// // // add the appropriate samples to the sprite media // ////////// myErr = QTTarg_AddIconMovieSamplesToMedia(myMedia); if (myErr != noErr) goto bail; myErr = EndMediaEdits(myMedia); if (myErr != noErr) goto bail; // add the media to the track InsertMediaIntoTrack(myTrack, 0, 0, GetMediaDuration(myMedia), fixed1); ////////// // // set the sprite track properties // ////////// QTTarg_SetTrackProperties(myMedia, 1); ////////// // // add the movie resource to the movie file // ////////// myErr = AddMovieResource(myMovie, myResRefNum, &myResID, myFile.name); bail: if (myResRefNum != 0) CloseMovieFile(myResRefNum); if (myMovie != NULL) DisposeMovie(myMovie); free(myPrompt); free(myFileName); return(myErr); }
//FLAC__StreamMetadata_StreamInfo void ACFLACCodec::GetMagicCookie(void* outMagicCookieData, UInt32& ioMagicCookieDataByteSize) const { Byte * buffer; Byte * currPtr; AudioFormatAtom * frmaAtom; FullAtomHeader * flacAtom; AudioTerminatorAtom * termAtom; SInt32 atomSize; UInt32 flacSize; UInt32 chanSize; UInt32 frmaSize; UInt32 termSize; FLAC__StreamMetadata_StreamInfo * config; OSStatus status; UInt32 tempMaxFrameBytes; //RequireAction( sampleDesc != nil, return paramErr; ); config = nil; frmaSize = sizeof(AudioFormatAtom); flacSize = sizeof(FullAtomHeader) + sizeof(FLAC__StreamMetadata_StreamInfo); chanSize = 0; termSize = sizeof(AudioTerminatorAtom); // if we're encoding more than two channels, add an AudioChannelLayout atom to describe the layout if ( mOutputFormat.mChannelsPerFrame > 2 ) { chanSize = sizeof(FullAtomHeader) + offsetof(AudioChannelLayout, mChannelDescriptions); } // create buffer of the required size atomSize = frmaSize + flacSize + chanSize + termSize; // Someone might have a stereo/mono cookie while we're trying to do surround. if ((UInt32)atomSize > ioMagicCookieDataByteSize) { CODEC_THROW(kAudioCodecBadPropertySizeError); } tempMaxFrameBytes = kInputBufferPackets * mOutputFormat.mChannelsPerFrame * ((10 + kMaxSampleSize) / 8) + 1; buffer = (Byte *)calloc( atomSize, 1 ); currPtr = buffer; // fill in the atom stuff frmaAtom = (AudioFormatAtom *) currPtr; frmaAtom->size = EndianU32_NtoB( frmaSize ); frmaAtom->atomType = EndianU32_NtoB( kAudioFormatAtomType ); frmaAtom->format = EndianU32_NtoB( 'flac' ); currPtr += frmaSize; // fill in the FLAC config flacAtom = (FullAtomHeader *) currPtr; flacAtom->size = EndianU32_NtoB( flacSize ); flacAtom->type = EndianU32_NtoB( 'flac' ); flacAtom->versionFlags = 0; currPtr += sizeof(FullAtomHeader); /* unsigned min_blocksize, max_blocksize; unsigned min_framesize, max_framesize; unsigned sample_rate; unsigned channels; unsigned bits_per_sample; FLAC__uint64 total_samples; FLAC__byte md5sum[16]; */ config = (FLAC__StreamMetadata_StreamInfo *) currPtr; if (mCookieDefined) { config->min_blocksize = EndianU32_NtoB( mStreamInfo.min_blocksize ); config->max_blocksize = EndianU32_NtoB( mStreamInfo.max_blocksize ); config->min_framesize = EndianU32_NtoB( mStreamInfo.min_framesize ); config->max_framesize = EndianU32_NtoB( mStreamInfo.max_framesize ); config->sample_rate = EndianU32_NtoB( mStreamInfo.sample_rate ); config->channels = EndianU32_NtoB( mStreamInfo.channels ); config->bits_per_sample = EndianU32_NtoB( mStreamInfo.bits_per_sample ); config->total_samples = EndianU64_NtoB( mStreamInfo.total_samples ); config->md5sum[0] = mStreamInfo.md5sum[0]; config->md5sum[1] = mStreamInfo.md5sum[1]; config->md5sum[2] = mStreamInfo.md5sum[2]; config->md5sum[3] = mStreamInfo.md5sum[3]; config->md5sum[4] = mStreamInfo.md5sum[4]; config->md5sum[5] = mStreamInfo.md5sum[5]; config->md5sum[6] = mStreamInfo.md5sum[6]; config->md5sum[7] = mStreamInfo.md5sum[7]; config->md5sum[8] = mStreamInfo.md5sum[8]; config->md5sum[9] = mStreamInfo.md5sum[9]; config->md5sum[10] = mStreamInfo.md5sum[10]; config->md5sum[11] = mStreamInfo.md5sum[11]; config->md5sum[12] = mStreamInfo.md5sum[12]; config->md5sum[13] = mStreamInfo.md5sum[13]; config->md5sum[14] = mStreamInfo.md5sum[14]; config->md5sum[15] = mStreamInfo.md5sum[15]; } else { config->min_blocksize = EndianU32_NtoB( kFLACDefaultFrameSize ); config->max_blocksize = EndianU32_NtoB( kFLACDefaultFrameSize ); config->min_framesize = EndianU32_NtoB( 0 ); config->max_framesize = EndianU32_NtoB( 0 ); config->sample_rate = EndianU32_NtoB( (UInt32)(mOutputFormat.mSampleRate) ); config->channels = EndianU32_NtoB(mOutputFormat.mChannelsPerFrame); config->bits_per_sample = EndianU32_NtoB(mBitDepth); config->total_samples = 0; config->md5sum[0] = 0; config->md5sum[1] = 0; config->md5sum[2] = 0; config->md5sum[3] = 0; config->md5sum[4] = 0; config->md5sum[5] = 0; config->md5sum[6] = 0; config->md5sum[7] = 0; config->md5sum[8] = 0; config->md5sum[9] = 0; config->md5sum[10] = 0; config->md5sum[11] = 0; config->md5sum[12] = 0; config->md5sum[13] = 0; config->md5sum[14] = 0; config->md5sum[15] = 0; } currPtr += sizeof(FLAC__StreamMetadata_StreamInfo); // if we're encoding more than two channels, add an AudioChannelLayout atom to describe the layout // Unfortunately there is no way to avoid dealing with an atom here if ( mOutputFormat.mChannelsPerFrame > 2 ) { AudioChannelLayoutTag tag; FullAtomHeader * chan; AudioChannelLayout * layout; chan = (FullAtomHeader *) currPtr; chan->size = EndianU32_NtoB( chanSize ); chan->type = EndianU32_NtoB( AudioChannelLayoutAID ); // version flags == 0 currPtr += sizeof(FullAtomHeader); // we use a predefined set of layout tags so we don't need to write any channel descriptions layout = (AudioChannelLayout *) currPtr; tag = sChannelLayoutTags[mOutputFormat.mChannelsPerFrame - 1]; layout->mChannelLayoutTag = EndianU32_NtoB( tag ); layout->mChannelBitmap = 0; layout->mNumberChannelDescriptions = 0; currPtr += offsetof(AudioChannelLayout, mChannelDescriptions); } // fill in Terminator atom header termAtom = (AudioTerminatorAtom *) currPtr; termAtom->size = EndianU32_NtoB( termSize ); termAtom->atomType = EndianU32_NtoB( kAudioTerminatorAtomType ); // all good, return the new description memcpy (outMagicCookieData, (const void *)(buffer), atomSize); ioMagicCookieDataByteSize = atomSize; status = noErr; // delete any memory we allocated if ( buffer != NULL ) { delete buffer; buffer = NULL; } }
OSErr SpriteUtils_SetSpriteData (QTAtomContainer theSprite, Point *theLocation, short *theVisible, short *theLayer, short *theImageIndex, ModifierTrackGraphicsModeRecord *theGraphicsMode, StringPtr theSpriteName, QTAtomContainer theActionAtoms) { QTAtom myPropertyAtom; OSErr myErr = noErr; if (theSprite == NULL) return(paramErr); // set the sprite location data if (theLocation != NULL) { MatrixRecord myMatrix; SetIdentityMatrix(&myMatrix); myMatrix.matrix[2][0] = ((long)theLocation->h << 16); myMatrix.matrix[2][1] = ((long)theLocation->v << 16); EndianUtils_MatrixRecord_NtoB(&myMatrix); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyMatrix, 1, 0, sizeof(MatrixRecord), &myMatrix, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(MatrixRecord), &myMatrix); if (myErr != noErr) goto bail; } // set the sprite visibility state if (theVisible != NULL) { short myVisible = *theVisible; myVisible = EndianS16_NtoB(myVisible); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyVisible, 1, 0, sizeof(short), &myVisible, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myVisible); if (myErr != noErr) goto bail; } // set the sprite layer if (theLayer != NULL) { short myLayer = *theLayer; myLayer = EndianS16_NtoB(myLayer); myPropertyAtom = QTFindChildByIndex(theSprite, 0, kSpritePropertyLayer, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, 0, kSpritePropertyLayer, 1, 0, sizeof(short), &myLayer, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myLayer); if (myErr != noErr) goto bail; } // set the sprite image index if (theImageIndex != NULL) { short myImageIndex = *theImageIndex; myImageIndex = EndianS16_NtoB(myImageIndex); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyImageIndex, 1, 0, sizeof(short), &myImageIndex, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(short), &myImageIndex); if (myErr != noErr) goto bail; } // set the sprite graphics mode if (theGraphicsMode != NULL) { ModifierTrackGraphicsModeRecord myGraphicsMode; myGraphicsMode.graphicsMode = EndianU32_NtoB(theGraphicsMode->graphicsMode); myGraphicsMode.opColor.red = EndianU16_NtoB(theGraphicsMode->opColor.red); myGraphicsMode.opColor.green = EndianU16_NtoB(theGraphicsMode->opColor.green); myGraphicsMode.opColor.blue = EndianU16_NtoB(theGraphicsMode->opColor.blue); myPropertyAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, NULL); if (myPropertyAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpritePropertyGraphicsMode, 1, 0, sizeof(myGraphicsMode), &myGraphicsMode, NULL); else myErr = QTSetAtomData(theSprite, myPropertyAtom, sizeof(myGraphicsMode), &myGraphicsMode); if (myErr != noErr) goto bail; } // set the sprite name if (theSpriteName != NULL) { QTAtom mySpriteNameAtom; mySpriteNameAtom = QTFindChildByIndex(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, NULL); if (mySpriteNameAtom == 0) myErr = QTInsertChild(theSprite, kParentAtomIsContainer, kSpriteNameAtomType, 1, 0, theSpriteName[0] + 1, theSpriteName, NULL); else myErr = QTSetAtomData(theSprite, mySpriteNameAtom, theSpriteName[0] + 1, theSpriteName); if (myErr != noErr) goto bail; } // set the action atoms if (theActionAtoms != NULL) myErr = QTInsertChildren(theSprite, kParentAtomIsContainer, theActionAtoms); bail: if ((myErr != noErr) && (theSprite != NULL)) QTRemoveChildren(theSprite, 0); return(myErr); }