/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M M AAA CCCC % % MM MM A A C % % M M M AAAAA C % % M M A A C % % M M A A CCCC % % % % % % Macintosh Utility Methods for MagickCore % % % % Software Design % % John Cristy % % September 1996 % % % % % % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % % obtain a copy of the License at % % % % http://www.imagemagick.org/script/license.php % % % % Unless required by applicable law or agreed to in writing, software % % distributed under the License is distributed on an "AS IS" BASIS, % % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % % See the License for the specific language governing permissions and % % limitations under the License. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % The directory methods are strongly based on similar methods written % by Steve Summit, scs@eskimo.com. The Ghostscript launch code is strongly % based on Dave Schooley's Mac Gnuplot and contributed by % schindall@wave14i.nrl.navy.mil. Mac-centric improvements contributed by % leonardr@digapp.com. % % */ #if defined(macintosh) /* Include declarations. */ #define _X_H #define _WIDGET_H #include #include #include #include #include #include #include #include #include #include #include #include #include #define ColorInfo KolorInfo #include "MagickCore/studio.h" #include "MagickCore/blob.h" #include "MagickCore/client.h" #include "MagickCore/exception.h" #include "MagickCore/exception-private.h" #include "MagickCore/image-private.h" #include "MagickCore/list.h" #include "MagickCore/magick.h" #include "MagickCore/monitor.h" #include "MagickCore/monitor-private.h" #include "MagickCore/quantum.h" #include "MagickCore/string_.h" #include "MagickCore/utility.h" #include "MagickCore/mac.h" /* Global declaractions. */ ImageDescriptionHandle image_description = nil; /* Forward declaractions. */ static Boolean SearchForFile(OSType,OSType,FSSpec *,short); static pascal void ArcMethod(GrafVerb,Rect *,short,short), BitsMethod(BitMap *,Rect *,Rect *,short,RgnHandle), FilenameToFSSpec(const char *filename,FSSpec *fsspec), LineMethod(Point), OvalMethod(GrafVerb,Rect *), PolyMethod(GrafVerb,PolyHandle), RRectMethod(GrafVerb,Rect *,short,short), RectMethod(GrafVerb,Rect *), RegionMethod(GrafVerb,RgnHandle), StandardPixmap(PixMapPtr,Rect *,MatrixRecordPtr,short,RgnHandle,PixMapPtr, Rect *,short), TextMethod(short,Ptr,Point,Point); /* Static declarations */ #if defined(DISABLE_SIOUX) static MACEventHookPtr event_hook = nil; static MACErrorHookPtr exception.hook = nil; #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % B o t t l e n e c k T e s t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % BottleneckTest() intercepts any compressed images. % % The format of the BottleneckTest method is: % % int BottleneckTest(const char *magick) % % A description of each parameter follows: % % o picture: Specifies a pointer to a PicHandle structure. % % o codec: the code type is returned in this CodecType pointer structure. % % o depth: the image depth is returned as an integer pointer. % % o colormap_id: the colormap ID is returned in this short pointer. % % */ static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle, short arcAngle) { #pragma unused (verb,r,startAngle,arcAngle) } static pascal void BitsMethod(BitMap *bitPtr,Rect *source_rectangle, Rect *dstRect,short mode,RgnHandle maskRgn) { #pragma unused (bitPtr,source_rectangle,dstRect,mode,maskRgn) } static pascal void LineMethod(Point newPt) { #pragma unused (newPt) } static pascal void OvalMethod(GrafVerb verb,Rect *r) { #pragma unused (verb,r) } static pascal void PolyMethod(GrafVerb verb,PolyHandle poly) { #pragma unused (verb,poly) } static pascal void RectMethod(GrafVerb verb,Rect *r) { #pragma unused (verb,r) } static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn) { #pragma unused (verb,rgn) } static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth, short ovalHeight) { #pragma unused (verb,r,ovalWidth,ovalHeight) } static pascal void StandardPixmap(PixMapPtr source,Rect *source_rectangle, MatrixRecordPtr matrix,short mode,RgnHandle mask,PixMapPtr matte, Rect *matte_rectangle,short flags) { #pragma unused (source_rectangle,matrix,mode,mask,matte,matte_rectangle,flags) Ptr data; ssize_t size; GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil); } static pascal void TextMethod(short byteCount,Ptr textBuf,Point numer, Point denom) { #pragma unused (byteCount,textBuf,numer,denom) } #if !defined(DISABLE_QUICKTIME) static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth, short *colormap_id) { CQDProcs bottlenecks; int status; Rect rectangle; ssize_t version; status=Gestalt(gestaltQuickTime,&version); if (status != noErr) { ParamText("\pQuickTime not installed. Please install, then try again.", "\p","\p","\p"); Alert(128,nil); return(-1); } /* Define our own bottlenecks to do nothing. */ SetStdCProcs(&bottlenecks); bottlenecks.textProc=NewQDTextUPP(&TextMethod); bottlenecks.lineProc=NewQDLineUPP(&LineMethod); bottlenecks.rectProc=NewQDRectUPP(&RectMethod); bottlenecks.rRectProc=NewQDRRectUPP(&RRectMethod); bottlenecks.ovalProc=NewQDOvalUPP(&OvalMethod); bottlenecks.arcProc=NewQDArcUPP(&ArcMethod); bottlenecks.polyProc=NewQDPolyUPP(&PolyMethod); bottlenecks.rgnProc=NewQDRgnUPP(&RegionMethod); bottlenecks.bitsProc=NewQDBitsUPP(&BitsMethod); bottlenecks.newProc1=(UniversalProcPtr) NewStdPixUPP(&StandardPixmap); /* Install our custom bottlenecks to intercept any compressed images. */ (*(qd.thePort)).grafProcs=(QDProcs *) &bottlenecks; DrawPicture(picture,&((**picture).picFrame)); PaintRect(&rectangle); (*(qd.thePort)).grafProcs=0L; /* Initialize our return values. */ *codec='unkn'; *depth=0; *colormap_id=(-1); if (image_description != nil) { *codec=(**image_description).cType; *depth=(**image_description).depth; *colormap_id=(**image_description).clutID; } DisposeQDTextUPP(bottlenecks.textProc); DisposeQDLineUPP(bottlenecks.lineProc); DisposeQDRectUPP(bottlenecks.rectProc); DisposeQDRRectUPP(bottlenecks.rRectProc); DisposeQDOvalUPP(bottlenecks.ovalProc); DisposeQDArcUPP(bottlenecks.arcProc); DisposeQDPolyUPP(bottlenecks.polyProc); DisposeQDRgnUPP(bottlenecks.rgnProc); DisposeQDBitsUPP(bottlenecks.bitsProc); DisposeStdPixUPP(bottlenecks.newProc1); return(0); } #endif #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % c l o s e d i r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % closedir() closes the named directory stream and frees the DIR structure. % % The format of the closedir method is: % % closedir(entry) % % A description of each parameter follows: % % o entry: Specifies a pointer to a DIR structure. % % */ MagickExport void closedir(DIR *entry) { if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); assert(entry != (DIR *) NULL); RelinquishMagickMemory(entry); } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % E x i t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Exit() exits the process. % % The format of the exit method is: % % Exit(status) % % A description of each parameter follows: % % o status: an integer value representing the status of the terminating % process. % % */ MagickExport int Exit(int status) { #if !defined(DISABLE_SIOUX) (void) FormatLocaleFile(stdout,"Select File->Quit to exit.\n"); #endif exit(status); return(0); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % F i l e n a m e T o F S S p e c % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FilenameToFSSpec() sets the file type of an image. % % The format of the FilenameToFSSpec method is: % % FilenameToFSSpec(filename,fsspec) % % A description of each parameter follows: % % o filename: Specifies the name of the file. % % o fsspec: A pointer to type FSSpec. % % */ MagickExport void pascal FilenameToFSSpec(const char *filename,FSSpec *fsspec) { Str255 name; assert(filename != (char *) NULL); c2pstrcpy(name,filename); FSMakeFSSpec(0,0,name,fsspec); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % I s M a g i c k C o n f l i c t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACIsMagickConflict() returns true if the image format conflicts with a % logical drive (.e.g. X:). % % Contributed by Mark Gavin of Digital Applications, Inc. % % The format of the MACIsMagickConflict method is: % % status=MACIsMagickConflict(magick) % % A description of each parameter follows: % % o magick: Specifies the image format. % % */ static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume, size_t *free_bytes,size_t *total_bytes) { HParamBlockRec pb; OSErr result; size_t blocksize; unsigned short allocation_blocks, free_blocks; /* Use the File Manager to get the real vRefNum. */ pb.volumeParam.ioVRefNum=0; pb.volumeParam.ioNamePtr=volume_name; pb.volumeParam.ioVolIndex=volume_index; result=PBHGetVInfoSync(&pb); if (result != noErr) return(result); *volume=pb.volumeParam.ioVRefNum; blocksize=(size_t) pb.volumeParam.ioVAlBlkSiz; allocation_blocks=(unsigned short) pb.volumeParam.ioVNmAlBlks; free_blocks=(unsigned short) pb.volumeParam.ioVFrBlk; *free_bytes=free_blocks*blocksize; *total_bytes=allocation_blocks*blocksize; return(result); } MagickExport MagickBooleanType MACIsMagickConflict(const char *magick) { size_t free_bytes, number_bytes; OSErr status; short volume; Str255 volume_name; assert(magick != (char *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick); (void) CopyMagickString((char *) volume_name,magick,MaxTextExtent); c2pstr((char *) volume_name); if (volume_name[volume_name[0]] != ':') volume_name[++volume_name[0]]=':'; status=HGetVInfo(-1,volume_name,&volume,&free_bytes,&number_bytes); return(status != 0 ? MagickFalse : MagickTrue); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + M A C E r r o r H a n d l e r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACErrorHandler() displays an error reason and then terminates the program. % % The format of the MACErrorHandler method is: % % void MACErrorHandler(const ExceptionType error,const char *reason, % const char *description) % % A description of each parameter follows: % % o exception: Specifies the numeric error category. % % o reason: Specifies the reason to display before terminating the % program. % % o description: Specifies any description to the reason. % % */ MagickExport void MACErrorHandler(const ExceptionType error,const char *reason, const char *description) { char buffer[3*MaxTextExtent]; if (reason == (char *) NULL) return; if (description == (char *) NULL) (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(), reason); else (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n", GetClientName(),reason,description); #if defined(DISABLE_SIOUX) if(exception.hook != (MACErrorHookPtr) NULL) exception.hook(error,buffer); else { MagickCoreTerminus(); exit(error); } #else puts(buffer); MagickCoreTerminus(); exit(error); #endif } #if defined(DISABLE_SIOUX) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % + M A C F a t a l E r r o r H a n d l e r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACFatalErrorHandler() displays an error reason and then terminates the % program. % % The format of the MACFatalErrorHandler method is: % % void MACFatalErrorHandler(const ExceptionType severity, % const char *reason,const char *description) % % A description of each parameter follows: % % o severity: Specifies the numeric error category. % % o reason: Specifies the reason to display before terminating the % program. % % o description: Specifies any description to the reason. % */ static void MACFatalErrorHandler(const ExceptionType severity, const char *reason,const char *description) { char buffer[3*MaxTextExtent]; if (reason == (char *) NULL) return; if (description == (char *) NULL) (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(), reason); else (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n", GetClientName(),reason,description); if(exception.hook != (MACErrorHookPtr) NULL) exception.hook(severity, buffer); else { MagickCoreTerminus(); exit(severity); } } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S E x e c u t e C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSExecuteCommand() executes the Ghostscript command. % % */ static OSErr MacGSExecuteCommand(const char *command,ssize_t length) { AEAddressDesc event_descriptor; AEDesc reply = {typeNull, NULL}; AppleEvent event = {typeNull, NULL}; DescType descriptor_type; int error; OSType id = 'gsVR'; Size actualSize; /* Send the Apple Event. */ (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor); (void) AECreateAppleEvent(id,'exec',&event_descriptor,-1,kAnyTransactionID, &event); (void) AEPutParamPtr(&event,keyDirectObject,typeChar,command,length); (void) AESend(&event,&reply,kAEWaitReply+kAENeverInteract,kAENormalPriority, kNoTimeOut,NULL,NULL); /* Handle the reply and exit. */ (void) AEGetParamPtr(&reply,keyDirectObject,typeInteger,&descriptor_type, &error,sizeof(error),&actualSize); (void) AEDisposeDesc(&event_descriptor); (void) AEDisposeDesc(&event); if (reply.descriptorType != NULL) AEDisposeDesc(&reply); return((OSErr) error); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S L a u n c h A p p l i c a t i o n C o r e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSLaunchApplicationCore() launches the Ghostscript command. % % */ static OSErr MacGSLaunchApplicationCore(ssize_t flags) { FSSpec file_info; LaunchParamBlockRec launch_info; OSErr error; if (!SearchForFile('gsVR','APPL',&file_info,1)) return(-43); launch_info.launchBlockID=extendedBlock; launch_info.launchEPBLength=extendedBlockLen; launch_info.launchFileFlags=0; launch_info.launchControlFlags=launchContinue+launchNoFileFlags+flags; launch_info.launchAppSpec=(&file_info); launch_info.launchAppParameters=nil; error=LaunchApplication(&launch_info); return(error); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S L a u n c h A p p l i c a t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSLaunchApplication() launches the Ghostscript command. % % */ static OSErr MacGSLaunchApplication(void) { return(MacGSLaunchApplicationCore(launchDontSwitch)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S L a u n c h A p p l i c a t i o n T o F r o n t % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSLaunchApplicationToFront() moves the Ghostscript window to the front. % % */ static OSErr MacGSLaunchApplicationToFront(void) { return(MacGSLaunchApplicationCore(0)); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S Q u i t A p p l i c a t i o n % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSQuitApplication() quits the Ghostscript application. % % */ static void MacGSQuitApplication(void) { AEAddressDesc event_descriptor; AEDesc reply = {typeNull, NULL}; AppleEvent event = {typeNull, NULL}; OSType id = 'GPLT'; /* Send the Apple Event. */ (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor); (void) AECreateAppleEvent(typeAppleEvent,kAEQuitApplication, &event_descriptor,-1,kAnyTransactionID,&event); (void) AESend(&event,&reply,kAENoReply,kAENormalPriority,kNoTimeOut,NULL, NULL); /* Clean up and exit. */ (void) AEDisposeDesc(&event_descriptor); (void) AEDisposeDesc(&event); if (reply.descriptorType != NULL) AEDisposeDesc(&reply); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M a c G S S e t W o r k i n g F o l d e r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MacGSSetWorkingFolder() set the Ghostscript working folder. % % */ static OSErr MacGSSetWorkingFolder(char *directory) { AEDesc application_descriptor, event_descriptor, object, path_descriptor, type_descriptor, reply; AppleEvent event; DescType folder_type = 'wfdr'; OSErr error; OSType id = 'GPLT'; /* Send the Apple Event. */ AECreateDesc(typeNull,NULL,0,&application_descriptor); AECreateDesc(typeChar,directory,strlen(directory),&path_descriptor); (void) AECreateDesc(typeType,&folder_type,sizeof(DescType),&type_descriptor); CreateObjSpecifier(cProperty,&application_descriptor,formPropertyID, &type_descriptor,0,&object); (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor); (void) AECreateAppleEvent(kAECoreSuite,kAESetData,&event_descriptor,-1, kAnyTransactionID,&event); (void) AEPutParamDesc(&event,keyDirectObject,&object); (void) AEPutParamDesc(&event,keyAEData,&path_descriptor); error=AESend(&event,&reply,kAENoReply+kAENeverInteract,kAENormalPriority, kNoTimeOut,NULL,NULL); (void) AEDisposeDesc(&event); (void) AEDisposeDesc(&event_descriptor); (void) AEDisposeDesc(&object); (void) AEDisposeDesc(&type_descriptor); (void) AEDisposeDesc(&path_descriptor); (void) AEDisposeDesc(&application_descriptor); return(error); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M A C S e t E r r o r H o o k % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACSetErrorHook sets a callback function which is called if any error % occurs within ImageMagick. % % The format of the MACSetErrorHook method is: % % int MACSetErrorHook(MACErrorHookPtr hook) % % A description of each parameter follows: % % o hook: This function pointer is the callback function. % % */ MagickExport void MACSetErrorHook(MACErrorHookPtr hook) { /* We forget any previously set exception.hook. */ exception.hook=hook; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M A C S e t E v e n t H o o k % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACSetEventHook sets a callback function which is called every time % ImageMagick likes to release the processor. % % The format of the MACSetEventHook method is: % % int MACSetEventHook(MACEventHookPtr hook) % % A description of each parameter follows: % % o hook: This function pointer is the callback function. % % */ MagickExport void MACSetEventHook(MACEventHookPtr hook) { /* We forget any previously set event hook. */ event_hook=hook; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M A C S y s t e m C o m m a n d % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method MACSystemCommand executes the specified command and waits until it % terminates. The returned value is the exit status of the command. % % The format of the MACSystemCommand method is: % % int MACSystemCommand(MagickFalse,const char * command) % % A description of each parameter follows: % % o command: This string is the command to execute. % */ MagickExport int MACSystemCommand(const char * command) { /* We only know how to launch Ghostscript. */ if (MacGSLaunchApplicationToFront()) return(-1); return(MacGSExecuteCommand(command,strlen(command))); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % M A C W a r n i n g H a n d l e r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MACWarningHandler() displays a warning reason. % % The format of the MACWarningHandler method is: % + void MACWarningHandler(const ExceptionType warning,const char *reason, % const char *description) % % A description of each parameter follows: % % o warning: Specifies the numeric warning category. % % o reason: Specifies the reason to display before terminating the % program. % % o description: Specifies any description to the reason. % % */ MagickExport void MACWarningHandler(const ExceptionType warning, const char *reason,const char *description) { char buffer[1664]; if (reason == (char *) NULL) return; if (description == (char *) NULL) (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(), reason); else (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n", GetClientName(),reason,description); #if defined(DISABLE_SIOUX) if(exception.hook != (MACErrorHookPtr) NULL) exception.hook(warning, buffer); #else (void)warning; puts(buffer); #endif } #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % o p e n d i r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % opendir() opens the directory named by filename and associates a directory % stream with it. % % The format of the opendir method is: % % MagickExport DIR *opendir(char *path) % % A description of each parameter follows: % % o entry: Specifies a pointer to a DIR structure. % % */ MagickExport DIR *opendir(const char *path) { Str255 pathname; CInfoPBRec search_info; DIR *entry; int error; search_info.hFileInfo.ioNamePtr=0; if ((path != (char *) NULL) || (*path != '\0')) if ((path[0] != '.') || (path[1] != '\0')) { c2pstrcpy(pathname,path); search_info.hFileInfo.ioNamePtr=pathname; } search_info.hFileInfo.ioCompletion=0; search_info.hFileInfo.ioVRefNum=0; search_info.hFileInfo.ioFDirIndex=0; search_info.hFileInfo.ioDirID=0; error=PBGetCatInfoSync(&search_info); if (error != noErr) { errno=error; return((DIR *) NULL); } entry=(DIR *) AcquireMagickMemory(sizeof(DIR)); if (entry == (DIR *) NULL) return((DIR *) NULL); entry->d_VRefNum=search_info.hFileInfo.ioVRefNum; entry->d_DirID=search_info.hFileInfo.ioDirID; entry->d_index=1; return(entry); } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % P r o c e s s P e n d i n g E v e n t s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ProcessPendingEvents() processes any pending events. This prevents % ImageMagick from monopolizing the processor. % % The format of the ProcessPendingEvents method is: % % ProcessPendingEvents(text) % % A description of each parameter follows: % % o text: A character string representing the current process. % % */ MagickExport void ProcessPendingEvents(const char *text) { #if defined(DISABLE_SIOUX) if (event_hook != (MACEventHookPtr) NULL) event_hook(text); #else static const char *mark = (char *) NULL; EventRecord event; while (WaitNextEvent(everyEvent,&event,0L,nil)) SIOUXHandleOneEvent(&event); if (isatty(STDIN_FILENO) && (text != mark)) { (void) puts(text); mark=text; } #endif } #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % r e a d d i r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % readdir() returns a pointer to a structure representing the directory entry % at the current position in the directory stream to which entry refers. % % The format of the readdir % % struct dirent *readdir(DIR *entry) % % A description of each parameter follows: % % o entry: Specifies a pointer to a DIR structure. % % */ MagickExport struct dirent *readdir(DIR *entry) { CInfoPBRec search_info; int error; static struct dirent dir_entry; static unsigned char pathname[MaxTextExtent]; if (entry == (DIR *) NULL) return((struct dirent *) NULL); search_info.hFileInfo.ioCompletion=0; search_info.hFileInfo.ioNamePtr=pathname; search_info.hFileInfo.ioVRefNum=0; search_info.hFileInfo.ioFDirIndex=entry->d_index; search_info.hFileInfo.ioDirID=entry->d_DirID; error=PBGetCatInfoSync(&search_info); if (error != noErr) { errno=error; return((struct dirent *) NULL); } entry->d_index++; p2cstrcpy(dir_entry.d_name,search_info.hFileInfo.ioNamePtr); dir_entry.d_namlen=strlen(dir_entry.d_name); return(&dir_entry); } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R e a d P I C T I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ReadPICTImage() reads an Apple Macintosh QuickDraw/PICT image file using % MacOS QuickDraw methods and returns it. It allocates the memory necessary % for the new Image structure and returns a pointer to the new image. % % This method was written and contributed by spd@daphne.cps.unizar.es % (feel free to copy and use it as you want. No warranty). % % The format of the ReadPICTImage method is: % % Image *ReadPICTImage(const ImageInfo *image_info, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: Method ReadPICTImage returns a pointer to the image after % reading. A null image is returned if there is a memory shortage or % if the image cannot be read. % % o image_info: the image info.. % % o exception: return any errors or warnings in this structure. % */ static inline size_t MagickMax(const size_t x,const size_t y) { if (x > y) return(x); return(y); } MagickExport Image *ReadPICTImage(const ImageInfo *image_info, ExceptionInfo *exception) { #define PICTHeaderSize 512 CodecType codec; GDHandle device; GWorldPtr graphic_world, port; Image *image; int depth, status; MagickBooleanType proceed, status; PicHandle picture_handle; PictInfo picture_info; QDErr theErr = noErr; Rect rectangle; RGBColor Pixel; short colormap_id; ssize_t y; /* Open image file. */ image=AcquireImage(image_info); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) return(NULL); picture_handle=(PicHandle) NewHandle(MagickMax(GetBlobSize(image)- PICTHeaderSize,PICTHeaderSize)); if (picture_handle == nil) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); HLock((Handle) picture_handle); (void) ReadBlob(image,PICTHeaderSize,*(unsigned char **) picture_handle); status=ReadBlob(image,GetBlobSize(image)-PICTHeaderSize,*(unsigned char **) picture_handle); if (status == MagickFalse) { DisposeHandle((Handle) picture_handle); ThrowReaderException(CorruptImageError,"UnableToReadImageData"); } GetGWorld(&port,&device); theErr=NewGWorld(&graphic_world,0,&(**picture_handle).picFrame,nil,nil, useTempMem | keepLocal); if ((theErr != noErr) && (graphic_world == nil)) { DisposeHandle((Handle) picture_handle); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } HUnlock((Handle) picture_handle); SetGWorld(graphic_world,nil); theErr=GetPictInfo(picture_handle,&picture_info,0,1,systemMethod,0); if (theErr != noErr) { DisposeGWorld(graphic_world); DisposeHandle((Handle) picture_handle); ThrowReaderException(CorruptImageError,"UnableToReadImageData"); } #if defined(DISABLE_QUICKTIME) codec='unkn'; colormap_id=(-1); depth=picture_info.depth; #else BottleneckTest(picture_handle,&codec,&depth,&colormap_id); #endif switch (codec) { case 'rpza': case 'jpeg': case 'rle ': case 'raw ': case 'smc ': { if (depth > 200) { depth-=32; picture_info.theColorTable=GetCTable(colormap_id); } break; } default: { depth=picture_info.depth; if (depth <= 8) (void) GetPictInfo(picture_handle,&picture_info,returnColorTable, (short) (1 << picture_info.depth),systemMethod,0); break; } } image->x_resolution=(picture_info.hRes) >> 16; image->y_resolution=(picture_info.vRes) >> 16; image->units=PixelsPerInchResolution; image->columns=picture_info.sourceRect.right-picture_info.sourceRect.left; image->rows=picture_info.sourceRect.bottom-picture_info.sourceRect.top; if ((depth <= 8) && ((*(picture_info.theColorTable))->ctSize != 0)) { size_t number_colors; /* Colormapped PICT image. */ number_colors=(*(picture_info.theColorTable))->ctSize; if (!AcquireImageColormap(image,number_colors)) { if (picture_info.theColorTable != nil) DisposeHandle((Handle) picture_info.theColorTable); DisposeGWorld(graphic_world); DisposeHandle((Handle) picture_handle); ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); } for (x=0; x < image->colors; x++) { image->colormap[x].red= (*(picture_info.theColorTable))->ctTable[x].rgb.red; image->colormap[x].green= (*(picture_info.theColorTable))->ctTable[x].rgb.green; image->colormap[x].blue= (*(picture_info.theColorTable))->ctTable[x].rgb.blue; } } SetRect(&rectangle,0,0,image->columns,image->rows); (void) UpdateGWorld(&graphic_world,depth,&rectangle, picture_info.theColorTable,nil,0); LockPixels(GetGWorldPixMap(graphic_world)); /*->portPixMap); */ EraseRect(&rectangle); DrawPicture(picture_handle,&rectangle); if ((depth <= 8) && (colormap_id == -1)) { DisposeHandle((Handle) picture_info.theColorTable); picture_info.theColorTable=nil; } DisposeHandle((Handle) picture_handle); /* Convert PICT pixels to pixel packets. */ for (y=0; y < image->rows; y++) { register ssize_t x; register Quantum *restrict q; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; for (x=0; x < image->columns; x++) { GetCPixel(x,y,&Pixel); SetPixelRed(image,ScaleCharToQuantum(Pixel.red & 0xff),q); SetPixelGreen(image,ScaleCharToQuantum(Pixel.green & 0xff),q); SetPixelBlue(image,ScaleCharToQuantum(Pixel.blue & 0xff),q); if (image->storage_class == PseudoClass) SetPixelIndex(image,Color2Index(&Pixel),q); q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) break; proceed=SetImageProgress(image,LoadImageTag,y,image->rows); if (proceed == MagickFalse) break; } UnlockPixels(GetGWorldPixMap(graphic_world)); SetGWorld(port,device); if (picture_info.theColorTable != nil) DisposeHandle((Handle) picture_info.theColorTable); DisposeGWorld(graphic_world); (void) CloseBlob(image); return(image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e a r c h F o r F i l e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SearchForFile() searches for a file. % % */ static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file, short count) { char *buffer; CInfoPBRec search1_info, search2_info; FSSpec application; HParamBlockRec parameter_info; OSErr error; ProcessInfoRec application_info; ProcessSerialNumber serial_number; ssize_t buffer_size = 16384; serial_number.lowLongOfPSN=kCurrentProcess; serial_number.highLongOfPSN=0; application_info.processInfoLength=sizeof(ProcessInfoRec); application_info.processName=NULL; application_info.processAppSpec=(&application); GetProcessInformation(&serial_number,&application_info); buffer=NewPtr(buffer_size); if (buffer == (char *) NULL) return(false); parameter_info.csParam.ioCompletion=NULL; parameter_info.csParam.ioNamePtr=NULL; parameter_info.csParam.ioVRefNum=application.vRefNum; parameter_info.csParam.ioMatchPtr=file; parameter_info.csParam.ioReqMatchCount=count; parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo; parameter_info.csParam.ioSearchInfo1=&search1_info; parameter_info.csParam.ioSearchInfo2=&search2_info; parameter_info.csParam.ioSearchTime=0; parameter_info.csParam.ioCatPosition.initialize=0; parameter_info.csParam.ioOptBuffer=buffer; parameter_info.csParam.ioOptBufSize=buffer_size; search1_info.hFileInfo.ioNamePtr=NULL; search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type; search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type; search1_info.hFileInfo.ioFlAttrib=0; search1_info.hFileInfo.ioFlParID=0; search2_info=search1_info; search2_info.hFileInfo.ioFlAttrib=0x10; search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type; search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1); search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0; search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0; search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0; search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0; search2_info.hFileInfo.ioFlParID=0; error=PBCatSearchSync((CSParamPtr) ¶meter_info); DisposePtr(buffer); if (parameter_info.csParam.ioReqMatchCount == parameter_info.csParam.ioActMatchCount) error=eofErr; if (parameter_info.csParam.ioActMatchCount == 0) error=0; return(error == eofErr); } #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % s e e k d i r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % seekdir() sets the position of the next readdir() operation on the directory % stream. % % The format of the seekdir method is: % % void seekdir(DIR *entry,ssize_t position) % % A description of each parameter follows: % % o entry: Specifies a pointer to a DIR structure. % % o position: specifies the position associated with the directory % stream. % % % */ MagickExport void seekdir(DIR *entry,ssize_t position) { assert(entry != (DIR *) NULL); entry->d_index=position; } #endif /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % S e t A p p l i c a t i o n T y p e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % SetApplicationType() sets the file type of an image. % % The format of the SetApplicationType method is: % % void SetApplicationType(const char *filename,const char *magick, % OSType application) % % A description of each parameter follows: % % o filename: Specifies the name of the file. % % o filename: Specifies the file type. % % o application: Specifies the type of the application. % */ static inline size_t MagickMin(const size_t x,const size_t y) { if (x < y) return(x); return(y); } MagickExport void SetApplicationType(const char *filename,const char *magick, OSType application) { FSSpec file_specification; OSType filetype; Str255 name; assert(filename != (char *) NULL); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); assert(magick != (const char *) NULL); filetype=' '; (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick), 4)); if (LocaleCompare(magick,"JPG") == 0) (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent); c2pstrcpy(name,filename); FSMakeFSSpec(0,0,name,&file_specification); FSpCreate(&file_specification,application,filetype,smSystemScript); } #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % t e l l d i r % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Method telldir returns the current location associated with the % named directory stream. % % The format of the telldir method is: % % telldir(DIR *entry) % % A description of each parameter follows: % % o entry: Specifies a pointer to a DIR structure. % % */ MagickExport ssize_t telldir(DIR *entry) { return(entry->d_index); } #endif #endif