void TLevelWriter3gp::save(const TImageP &img, int frameIndex) { if (m_cancelled) return; TRasterImageP image(img); int lx = image->getRaster()->getLx(); int ly = image->getRaster()->getLy(); //void *buffer = image->getRaster()->getRawData(); int pixSize = image->getRaster()->getPixelSize(); if (pixSize != 4) throw TImageException(getFilePath(), "Unsupported pixel type"); QMutexLocker sl(&m_mutex); if (!m_properties) m_properties = new Tiio::MovWriterProperties(); Tiio::MovWriterProperties *prop = (Tiio::MovWriterProperties *)(m_properties); //CodecType compression = StandardCompressionType; prop->getCurrentCodec(); //CodecQ quality = StandardQualityType; prop->getCurrentQuality(); if (!m_initDone) { //FSSpec fspec; Rect frame; long max_compressed_size; QDErr err; m_videoTrack = NewMovieTrack(m_movie, FixRatio((short)lx, 1), FixRatio((short)ly, 1), kNoVolume); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create video track"); m_dataRef = nil; m_hMovieData = NewHandle(0); // Construct the Handle data reference err = PtrToHand(&m_hMovieData, &m_dataRef, sizeof(Handle)); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create Data Ref"); m_videoMedia = NewTrackMedia(m_videoTrack, VideoMediaType, (TINT32)m_frameRate, m_dataRef, HandleDataHandlerSubType); OpenADefaultComponent(MovieExportType, '3gpp', &m_myExporter); // err = (short)MovieExportDoUserDialog(m_myExporter, m_movie, 0, 0, 0, &m_cancelled); // if (m_cancelled) // throw TImageException(getFilePath(), "User abort of 3GP render"); if ((err = GetMoviesError() != noErr)) throw TImageException(getFilePath(), "can't create video media"); if ((err = BeginMediaEdits(m_videoMedia)) != noErr) throw TImageException(getFilePath(), "can't begin edit video media"); frame.left = 0; frame.top = 0; frame.right = lx; frame.bottom = ly; #if 0 if ((err = NewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0))!=noErr) #else /* Mac OSX 10.7 later */ if ((err = QTNewGWorld(&(m_gworld), pixSize * 8, &frame, 0, 0, 0)) != noErr) #endif throw TImageException(getFilePath(), "can't create movie buffer"); #ifdef WIN32 LockPixels(m_gworld->portPixMap); if ((err = GetMaxCompressionSize(m_gworld->portPixMap, &frame, 0, quality, compression, anyCodec, &max_compressed_size)) != noErr) throw TImageException(getFilePath(), "can't get max compression size"); #else #if 0 PixMapHandle pixmapH = GetPortPixMap (m_gworld); LockPixels(pixmapH); #else PixMapHandle pixmapH = NULL; #endif max_compressed_size = lx * ly * 4 * 20; /*if ((err = GetMaxCompressionSize(pixmapH, &frame, 0, quality, compression,anyCodec, &max_compressed_size))!=noErr) throw TImageException(getFilePath(), "can't get max compression size");*/ #endif m_compressedData = NewHandle(max_compressed_size); if ((err = MemError()) != noErr) throw TImageException(getFilePath(), "can't allocate compressed data for movie"); MoveHHi(m_compressedData); HLock(m_compressedData); if ((err = MemError()) != noErr) throw TImageException(getFilePath(), "can't allocate img handle"); #if 0 m_pixmap = GetGWorldPixMap(m_gworld); if (!LockPixels(m_pixmap)) throw TImageException(getFilePath(), "can't lock pixels"); buf = (PixelXRGB*) GetPixBaseAddr(m_pixmap); #else m_pixmap = NULL; buf = NULL; #endif buf_lx = lx; buf_ly = ly; m_initDone = true; } unsigned short rowBytes = (unsigned short)(((short)(*(m_pixmap))->rowBytes & ~(3 << 14))); Rect frame; ImageDescriptionHandle img_descr; Ptr compressed_data_ptr; QDErr err; frame.left = 0; frame.top = 0; frame.right = lx; frame.bottom = ly; TRasterP ras = image->getRaster(); #ifdef WIN32 compressed_data_ptr = StripAddress(*(m_compressedData)); copy(ras, buf, buf_lx, buf_ly); #else compressed_data_ptr = *m_compressedData; copy(ras, buf, buf_lx, buf_ly, rowBytes); #endif img_descr = (ImageDescriptionHandle)NewHandle(4); #ifdef WIN32 if ((err = CompressImage(m_gworld->portPixMap, &frame, quality, compression, img_descr, compressed_data_ptr)) != noErr) throw TImageException(getFilePath(), "can't compress image"); #else #if 0 PixMapHandle pixmapH = GetPortPixMap (m_gworld); if ((err = CompressImage(pixmapH, &frame, codecNormalQuality, kJPEGCodecType, img_descr, compressed_data_ptr))!=noErr) { throw TImageException(getFilePath(), "can't compress image"); } #endif #endif if ((err = AddMediaSample(m_videoMedia, m_compressedData, 0, (*img_descr)->dataSize, 1, (SampleDescriptionHandle)img_descr, 1, 0, 0)) != noErr) throw TImageException(getFilePath(), "can't add image to movie media"); DisposeHandle((Handle)img_descr); }
OSErr open_network_speaker() { short block_size = kBlockSize; short connection_threshold = kConnectionThreshhold; OSErr error; assert(!speaker); assert(block_size>0&&block_size<=MAXIMUM_DOUBLE_BUFFER_SIZE); assert(connection_threshold>1&&connection_threshold<16); /* install our atexit cleanup procedure and build a routine descriptor */ { static bool initialization= true; if (initialization) { // ZZZ: Sorry, it looks like the CarbonSndPlayDoubleBuffer stuff really wants a plain C function // pointer, sitting in the structure typed as a SndDoubleBackUPP. (Don't ask me!) #if defined(TARGET_API_MAC_CARBON) doubleback_routine_descriptor= (SndDoubleBackUPP)network_speaker_doubleback_procedure; #else // Thomas Herzog fix #if UNIVERSAL_INTERFACES_VERSION < 0x0340 doubleback_routine_descriptor= NewSndDoubleBackProc( (ProcPtr)network_speaker_doubleback_procedure); #else doubleback_routine_descriptor= NewSndDoubleBackUPP( network_speaker_doubleback_procedure); #endif // doubleback_routine_descriptor= NewSndDoubleBackProc((ProcPtr)network_speaker_doubleback_procedure); #endif assert(doubleback_routine_descriptor); atexit(close_network_speaker); } } speaker= (struct speaker_definition *) NewPtr(sizeof(struct speaker_definition)); if ((error= MemError())==noErr) { speaker->random_seed= 1; speaker->block_size= block_size; speaker->connection_threshold= connection_threshold; speaker->channel= (SndChannelPtr) NewPtrClear(sizeof(SndChannel)); speaker->header= (SndDoubleBufferHeaderPtr) NewPtrClear(sizeof(SndDoubleBufferHeader)); speaker->queue= NewPtr(sizeof(byte)*MAXIMUM_QUEUE_SIZE); if ((error= MemError())==noErr) { SndDoubleBufferHeaderPtr header= speaker->header; header->dbhNumChannels= 1; header->dbhSampleSize= 8; header->dbhCompressionID= 0; header->dbhPacketSize= 0; header->dbhSampleRate= rate11025hz; header->dbhDoubleBack= doubleback_routine_descriptor; header->dbhBufferPtr[0]= (SndDoubleBufferPtr) NewPtrClear( sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE); header->dbhBufferPtr[1]= (SndDoubleBufferPtr) NewPtrClear( sizeof(SndDoubleBuffer)+MAXIMUM_DOUBLE_BUFFER_SIZE); if ((error= MemError())==noErr) { speaker->channel->qLength= stdQLength; #ifdef env68k speaker->channel->userInfo= (long) get_a5(); #endif error= SndNewChannel(&speaker->channel, sampledSynth, initMono|initMACE6, NULL); if (error==noErr) { quiet_network_speaker(); /* to set defaults */ } } } } #ifdef SPEEX init_speex_decoder(); #endif /* if something went wrong, zero the speaker definition (without freeing any of our memory like we should) */ if (error!=noErr) { speaker= (struct speaker_definition *) NULL; } return error; }
/* ** GetIconFromDesktopFile ** ** INPUT a pointer to a non-existent Handle, because we'll allocate one ** ** search each BNDL resource for the right fileCreator and once we get it ** find the 'FREF' type in BNDL ** for each localID in the type, open the FREF resource ** if the FREF is the desired fileType ** get its icon localID ** get the ICN# type in BNDL ** get the icon resource number from the icon localID ** get the icon resource type from the desktop mgr's iconType ** get the icon of that type and number */ static OSErr GetIconFromDesktopFile(ConstStr255Param volName, short vRefNum, short iconType, OSType fileCreator, OSType fileType, Handle *iconHandle) { OSErr error; short realVRefNum; Str255 desktopName; short savedResFile; short dfRefNum; BNDLRecHandle theBndl = NULL; BundleTypePtr theBundleType; short iconLocalID; short iconRsrcID; OSType iconRsrcType; Handle returnIconHandle; char bndlState; *iconHandle = NULL; error = DetermineVRefNum(volName, vRefNum, &realVRefNum); if ( error == noErr ) { error = GetDesktopFileName(realVRefNum, desktopName); if ( error == noErr ) { savedResFile = CurResFile(); /* ** Open the 'Desktop' file in the root directory. (because ** opening the resource file could preload unwanted resources, ** bracket the call with SetResLoad(s)) */ SetResLoad(false); dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, fsRdPerm); SetResLoad(true); if ( dfRefNum != -1 ) { /* ** Find the BNDL resource with the specified creator. */ error = FindBundleGivenCreator(fileCreator, &theBndl); if ( error == noErr ) { /* Lock the BNDL resource so it won't be purged when other resources are loaded */ bndlState = HGetState((Handle)theBndl); HLock((Handle)theBndl); /* Find the 'FREF' BundleType record in the BNDL resource. */ error = FindTypeInBundle(kFREFResType, theBndl, &theBundleType); if ( error == noErr ) { /* Find the local ID in the 'FREF' resource with the specified fileType */ error = GetLocalIDFromFREF(theBundleType, fileType, &iconLocalID); if ( error == noErr ) { /* Find the 'ICN#' BundleType record in the BNDL resource. */ error = FindTypeInBundle(kIconFamResType, theBndl, &theBundleType); if ( error == noErr ) { /* Find the icon's resource ID in the 'ICN#' BundleType record */ error = GetIconRsrcIDFromLocalID(theBundleType, iconLocalID, &iconRsrcID); if ( error == noErr ) { /* Map Desktop Manager icon type to resource type */ iconRsrcType = DTIconToResIcon(iconType); if ( iconRsrcType != (OSType)0 ) { /* Load the icon */ returnIconHandle = Get1Resource(iconRsrcType, iconRsrcID); if ( returnIconHandle != NULL ) { /* Copy the resource handle, and return the copy */ HandToHand(&returnIconHandle); if ( MemError() == noErr ) { *iconHandle = returnIconHandle; } else { error = afpItemNotFound; } } else { error = afpItemNotFound; } } } } } } /* Restore the state of the BNDL resource */ HSetState((Handle)theBndl, bndlState); } /* Restore the resource chain and close the Desktop file */ UseResFile(savedResFile); CloseResFile(dfRefNum); } else { error = ResError(); /* could not open Desktop file */ } } if ( (error != noErr) && (error != memFullErr) ) { error = afpItemNotFound; /* force an error we should return */ } } return ( error ); }
OSErr FSpPathFromLocation( FSSpec *spec, /* The location we want a path for. */ int *length, /* Length of the resulting path. */ Handle *fullPath) /* Handle to path. */ { OSErr err; FSSpec tempSpec; CInfoPBRec pb; *fullPath = NULL; /* * Make a copy of the input FSSpec that can be modified. */ BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); if (tempSpec.parID == fsRtParID) { /* * The object is a volume. Add a colon to make it a full * pathname. Allocate a handle for it and we are done. */ tempSpec.name[0] += 2; tempSpec.name[tempSpec.name[0] - 1] = ':'; tempSpec.name[tempSpec.name[0]] = '\0'; err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); } else { /* * The object isn't a volume. Is the object a file or a directory? */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrDirID = tempSpec.parID; pb.dirInfo.ioFDirIndex = 0; err = PBGetCatInfoSync(&pb); if ((err == noErr) || (err == fnfErr)) { /* * If the file doesn't currently exist we start over. If the * directory exists everything will work just fine. Otherwise we * will just fail later. If the object is a directory, append a * colon so full pathname ends with colon, but only if the name is * not empty. NavServices returns FSSpec's with the parent ID set, * but the name empty... */ if (err == fnfErr) { BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { if (tempSpec.name[0] > 0) { tempSpec.name[0] += 1; tempSpec.name[tempSpec.name[0]] = ':'; } } /* * Create a new Handle for the object - make it a C string. */ tempSpec.name[0] += 1; tempSpec.name[tempSpec.name[0]] = '\0'; err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); if (err == noErr) { /* * Get the ancestor directory names - loop until we have an * error or find the root directory. */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrParID = tempSpec.parID; do { pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; err = PBGetCatInfoSync(&pb); if (err == noErr) { /* * Append colon to directory name and add * directory name to beginning of fullPath. */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]); err = MemError(); } } while ( (err == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); } } } /* * On error Dispose the handle, set it to NULL & return the err. * Otherwise, set the length & return. */ if (err == noErr) { *length = GetHandleSize(*fullPath) - 1; } else { if ( *fullPath != NULL ) { DisposeHandle(*fullPath); } *fullPath = NULL; *length = 0; } return err; }
OSErr QTDR_CopyRemoteFileToLocalFile (char *theURL, FSSpecPtr theFile) { Handle myReaderRef = NULL; // data reference for the remote file Handle myWriterRef = NULL; // data reference for the local file ComponentResult myErr = badComponentType; ////////// // // create the local file with the desired type and creator // ////////// // delete the target local file, if it already exists; // if it doesn't exist yet, we'll get an error (fnfErr), which we just ignore FSpDelete(theFile); myErr = FSpCreate(theFile, kTransFileCreator, kTransFileType, smSystemScript); if (myErr != noErr) goto bail; ////////// // // create data references for the remote file and the local file // ////////// myReaderRef = QTDR_MakeURLDataRef(theURL); if (myReaderRef == NULL) goto bail; myWriterRef = QTDR_MakeFileDataRef(theFile); if (myWriterRef == NULL) goto bail; ////////// // // find and open the URL and file data handlers; connect the data references to them // ////////// gDataReader = OpenComponent(GetDataHandler(myReaderRef, URLDataHandlerSubType, kDataHCanRead)); if (gDataReader == NULL) goto bail; gDataWriter = OpenComponent(GetDataHandler(myWriterRef, rAliasType, kDataHCanWrite)); if (gDataWriter == NULL) goto bail; // set the data reference for the URL data handler myErr = DataHSetDataRef(gDataReader, myReaderRef); if (myErr != noErr) goto bail; // set the data reference for the file data handler myErr = DataHSetDataRef(gDataWriter, myWriterRef); if (myErr != noErr) goto bail; ////////// // // allocate a data buffer; the URL data handler copies data into this buffer, // and the file data handler copies data out of it // ////////// gDataBuffer = NewPtrClear(kDataBufferSize); myErr = MemError(); if (myErr != noErr) goto bail; ////////// // // connect to the remote and local files // ////////// // open a read-only path to the remote data reference myErr = DataHOpenForRead(gDataReader); if (myErr != noErr) goto bail; // get the size of the remote file myErr = DataHGetFileSize(gDataReader, &gBytesToTransfer); if (myErr != noErr) goto bail; // open a write-only path to the local data reference myErr = DataHOpenForWrite(gDataWriter); if (myErr != noErr) goto bail; ////////// // // start reading and writing data // ////////// gDoneTransferring = false; gBytesTransferred = 0L; gReadDataHCompletionUPP = NewDataHCompletionUPP(QTDR_ReadDataCompletionProc); gWriteDataHCompletionUPP = NewDataHCompletionUPP(QTDR_WriteDataCompletionProc); // start retrieving the data; we do this by calling our own write completion routine, // pretending that we've just successfully finished writing 0 bytes of data QTDR_WriteDataCompletionProc(gDataBuffer, 0L, noErr); bail: // if we encountered any error, close the data handler components if (myErr != noErr) QTDR_CloseDownHandlers(); return((OSErr)myErr); }
OSErr NetDDPOpenSocket( short *socketNumber, packetHandlerProcPtr packetHandler) { OSErr error; Handle socket_listener_resource; ProcPtr initialize_socket_listener, socket_listener; MPPPBPtr myMPPPBPtr= (MPPPBPtr) NewPtrClear(sizeof(MPPParamBlock)); static ProcPtr initialize_upp = NULL; static UniversalProcPtr packet_handler_upp = NULL; assert(packetHandler); /* canÕt have NULL packet handlers */ assert(!ddpPacketBuffer); /* canÕt have more than one socket listener installed */ socket_listener_resource = GetResource(SOCKET_LISTENER_RESOURCE_TYPE, SOCKET_LISTENER_ID); assert(socket_listener_resource); HLock(socket_listener_resource); HNoPurge(socket_listener_resource); initialize_socket_listener = (ProcPtr) StripAddress(*socket_listener_resource); ddpPacketBuffer= (DDPPacketBufferPtr) NewPtrClear(sizeof(DDPPacketBuffer)); error= MemError(); if (error==noErr) { if (packet_handler_upp == NULL) { packet_handler_upp = (UniversalProcPtr) NewRoutineDescriptor((ProcPtr) packetHandler, uppPacketHandlerProcInfo, GetCurrentISA()); } assert(packet_handler_upp); if (initialize_upp == NULL) { initialize_upp = (ProcPtr) NewRoutineDescriptor((ProcPtr) initialize_socket_listener, uppInitializeListenerProcInfo, kM68kISA); // it's in a 68k code resource } assert(initialize_upp); #ifdef env68k // it seems that we don't have CallUniversalProc() in the library. strange... #ifndef VULCAN socket_listener = (ProcPtr) initialize_socket_listener(packet_handler_upp, ddpPacketBuffer, 1); #else debugstr("Hey, socket listener was never initialized"); #endif #else socket_listener = (ProcPtr) CallUniversalProc((UniversalProcPtr) initialize_upp, uppInitializeListenerProcInfo, packet_handler_upp, ddpPacketBuffer, 1); #endif listenerUPP = (DDPSocketListenerUPP) NewRoutineDescriptor((ProcPtr) socket_listener, uppDDPSocketListenerProcInfo, kM68kISA); // have to force it to realize that it's a 68K resource assert(listenerUPP); myMPPPBPtr->DDP.socket= 0; myMPPPBPtr->DDP.u.listener= listenerUPP; error= POpenSkt(myMPPPBPtr, FALSE); if (error==noErr) { *socketNumber= myMPPPBPtr->DDP.socket; } DisposePtr((Ptr)myMPPPBPtr); } return error; }
pascal OSErr FSpGetFullPath(const FSSpec *spec, short *fullPathLength, Handle *fullPath) { OSErr result; OSErr realResult; FSSpec tempSpec; CInfoPBRec pb; *fullPathLength = 0; *fullPath = NULL; /* Default to noErr */ realResult = result = noErr; /* work around Nav Services "bug" (it returns invalid FSSpecs with empty names) */ if ( spec->name[0] == 0 ) { result = FSMakeFSSpecCompat(spec->vRefNum, spec->parID, spec->name, &tempSpec); } else { /* Make a copy of the input FSSpec that can be modified */ BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); } if ( result == noErr ) { if ( tempSpec.parID == fsRtParID ) { /* The object is a volume */ /* Add a colon to make it a full pathname */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; /* We're done */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); } else { /* The object isn't a volume */ /* Is the object a file or a directory? */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrDirID = tempSpec.parID; pb.dirInfo.ioFDirIndex = 0; result = PBGetCatInfoSync(&pb); /* Allow file/directory name at end of path to not exist. */ realResult = result; if ( (result == noErr) || (result == fnfErr) ) { /* if the object is a directory, append a colon so full pathname ends with colon */ if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & kioFlAttribDirMask) != 0 ) { ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; } /* Put the object name in first */ result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); if ( result == noErr ) { /* Get the ancestor directory names */ pb.dirInfo.ioNamePtr = tempSpec.name; pb.dirInfo.ioVRefNum = tempSpec.vRefNum; pb.dirInfo.ioDrParID = tempSpec.parID; do /* loop until we have an error or find the root directory */ { pb.dirInfo.ioFDirIndex = -1; pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; result = PBGetCatInfoSync(&pb); if ( result == noErr ) { /* Append colon to directory name */ ++tempSpec.name[0]; tempSpec.name[tempSpec.name[0]] = ':'; /* Add directory name to beginning of fullPath */ (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]); result = MemError(); } } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); } } } } if ( result == noErr ) { /* Return the length */ *fullPathLength = GetHandleSize(*fullPath); result = realResult; /* return realResult in case it was fnfErr */ } else { /* Dispose of the handle and return NULL and zero length */ if ( *fullPath != NULL ) { DisposeHandle(*fullPath); } *fullPath = NULL; *fullPathLength = 0; } return ( result ); }
extern pascal OSStatus InsertSystemSubMenu(MenuRef rootMenu, MenuRef parentMenu, UInt16 itemInParent, MenuRef childMenu) // See comment in interface part. { long oldA4; OSStatus err; SubSysMenuEntry newEntry; SInt16 newIDForChildMenu; oldA4 = SetUpA4(); assert(ValidateSystemMenuRef(rootMenu )); assert(ValidateSystemMenuRef(parentMenu)); assert(ValidateSystemMenuRef(childMenu )); assert(gMenuSelectState = kMenuSelectStatePre); // Validate parameters err = noErr; if ((rootMenu == NULL) || (parentMenu == NULL) || (childMenu == NULL)) { err = paramErr; } if (err == noErr && ((itemInParent == 0) || (itemInParent > CountMenuItems(parentMenu)))) { err = paramErr; } // Make sure rootMenu references a current system menu. // If it does, record the index of the root menu for // later use by HandleMenuSelect. Also fill out the rest // of the fields of the sub-menu entry. if (err == noErr) { newEntry.rootMenuIndex = FindRootMenuByRef(rootMenu); newEntry.parentMenu = parentMenu; newEntry.itemInParent = itemInParent; newEntry.childMenu = childMenu; if (newEntry.rootMenuIndex == kRootMenuNotFound) { err = paramErr; } } // Add newEntry to the sub-menu list, creating the sub-menu list if necessary. if (err == noErr) { if (gSubSysMenus == NULL) { gSubSysMenus = (SubSysMenuHandle) NewHandleSys(0); err = MemError(); } } if (err == noErr) { err = PtrAndHand(&newEntry, (Handle) gSubSysMenus, sizeof(newEntry)); } // Finally, insert the menu with a unique ID into the menu bar, // and set the parent item to reference its ID. if (err == noErr) { newIDForChildMenu = FindUniqueSubMenuID(); (**childMenu).menuID = newIDForChildMenu; InsertMenu(childMenu, hierMenu); SetItemCmd(parentMenu, itemInParent, hMenuCmd); SetItemMark(parentMenu, itemInParent, newIDForChildMenu); // I added this after testing revealed that adding a sub-menu didn't // force the menu size to be recalculated, so the item text of the // hierarchical item in the sub-menu was being truncated. This // only appears to happen on Mac OS 8.5, but the fix is sufficiently // benign to be employed on all systems. CalcMenuSize(parentMenu); } (void) SetA4(oldA4); return err; }
TQ3Status E3CompressedPixmapTexture_CompressImage(TQ3CompressedPixmap * compressedPixmap, PixMapHandle sourcePixMap, CodecType codecType, CodecComponent codecComponent, TQ3Int16 codedDepth, CodecQ codecQuality) { // If we support QuickTime, compress the image ImageDescriptionHandle imageDescH = NULL; long maxCompressedSize = 0; Handle compressedDataH = NULL; Ptr compressedDataP = NULL; OSErr theErr = noErr; Rect bounds = (**sourcePixMap).bounds; TQ3StorageObject compressedImage = NULL; TQ3StorageObject imageDesc = NULL; // Make sure QuickTime is present if ((TQ3Uns32) EnterMovies == (TQ3Uns32) kUnresolvedCFragSymbolAddress) return(kQ3Failure); theErr = GetMaxCompressionSize( sourcePixMap, &bounds, codedDepth, codecQuality, codecType, (CompressorComponent)codecComponent, &maxCompressedSize); if ( theErr != noErr ) { // paramErr or noCodecErr E3ErrorManager_PostError( kQ3ErrorInvalidParameter, kQ3False ) ; // failure return(kQ3Failure); } // allocate memory - we need to use Mac OS Handles for QuickTime imageDescH = (ImageDescriptionHandle) NewHandle( 4 ); compressedDataH = NewHandle( maxCompressedSize ); if ( compressedDataH != NULL && imageDescH != NULL ) { HLock(compressedDataH); compressedDataP = *compressedDataH; theErr = FCompressImage(sourcePixMap, &bounds, codedDepth, codecQuality, codecType, (CompressorComponent) codecComponent, NULL, 0, 0, NULL, NULL, imageDescH, compressedDataP); if ( theErr != noErr ) { // post error if (MemError() != noErr) E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; else E3ErrorManager_PostError( kQ3ErrorInvalidParameter , kQ3False ) ; //deallocate handle storage DisposeHandle( (Handle)imageDescH); DisposeHandle( compressedDataH); // failure return(kQ3Failure) ; } } // otherwise we have a memory error else { // deallocate handle storage if (imageDescH) DisposeHandle( (Handle)imageDescH); if (compressedDataH) DisposeHandle( compressedDataH); // post error E3ErrorManager_PostError( kQ3ErrorOutOfMemory , kQ3False ) ; //failure return( kQ3Failure) ; } if (imageDescH) DisposeHandle( (Handle)imageDescH); if (compressedDataH) DisposeHandle( compressedDataH); // lock the image desc handle HLock( (Handle) imageDescH ) ; // store the data in storage objects compressedImage = Q3MemoryStorage_New( (unsigned char *) compressedDataP, (TQ3Uns32) (**imageDescH).dataSize ) ; imageDesc = Q3MemoryStorage_New( (unsigned char *) imageDescH, (TQ3Uns32) (**imageDescH).idSize ) ; // make sure memory was allocated if( compressedImage == NULL && imageDesc == NULL ) { if( compressedImage != NULL ) Q3Object_Dispose( compressedImage ) ; if( imageDesc != NULL ) Q3Object_Dispose( imageDesc ) ; // deallocate handle storage DisposeHandle( (Handle) imageDescH ) ; DisposeHandle( compressedDataH ) ; // we don't need to post a memory error because it // has already been done, return failure return(kQ3Failure); } // store the data in the compressed pixmap structure E3Shared_Acquire(&compressedPixmap->compressedImage, compressedImage); E3Shared_Acquire(&compressedPixmap->imageDesc, imageDesc); // NOTE: we do not fill out the other fields of the data structure, // since this is the defined QD3D behaviour // deallocate handle storage DisposeHandle( (Handle) imageDescH ) ; DisposeHandle( compressedDataH ) ; return(kQ3Success) ; }
static pascal SInt32 MenuSelectPatch(Point startPt) // This is our patch on MenuSelect. The basic idea is to // call our clients to let them adjust their menus (and install // sub-menus by calling InsertSystemMenu), call through to // the old trap, call our clients to un-adjust their menus, // and then call HandleMenuSelect to see whether the chosen // menu was one of our system menus. If it was, HandleMenuSelect // calls the client to tell them that their menu was chosen and // returns 0 so that we tell the host application that nothing // happened. // // Note that MenuSelect is called by MenuEvent, so this patch // covers that case as well. { long oldA4; SInt32 result; SubSysMenuHandle tempSubSysMenus; oldA4 = SetUpA4(); // Our patch should only be installed if InitMoreSystemMenus was successful. assert(gRootSysMenus != NULL); // Only do stuff if we're actually up and running. // If gHaveInsertedRootSysMenus is false, it means that // someone is calling MenuSelect before our InsertMenu patch // has run, ie before anyone has inserted any system menus, // ie before the Process Manager has launched. I don't know // whether this ever happens, I'm use being cautious. // Also, if gMenuSelectState is not NULL then we're getting recursion // where we're not expecting it (probably from the kSystemMenuPreSelectAdjust // or kSystemMenuPostSelectAdjust callbacks, but possibly from another // trap patch), so we just call through to the system in that case. // We want debug versions to tell the client that they're recursing // in an unsupport fashion. assert(gMenuSelectState == kMenuSelectStateNil); if ( gHaveInsertedRootSysMenus && gMenuSelectState == kMenuSelectStateNil) { // OK, so we're up and running, so let's do our stuff. // First tell all clients that we're about to do a MenuSelect // (they can adjust their menus and insert sub-menus)... assert(gSubSysMenus == NULL); gMenuSelectState = kMenuSelectStatePre; CallAllClients(kSystemMenuPreSelectAdjust, NULL); // ... then call through to the old trap address... result = CallMenuSelectProc(gMenuSelectOldUPP, startPt); // ... and then tell all clients that we're done... gMenuSelectState = kMenuSelectStatePost; CallAllClients(kSystemMenuPostSelectAdjust, NULL); // Things get tricky here. In order to allow the client // to post modal dialogs from its kSystemMenuActOnChosen callback, // we must be re-entrant at the time we call HandleMenuSelect // (because the ModalDialog routine will call MenuSelect). // But we want to avoid having sub-menus in the menu bar when // we're recursively called because we're going to call the // client's kSystemMenuPreSelectAdjust callback, which will // attempt to re-insert those menus. // // So, we remove our sub-menus now, before calling the // kSystemMenuActOnChosen callback, then we make the callback, // and then we dispose of the memory we used to track the // sub-menus. tempSubSysMenus = gSubSysMenus; gSubSysMenus = NULL; DeleteSubMenus(tempSubSysMenus); gMenuSelectState = kMenuSelectStateNil; // At this point we're prepared to accept recursion. // Call HandleMenuSelect to process the results // from the menu operation and call the appropriate // client if it was one of our menus. result = HandleMenuSelect(result, tempSubSysMenus); // Clean up. If we created any sub-menu info, // dispose of it. if (tempSubSysMenus != NULL) { DisposeHandle( (Handle) tempSubSysMenus); assert(MemError() == noErr); } } else { result = CallMenuSelectProc(gMenuSelectOldUPP, startPt); } assert(gMenuSelectState == kMenuSelectStateNil); (void) SetA4(oldA4); return result; }
extern pascal OSStatus InitMoreSystemMenus(void) // See comment in interface part. { OSStatus err; UniversalProcPtr gMenuSelectPatchUPP; // points to MenuSelectPatch UniversalProcPtr gInsertMenuPatchUPP; // points to InsertMenuPatch // We need to use the callback routine SetUpA4 to set up // A4 in our trap patches. In preparation for that, we // need to remember A4 in some PC-relative place. The client // may have already done this, but doing it twice doesn't hurt. // // Note that this translates to a NOP for the CFM build. RememberA4(); assert(IsSystemStartup()); // To avoid allocating extra pointer blocks for each of our // routine descriptors, we just declare them statically // here, and then setup the gFooUPP pointers to point to // them. // // Of course, for the classic 68K case, we can just use // assign them directly. // Build our routine descriptors. #if TARGET_RT_MAC_CFM { static RoutineDescriptor gDetachIconActionRD = BUILD_ROUTINE_DESCRIPTOR(uppIconActionProcInfo, DetachIconAction); static RoutineDescriptor gMenuSelectPatchRD = BUILD_ROUTINE_DESCRIPTOR(uppMenuSelectProcInfo, MenuSelectPatch); static RoutineDescriptor gInsertMenuPatchRD = BUILD_ROUTINE_DESCRIPTOR(uppInsertMenuProcInfo, InsertMenuPatch); gDetachIconActionUPP = &gDetachIconActionRD; gMenuSelectPatchUPP = &gMenuSelectPatchRD; gInsertMenuPatchUPP = &gInsertMenuPatchRD; } #else gDetachIconActionUPP = (IconActionUPP) DetachIconAction; gMenuSelectPatchUPP = (UniversalProcPtr) MenuSelectPatch; gInsertMenuPatchUPP = (UniversalProcPtr) InsertMenuPatch; #endif // Setup our global state. gMenuSelectState = kMenuSelectStateNil; gRootSysMenus = (RootSysMenuHandle) NewHandleSys(0); err = MemError(); // If all goes well, install our patches. if (err == noErr) { gMenuSelectOldUPP = GetToolboxTrapAddress(_MenuSelect); gInsertMenuOldUPP = GetToolboxTrapAddress(_InsertMenu); SetToolboxTrapAddress(gMenuSelectPatchUPP, _MenuSelect); SetToolboxTrapAddress(gInsertMenuPatchUPP, _InsertMenu); } return err; }
inline short memory_error() {return MemError();}
struct servent *getservent(void) { static int preferedProto = 0; OSStatus err; long len; ICAttr attr; ICServices *buf; ICServiceEntry tmpICSvc; /* We use this to store an aligned copy of *curSvc. */ static ICServiceEntry *curICSvc = NULL; static struct servent svc = {NULL, NULL, 0, NULL}; ncbi_ClearErrno(); // Deallocate the last service name we returned. if (svc.s_name!=NULL) { free(svc.s_name); svc.s_name=NULL; } // If we haven't loaded the service table, load it now. if (gServices==NULL) { err=ICStart(&gConfig, 'Sock'); if (err) { ncbi_SetOTErrno(err); return NULL; } #if !TARGET_API_MAC_CARBON // Need to #ifdef this out for Carbon builds err=ICFindConfigFile(gConfig, 0, nil); if (err) { ncbi_SetOTErrno(err); return NULL; } // End of #ifdef for Carbon #endif len = 0; err = ICGetPref(gConfig, kICServices, &attr, NULL, &len); if (err) { ncbi_SetOTErrno(err); return NULL; } buf=(ICServices*)NewPtr(len); if (buf==NULL || MemError()!=noErr) { ncbi_SetOTErrno(MemError()); return NULL; } err=ICGetPref(gConfig, kICServices, &attr, (char*)buf, &len); if (err){ ncbi_SetOTErrno(err); return NULL; } gServices=buf; curICSvc=&gServices->services[0]; gServiceIndex=0; } /* If we are out of entries, return NULL. */ if (curICSvc==NULL || gServiceIndex>=gServices->count) return NULL; /* gServices is "packed", which means we cannot directly index gServices->services. * So, we have to manually increment the current record pointer. We also have to * memmove any numbers into an aligned variable, because entries in gServices are * not guaranteed to be on whatever boundary the current processor prefers. */ /* Make an aligned copy of *curICSvc */ memmove(tmpICSvc.name, curICSvc, ((char*)curICSvc)[0]+1); memmove(&tmpICSvc.port, (char*)curICSvc+((char*)curICSvc)[0]+1, 2); memmove(&tmpICSvc.flags, (char*)curICSvc+((char*)curICSvc)[0]+3, 2); /* Put together a servent based on the current service table entry. */ len = tmpICSvc.name[0]+1; svc.s_name = malloc(len); if (svc.s_name == NULL) { ncbi_SetOTErrno(memFullErr); return NULL; } //memmove(svc.s_name, tmpICSvc.name, len); //p2cstr((StringPtr)svc.s_name); p2cstrcpy(svc.s_name, tmpICSvc.name); svc.s_aliases=(char**)¬_an_alias; svc.s_port=tmpICSvc.port; switch(preferedProto){ case 0: switch(tmpICSvc.flags){ case 0: svc.s_proto=(char*)prot_none; break; case kICServicesUDPMask: svc.s_proto=(char*)prot_udp; break; case kICServicesTCPMask: svc.s_proto=(char*)prot_tcp; break; case 3: svc.s_proto=(char*)prot_udp; preferedProto=kICServicesTCPMask; break; } break; case kICServicesUDPMask: svc.s_proto=(char*)prot_udp; preferedProto=0; break; case kICServicesTCPMask: svc.s_proto=(char*)prot_tcp; preferedProto=0; break; default: // Assert_(0); /* We have set a preferedProto that we don't support. */ break; } if (preferedProto==0){ if ((++gServiceIndex)<gServices->count){ /* Cast gCurrentService to char* so we can play pointer arithmetic games in * byte-sized increments. The 5 is the length byte plus two 2-byte ints. */ curICSvc=(ICServiceEntry*)((char*)curICSvc+((char*)curICSvc)[0]+5); } else { curICSvc=NULL; } } return &svc; }
void MacQTStartRecording(char *path) { OSStatus err; CFStringRef str; CFURLRef url; memset(&sqt, 0, sizeof(sqt)); // storage str = CFStringCreateWithCString(kCFAllocatorDefault, path, MAC_PATH_ENCODING); url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, str, kCFURLPOSIXPathStyle, false); err = QTNewDataReferenceFromCFURL(url, 0, &(sqt.dataRef), &(sqt.dataRefType)); CheckError(err, 21); CFRelease(url); CFRelease(str); err = CreateMovieStorage(sqt.dataRef, sqt.dataRefType, 'TVOD', smSystemScript, createMovieFileDeleteCurFile | newMovieActive, &(sqt.dataHandler), &(sqt.movie)); CheckError(err, 22); // video MacQTOpenVideoComponent(&(sqt.vci)); SCTemporalSettings ts; err = SCGetInfo(sqt.vci, scTemporalSettingsType, &ts); ts.frameRate = FixRatio(Memory.ROMFramesPerSecond, 1); if (ts.keyFrameRate < 1) ts.keyFrameRate = Memory.ROMFramesPerSecond; sqt.keyFrame = sqt.keyFrameCount = ts.keyFrameRate; sqt.frameSkip = sqt.frameSkipCount = (macQTMovFlag & 0xFF00) >> 8; err = SCSetInfo(sqt.vci, scTemporalSettingsType, &ts); sqt.frame.top = 0; sqt.frame.left = 0; sqt.frame.right = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * SNES_WIDTH; sqt.frame.bottom = ((macQTMovFlag & kMovDoubleSize) ? 2 : 1) * ((macQTMovFlag & kMovExtendedHeight) ? SNES_HEIGHT_EXTENDED : SNES_HEIGHT); sqt.pw = sqt.ph = 0; sqt.firstFrame = true; Rect rct; SetRect(&rct, 0, 0, SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2 + 4); InitGWorld(&(sqt.bw), &rct, 16); sqt.vTrack = NewMovieTrack(sqt.movie, FixRatio(sqt.frame.right, 1), FixRatio(sqt.frame.bottom, 1), kNoVolume); CheckError(GetMoviesError(), 23); sqt.vMedia = NewTrackMedia(sqt.vTrack, VideoMediaType, Memory.ROMFramesPerSecond, nil, 0); CheckError(GetMoviesError(), 24); err = BeginMediaEdits(sqt.vMedia); CheckError(err, 25); // sound sqt.soundDesc = (SoundDescriptionHandle) NewHandleClear(sizeof(SoundDescription)); CheckError(MemError(), 26); (**sqt.soundDesc).descSize = sizeof(SoundDescription); #ifdef __BIG_ENDIAN__ (**sqt.soundDesc).dataFormat = Settings.SixteenBitSound ? k16BitBigEndianFormat : k8BitOffsetBinaryFormat; #else (**sqt.soundDesc).dataFormat = Settings.SixteenBitSound ? k16BitLittleEndianFormat : k8BitOffsetBinaryFormat; #endif (**sqt.soundDesc).numChannels = Settings.Stereo ? 2 : 1; (**sqt.soundDesc).sampleSize = Settings.SixteenBitSound ? 16 : 8; (**sqt.soundDesc).sampleRate = (UnsignedFixed) FixRatio(Settings.SoundPlaybackRate, 1); sqt.samplesPerSec = Settings.SoundPlaybackRate / Memory.ROMFramesPerSecond; sqt.soundBufferSize = sqt.samplesPerSec; if (Settings.SixteenBitSound) sqt.soundBufferSize <<= 1; if (Settings.Stereo) sqt.soundBufferSize <<= 1; sqt.soundBuffer = NewHandleClear(sqt.soundBufferSize); CheckError(MemError(), 27); HLock(sqt.soundBuffer); sqt.sTrack = NewMovieTrack(sqt.movie, 0, 0, kFullVolume); CheckError(GetMoviesError(), 28); sqt.sMedia = NewTrackMedia(sqt.sTrack, SoundMediaType, Settings.SoundPlaybackRate, nil, 0); CheckError(GetMoviesError(), 29); err = BeginMediaEdits(sqt.sMedia); CheckError(err, 30); }
static OSStatus SetupSectionBaseAddresses(FragToFixInfo *fragToFix) // This routine initialises the section0Base and section1Base // base fields of fragToFix to the base addresses of the // instantiated fragment represented by the other fields // of fragToFix. The process works in three states: // // 1. Find the contents of the relocated TVector of the // fragment's initialisation routine, provided to us by // the caller. // // 2. Find the contents of the non-relocated TVector by // looking it up in the PEF loader info header and then // using that to read the TVector contents from disk. // This yields the offsets from the section bases for // the init routine. // // 3. Subtract 2 from 3. { OSStatus err; TVector * relocatedExport; SInt32 initSection; UInt32 initOffset; PEFSectionHeader * initSectionHeader; Ptr packedDataSection; Ptr unpackedDataSection; TVector originalOffsets; packedDataSection = nil; unpackedDataSection = nil; // Step 1. // First find the init routine's TVector, which gives us the relocated // offsets of the init routine into the data and code sections. relocatedExport = (TVector *) fragToFix->initRoutine; // Step 2. // Now find the init routine's TVector's offsets in the data section on // disk. This gives us the raw offsets from the data and code section // of the beginning of the init routine. err = noErr; initSection = fragToFix->loaderSection->initSection; initOffset = fragToFix->loaderSection->initOffset; if (initSection == -1) { err = cfragFragmentUsageErr; } if (err == noErr) { MoreAssertQ( initSection >= 0 ); // Negative indexes are pseudo-sections which are just not allowed! MoreAssertQ( initSection < fragToFix->containerHeader.sectionCount ); initSectionHeader = &fragToFix->sectionHeaders[initSection]; // If the data section is packed, unpack it to a temporary buffer and then get the // original offsets from that buffer. If the data section is unpacked, just read // the original offsets directly off the disk. if ( initSectionHeader->sectionKind == kPEFPackedDataSection ) { // Allocate space for packed and unpacked copies of the section. packedDataSection = NewPtr(initSectionHeader->containerLength); err = MemError(); if (err == noErr) { unpackedDataSection = NewPtr(initSectionHeader->unpackedLength); err = MemError(); } // Read the contents of the packed section. if (err == noErr) { err = FSReadAtOffset( fragToFix->fileRef, fragToFix->locator.offset + initSectionHeader->containerOffset, initSectionHeader->containerLength, packedDataSection); } // Unpack the data into the unpacked section. if (err == noErr) { err = UnpackPEFDataSection( (UInt8 *) packedDataSection, initSectionHeader->containerLength, (UInt8 *) unpackedDataSection, initSectionHeader->unpackedLength); } // Extract the init routine's TVector from the unpacked section. if (err == noErr) { BlockMoveData(unpackedDataSection + initOffset, &originalOffsets, sizeof(TVector)); } } else { MoreAssertQ(fragToFix->sectionHeaders[initSection].sectionKind == kPEFUnpackedDataSection); err = FSReadAtOffset(fragToFix->fileRef, fragToFix->locator.offset + fragToFix->sectionHeaders[initSection].containerOffset + initOffset, sizeof(TVector), &originalOffsets); } } // Step 3. // Do the maths to subtract the unrelocated offsets from the current address // to get the base address. if (err == noErr) { fragToFix->section0Base = ((char *) relocatedExport->codePtr) - (UInt32) originalOffsets.codePtr; fragToFix->section1Base = ((char *) relocatedExport->tocPtr) - (UInt32) originalOffsets.tocPtr; } // Clean up. if (packedDataSection != nil) { DisposePtr(packedDataSection); MoreAssertQ( MemError() == noErr ); } if (unpackedDataSection != nil) { DisposePtr(unpackedDataSection); MoreAssertQ( MemError() == noErr ); } return err; }
static OSStatus ReadContainerBasics(FragToFixInfo *fragToFix) // Reads some basic information from the container of the // fragment to fix and stores it in various fields of // fragToFix. This includes: // // o containerHeader -- The contain header itself. // o sectionHeaders -- The array of section headers (in a newly allocated pointer block). // o loaderSection -- The entire loader section (in a newly allocated pointer block). // // Also sets disposeSectionPointers to indicate whether // the last two pointers should be disposed of. // // Finally, it leaves the container file open for later // folks who want to read data from it. { OSStatus err; UInt16 sectionIndex; Boolean found; MoreAssertQ(fragToFix != nil); MoreAssertQ(fragToFix->locator.fileSpec != nil); MoreAssertQ(fragToFix->connID != nil); MoreAssertQ(fragToFix->loaderSection == nil); MoreAssertQ(fragToFix->sectionHeaders == nil); MoreAssertQ(fragToFix->fileRef == 0); fragToFix->disposeSectionPointers = true; // Open up the file, read the container head, then read in // all the section headers, then go looking through the // section headers for the loader section (PEF defines // that there can be only one). err = FSpOpenDF(fragToFix->locator.fileSpec, fsRdPerm, &fragToFix->fileRef); if (err == noErr) { err = FSReadAtOffset(fragToFix->fileRef, fragToFix->locator.offset, sizeof(fragToFix->containerHeader), &fragToFix->containerHeader); if (err == noErr) { if ( fragToFix->containerHeader.tag1 != kPEFTag1 || fragToFix->containerHeader.tag2 != kPEFTag2 || fragToFix->containerHeader.architecture != kCompiledCFragArch || fragToFix->containerHeader.formatVersion != kPEFVersion) { err = cfragFragmentFormatErr; } } if (err == noErr) { fragToFix->sectionHeaders = (PEFSectionHeader *) NewPtr(fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader)); err = MemError(); } if (err == noErr) { err = FSReadAtOffset(fragToFix->fileRef, fragToFix->locator.offset + sizeof(fragToFix->containerHeader), fragToFix->containerHeader.sectionCount * sizeof(PEFSectionHeader), fragToFix->sectionHeaders); } if (err == noErr) { sectionIndex = 0; found = false; while ( sectionIndex < fragToFix->containerHeader.sectionCount && ! found ) { found = (fragToFix->sectionHeaders[sectionIndex].sectionKind == kPEFLoaderSection); if ( ! found ) { sectionIndex += 1; } } } if (err == noErr && ! found) { err = cfragNoSectionErr; } // Now read allocate a pointer block and read the loader section into it. if (err == noErr) { fragToFix->loaderSection = (PEFLoaderInfoHeader *) NewPtr(fragToFix->sectionHeaders[sectionIndex].containerLength); err = MemError(); } if (err == noErr) { err = FSReadAtOffset(fragToFix->fileRef, fragToFix->locator.offset + fragToFix->sectionHeaders[sectionIndex].containerOffset, fragToFix->sectionHeaders[sectionIndex].containerLength, fragToFix->loaderSection); } } // No clean up. The client must init fragToFix to zeros and then // clean up regardless of whether we return an error. return err; }