blob: 984990717a49bf3ef986b56857bc4ef6a352dacf [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M AAA CCCC %
7% MM MM A A C %
8% M M M AAAAA C %
9% M M A A C %
10% M M A A CCCC %
11% %
12% %
13% Macintosh Utility Methods for MagickCore %
14% %
15% Software Design %
16% John Cristy %
17% September 1996 %
18% %
19% %
20% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% The directory methods are strongly based on similar methods written
37% by Steve Summit, scs@eskimo.com. The Ghostscript launch code is strongly
38% based on Dave Schooley's Mac Gnuplot and contributed by
39% schindall@wave14i.nrl.navy.mil. Mac-centric improvements contributed by
40% leonardr@digapp.com.
41%
42%
43*/
44
45#if defined(macintosh)
46/*
47 Include declarations.
48*/
49#define _X_H
50#define _WIDGET_H
51#include <AppleEvents.h>
52#include <AERegistry.h>
53#include <AEObjects.h>
54#include <AEPackObject.h>
55#include <Processes.h>
56#include <QuickDraw.h>
57#include <QDOffscreen.h>
58#include <Palettes.h>
59#include <ImageCompression.h>
60#include <PictUtils.h>
61#include <Files.h>
62#include <Gestalt.h>
63#include <TextUtils.h>
64#define ColorInfo KolorInfo
65#include "magick/studio.h"
66#include "magick/blob.h"
67#include "magick/client.h"
68#include "magick/exception.h"
69#include "magick/exception-private.h"
70#include "magick/image-private.h"
71#include "magick/list.h"
72#include "magick/magick.h"
73#include "magick/monitor.h"
74#include "magick/monitor-private.h"
75#include "magick/quantum.h"
76#include "magick/string_.h"
77#include "magick/utility.h"
78#include "magick/mac.h"
79
80/*
81 Global declaractions.
82*/
83ImageDescriptionHandle
84 image_description = nil;
85
86/*
87 Forward declaractions.
88*/
89static Boolean
90 SearchForFile(OSType,OSType,FSSpec *,short);
91
92static pascal void
93 ArcMethod(GrafVerb,Rect *,short,short),
94 BitsMethod(BitMap *,Rect *,Rect *,short,RgnHandle),
95 FilenameToFSSpec(const char *filename,FSSpec *fsspec),
96 LineMethod(Point),
97 OvalMethod(GrafVerb,Rect *),
98 PolyMethod(GrafVerb,PolyHandle),
99 RRectMethod(GrafVerb,Rect *,short,short),
100 RectMethod(GrafVerb,Rect *),
101 RegionMethod(GrafVerb,RgnHandle),
102 StandardPixmap(PixMapPtr,Rect *,MatrixRecordPtr,short,RgnHandle,PixMapPtr,
103 Rect *,short),
104 TextMethod(short,Ptr,Point,Point);
105
106/*
107 Static declarations
108 */
109#if defined(DISABLE_SIOUX)
110static MACEventHookPtr
111 event_hook = nil;
112
113static MACErrorHookPtr
114 exception.hook = nil;
115#endif
116
117/*
118%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119% %
120% %
121% %
122% B o t t l e n e c k T e s t %
123% %
124% %
125% %
126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127%
128% BottleneckTest() intercepts any compressed images.
129%
130% The format of the BottleneckTest method is:
131%
132% int BottleneckTest(const char *magick)
133%
134% A description of each parameter follows:
135%
136% o picture: Specifies a pointer to a PicHandle structure.
137%
138% o codec: the code type is returned in this CodecType pointer structure.
139%
140% o depth: the image depth is returned as an integer pointer.
141%
142% o colormap_id: the colormap ID is returned in this short pointer.
143%
144%
145*/
146
147static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle,
148 short arcAngle)
149{
150#pragma unused (verb,r,startAngle,arcAngle)
151}
152
153static pascal void BitsMethod(BitMap *bitPtr,Rect *source_rectangle,
154 Rect *dstRect,short mode,RgnHandle maskRgn)
155{
156#pragma unused (bitPtr,source_rectangle,dstRect,mode,maskRgn)
157}
158
159static pascal void LineMethod(Point newPt)
160{
161#pragma unused (newPt)
162}
163
164static pascal void OvalMethod(GrafVerb verb,Rect *r)
165{
166#pragma unused (verb,r)
167}
168
169static pascal void PolyMethod(GrafVerb verb,PolyHandle poly)
170{
171#pragma unused (verb,poly)
172}
173
174static pascal void RectMethod(GrafVerb verb,Rect *r)
175{
176#pragma unused (verb,r)
177}
178
179static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn)
180{
181#pragma unused (verb,rgn)
182}
183
184static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth,
185 short ovalHeight)
186{
187#pragma unused (verb,r,ovalWidth,ovalHeight)
188}
189
190static pascal void StandardPixmap(PixMapPtr source,Rect *source_rectangle,
191 MatrixRecordPtr matrix,short mode,RgnHandle mask,PixMapPtr matte,
192 Rect *matte_rectangle,short flags)
193{
194#pragma unused (source_rectangle,matrix,mode,mask,matte,matte_rectangle,flags)
195
196 long
197 size;
198
199 Ptr
200 data;
201
202 GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil);
203}
204
205static pascal void TextMethod(short byteCount,Ptr textBuf,Point numer,
206 Point denom)
207{
208#pragma unused (byteCount,textBuf,numer,denom)
209}
210
211#if !defined(DISABLE_QUICKTIME)
212static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth,
213 short *colormap_id)
214{
215 CQDProcs
216 bottlenecks;
217
218 int
219 status;
220
221 long
222 version;
223
224 Rect
225 rectangle;
226
227 status=Gestalt(gestaltQuickTime,&version);
228 if (status != noErr)
229 {
230 ParamText("\pQuickTime not installed. Please install, then try again.",
231 "\p","\p","\p");
232 Alert(128,nil);
233 return(-1);
234 }
235 /*
236 Define our own bottlenecks to do nothing.
237 */
238 SetStdCProcs(&bottlenecks);
239 bottlenecks.textProc=NewQDTextUPP(&TextMethod);
240 bottlenecks.lineProc=NewQDLineUPP(&LineMethod);
241 bottlenecks.rectProc=NewQDRectUPP(&RectMethod);
242 bottlenecks.rRectProc=NewQDRRectUPP(&RRectMethod);
243 bottlenecks.ovalProc=NewQDOvalUPP(&OvalMethod);
244 bottlenecks.arcProc=NewQDArcUPP(&ArcMethod);
245 bottlenecks.polyProc=NewQDPolyUPP(&PolyMethod);
246 bottlenecks.rgnProc=NewQDRgnUPP(&RegionMethod);
247 bottlenecks.bitsProc=NewQDBitsUPP(&BitsMethod);
248 bottlenecks.newProc1=(UniversalProcPtr) NewStdPixUPP(&StandardPixmap);
249 /*
250 Install our custom bottlenecks to intercept any compressed images.
251 */
252 (*(qd.thePort)).grafProcs=(QDProcs *) &bottlenecks;
253 DrawPicture(picture,&((**picture).picFrame));
254 PaintRect(&rectangle);
255 (*(qd.thePort)).grafProcs=0L;
256 /*
257 Initialize our return values.
258 */
259 *codec='unkn';
260 *depth=0;
261 *colormap_id=(-1);
262 if (image_description != nil)
263 {
264 *codec=(**image_description).cType;
265 *depth=(**image_description).depth;
266 *colormap_id=(**image_description).clutID;
267 }
268 DisposeQDTextUPP(bottlenecks.textProc);
269 DisposeQDLineUPP(bottlenecks.lineProc);
270 DisposeQDRectUPP(bottlenecks.rectProc);
271 DisposeQDRRectUPP(bottlenecks.rRectProc);
272 DisposeQDOvalUPP(bottlenecks.ovalProc);
273 DisposeQDArcUPP(bottlenecks.arcProc);
274 DisposeQDPolyUPP(bottlenecks.polyProc);
275 DisposeQDRgnUPP(bottlenecks.rgnProc);
276 DisposeQDBitsUPP(bottlenecks.bitsProc);
277 DisposeStdPixUPP(bottlenecks.newProc1);
278 return(0);
279}
280#endif
281
282#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
283/*
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285% %
286% %
287% %
288% c l o s e d i r %
289% %
290% %
291% %
292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293%
294% closedir() closes the named directory stream and frees the DIR structure.
295%
296% The format of the closedir method is:
297%
298% closedir(entry)
299%
300% A description of each parameter follows:
301%
302% o entry: Specifies a pointer to a DIR structure.
303%
304%
305*/
306MagickExport void closedir(DIR *entry)
307{
308 if (image->debug != MagickFalse)
309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
310 assert(entry != (DIR *) NULL);
311 RelinquishMagickMemory(entry);
312}
313#endif
314
315/*
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317% %
318% %
319% %
320% E x i t %
321% %
322% %
323% %
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325%
326% Exit() exits the process.
327%
328% The format of the exit method is:
329%
330% Exit(status)
331%
332% A description of each parameter follows:
333%
334% o status: an integer value representing the status of the terminating
335% process.
336%
337%
338*/
339MagickExport int Exit(int status)
340{
341#if !defined(DISABLE_SIOUX)
342 (void) fprintf(stdout,"Select File->Quit to exit.\n");
343#endif
344 exit(status);
345 return(0);
346}
347
348/*
349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350% %
351% %
352% %
353% F i l e n a m e T o F S S p e c %
354% %
355% %
356% %
357%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
358%
359% FilenameToFSSpec() sets the file type of an image.
360%
361% The format of the FilenameToFSSpec method is:
362%
363% FilenameToFSSpec(filename,fsspec)
364%
365% A description of each parameter follows:
366%
367% o filename: Specifies the name of the file.
368%
369% o fsspec: A pointer to type FSSpec.
370%
371%
372*/
373MagickExport void pascal FilenameToFSSpec(const char *filename,FSSpec *fsspec)
374{
375 Str255
376 name;
377
378 assert(filename != (char *) NULL);
379 c2pstrcpy(name,filename);
380 FSMakeFSSpec(0,0,name,fsspec);
381}
382
383/*
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385% %
386% %
387% %
388% I s M a g i c k C o n f l i c t %
389% %
390% %
391% %
392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393%
394% MACIsMagickConflict() returns true if the image format conflicts with a
395% logical drive (.e.g. X:).
396%
397% Contributed by Mark Gavin of Digital Applications, Inc.
398%
399% The format of the MACIsMagickConflict method is:
400%
401% status=MACIsMagickConflict(magick)
402%
403% A description of each parameter follows:
404%
405% o magick: Specifies the image format.
406%
407%
408*/
409
410static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume,
411 unsigned long *free_bytes,unsigned long *total_bytes)
412{
413 HParamBlockRec
414 pb;
415
416 OSErr
417 result;
418
419 unsigned long
420 blocksize;
421
422 unsigned short
423 allocation_blocks,
424 free_blocks;
425
426 /*
427 Use the File Manager to get the real vRefNum.
428 */
429 pb.volumeParam.ioVRefNum=0;
430 pb.volumeParam.ioNamePtr=volume_name;
431 pb.volumeParam.ioVolIndex=volume_index;
432 result=PBHGetVInfoSync(&pb);
433 if (result != noErr)
434 return(result);
435 *volume=pb.volumeParam.ioVRefNum;
436 blocksize=(unsigned long) pb.volumeParam.ioVAlBlkSiz;
437 allocation_blocks=(unsigned short) pb.volumeParam.ioVNmAlBlks;
438 free_blocks=(unsigned short) pb.volumeParam.ioVFrBlk;
439 *free_bytes=free_blocks*blocksize;
440 *total_bytes=allocation_blocks*blocksize;
441 return(result);
442}
443
444MagickExport MagickBooleanType MACIsMagickConflict(const char *magick)
445{
446 unsigned long
447 free_bytes,
448 number_bytes;
449
450 OSErr
451 status;
452
453 short
454 volume;
455
456 Str255
457 volume_name;
458
459 assert(magick != (char *) NULL);
460 if (image->debug != MagickFalse)
461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick);
462 (void) CopyMagickString((char *) volume_name,magick,MaxTextExtent);
463 c2pstr((char *) volume_name);
464 if (volume_name[volume_name[0]] != ':')
465 volume_name[++volume_name[0]]=':';
466 status=HGetVInfo(-1,volume_name,&volume,&free_bytes,&number_bytes);
467 return(status != 0 ? MagickFalse : MagickTrue);
468}
469
470/*
471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472% %
473% %
474% %
475+ M A C E r r o r H a n d l e r %
476% %
477% %
478% %
479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480%
481% MACErrorHandler() displays an error reason and then terminates the program.
482%
483% The format of the MACErrorHandler method is:
484%
485% void MACErrorHandler(const ExceptionType error,const char *reason,
486% const char *description)
487%
488% A description of each parameter follows:
489%
490% o exception: Specifies the numeric error category.
491%
492% o reason: Specifies the reason to display before terminating the
493% program.
494%
495% o description: Specifies any description to the reason.
496%
497%
498*/
499MagickExport void MACErrorHandler(const ExceptionType error,const char *reason,
500 const char *description)
501{
502 char
503 buffer[3*MaxTextExtent];
504
505 if (reason == (char *) NULL)
506 return;
507 if (description == (char *) NULL)
508 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
509 reason);
510 else
511 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
512 GetClientName(),reason,description);
513#if defined(DISABLE_SIOUX)
514 if(exception.hook != (MACErrorHookPtr) NULL)
515 exception.hook(error,buffer);
516 else
517 {
518 MagickCoreTerminus();
519 exit(error);
520 }
521#else
522 puts(buffer);
523 MagickCoreTerminus();
524 exit(error);
525#endif
526}
527
528#if defined(DISABLE_SIOUX)
529/*
530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531% %
532% %
533% %
534+ M A C F a t a l E r r o r H a n d l e r %
535% %
536% %
537% %
538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539%
540% MACFatalErrorHandler() displays an error reason and then terminates the
541% program.
542%
543% The format of the MACFatalErrorHandler method is:
544%
545% void MACFatalErrorHandler(const ExceptionType severity,
546% const char *reason,const char *description)
547%
548% A description of each parameter follows:
549%
550% o severity: Specifies the numeric error category.
551%
552% o reason: Specifies the reason to display before terminating the
553% program.
554%
555% o description: Specifies any description to the reason.
556%
557%
558*/
559static void MACFatalErrorHandler(const ExceptionType severity,
560 const char *reason,const char *description)
561{
562 char
563 buffer[3*MaxTextExtent];
564
565 if (reason == (char *) NULL)
566 return;
567 if (description == (char *) NULL)
568 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
569 reason);
570 else
571 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
572 GetClientName(),reason,description);
573 if(exception.hook != (MACErrorHookPtr) NULL)
574 exception.hook(severity, buffer);
575 else
576 {
577 MagickCoreTerminus();
578 exit(severity);
579 }
580}
581#endif
582
583/*
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585% %
586% %
587% %
588% M a c G S E x e c u t e C o m m a n d %
589% %
590% %
591% %
592%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593%
594% MacGSExecuteCommand() executes the Ghostscript command.
595%
596%
597*/
598static OSErr MacGSExecuteCommand(const char *command,long length)
599{
600 AEAddressDesc
601 event_descriptor;
602
603 AEDesc
604 reply = {typeNull, NULL};
605
606 AppleEvent
607 event = {typeNull, NULL};
608
609 DescType
610 descriptor_type;
611
612 int
613 error;
614
615 OSType
616 id = 'gsVR';
617
618 Size
619 actualSize;
620
621 /*
622 Send the Apple Event.
623 */
624 (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
625 (void) AECreateAppleEvent(id,'exec',&event_descriptor,-1,kAnyTransactionID,
626 &event);
627 (void) AEPutParamPtr(&event,keyDirectObject,typeChar,command,length);
628 (void) AESend(&event,&reply,kAEWaitReply+kAENeverInteract,kAENormalPriority,
629 kNoTimeOut,NULL,NULL);
630 /*
631 Handle the reply and exit.
632 */
633 (void) AEGetParamPtr(&reply,keyDirectObject,typeInteger,&descriptor_type,
634 &error,sizeof(error),&actualSize);
635 (void) AEDisposeDesc(&event_descriptor);
636 (void) AEDisposeDesc(&event);
637 if (reply.descriptorType != NULL)
638 AEDisposeDesc(&reply);
639 return((OSErr) error);
640}
641
642/*
643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644% %
645% %
646% %
647% 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 %
648% %
649% %
650% %
651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652%
653% MacGSLaunchApplicationCore() launches the Ghostscript command.
654%
655%
656*/
657static OSErr MacGSLaunchApplicationCore(long flags)
658{
659 FSSpec
660 file_info;
661
662 LaunchParamBlockRec
663 launch_info;
664
665 OSErr
666 error;
667
668 if (!SearchForFile('gsVR','APPL',&file_info,1))
669 return(-43);
670 launch_info.launchBlockID=extendedBlock;
671 launch_info.launchEPBLength=extendedBlockLen;
672 launch_info.launchFileFlags=0;
673 launch_info.launchControlFlags=launchContinue+launchNoFileFlags+flags;
674 launch_info.launchAppSpec=(&file_info);
675 launch_info.launchAppParameters=nil;
676 error=LaunchApplication(&launch_info);
677 return(error);
678}
679
680/*
681%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
682% %
683% %
684% %
685% M a c G S L a u n c h A p p l i c a t i o n %
686% %
687% %
688% %
689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
690%
691% MacGSLaunchApplication() launches the Ghostscript command.
692%
693%
694*/
695static OSErr MacGSLaunchApplication(void)
696{
697 return(MacGSLaunchApplicationCore(launchDontSwitch));
698}
699
700/*
701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702% %
703% %
704% %
705% 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 %
706% %
707% %
708% %
709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710%
711% MacGSLaunchApplicationToFront() moves the Ghostscript window to the front.
712%
713%
714*/
715static OSErr MacGSLaunchApplicationToFront(void)
716{
717 return(MacGSLaunchApplicationCore(0));
718}
719
720/*
721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722% %
723% %
724% %
725% M a c G S Q u i t A p p l i c a t i o n %
726% %
727% %
728% %
729%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
730%
731% MacGSQuitApplication() quits the Ghostscript application.
732%
733%
734*/
735static void MacGSQuitApplication(void)
736{
737 AEAddressDesc
738 event_descriptor;
739
740 AEDesc
741 reply = {typeNull, NULL};
742
743 AppleEvent
744 event = {typeNull, NULL};
745
746 OSType
747 id = 'GPLT';
748
749 /*
750 Send the Apple Event.
751 */
752 (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
753 (void) AECreateAppleEvent(typeAppleEvent,kAEQuitApplication,
754 &event_descriptor,-1,kAnyTransactionID,&event);
755 (void) AESend(&event,&reply,kAENoReply,kAENormalPriority,kNoTimeOut,NULL,
756 NULL);
757 /*
758 Clean up and exit.
759 */
760 (void) AEDisposeDesc(&event_descriptor);
761 (void) AEDisposeDesc(&event);
762 if (reply.descriptorType != NULL)
763 AEDisposeDesc(&reply);
764}
765
766/*
767%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768% %
769% %
770% %
771% M a c G S S e t W o r k i n g F o l d e r %
772% %
773% %
774% %
775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776%
777% MacGSSetWorkingFolder() set the Ghostscript working folder.
778%
779%
780*/
781static OSErr MacGSSetWorkingFolder(char *directory)
782{
783 AEDesc
784 application_descriptor,
785 event_descriptor,
786 object,
787 path_descriptor,
788 type_descriptor,
789 reply;
790
791 AppleEvent
792 event;
793
794 DescType
795 folder_type = 'wfdr';
796
797 OSErr
798 error;
799
800 OSType
801 id = 'GPLT';
802
803 /*
804 Send the Apple Event.
805 */
806 AECreateDesc(typeNull,NULL,0,&application_descriptor);
807 AECreateDesc(typeChar,directory,strlen(directory),&path_descriptor);
808 (void) AECreateDesc(typeType,&folder_type,sizeof(DescType),&type_descriptor);
809 CreateObjSpecifier(cProperty,&application_descriptor,formPropertyID,
810 &type_descriptor,0,&object);
811 (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
812 (void) AECreateAppleEvent(kAECoreSuite,kAESetData,&event_descriptor,-1,
813 kAnyTransactionID,&event);
814 (void) AEPutParamDesc(&event,keyDirectObject,&object);
815 (void) AEPutParamDesc(&event,keyAEData,&path_descriptor);
816 error=AESend(&event,&reply,kAENoReply+kAENeverInteract,kAENormalPriority,
817 kNoTimeOut,NULL,NULL);
818 (void) AEDisposeDesc(&event);
819 (void) AEDisposeDesc(&event_descriptor);
820 (void) AEDisposeDesc(&object);
821 (void) AEDisposeDesc(&type_descriptor);
822 (void) AEDisposeDesc(&path_descriptor);
823 (void) AEDisposeDesc(&application_descriptor);
824 return(error);
825}
826
827/*
828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829% %
830% %
831% %
832% M A C S e t E r r o r H o o k %
833% %
834% %
835% %
836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837%
838% MACSetErrorHook sets a callback function which is called if any error
839% occurs within ImageMagick.
840%
841% The format of the MACSetErrorHook method is:
842%
843% int MACSetErrorHook(MACErrorHookPtr hook)
844%
845% A description of each parameter follows:
846%
847% o hook: This function pointer is the callback function.
848%
849%
850*/
851MagickExport void MACSetErrorHook(MACErrorHookPtr hook)
852{
853 /*
854 We forget any previously set exception.hook.
855 */
856 exception.hook=hook;
857}
858
859/*
860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861% %
862% %
863% %
864% M A C S e t E v e n t H o o k %
865% %
866% %
867% %
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869%
870% MACSetEventHook sets a callback function which is called every time
871% ImageMagick likes to release the processor.
872%
873% The format of the MACSetEventHook method is:
874%
875% int MACSetEventHook(MACEventHookPtr hook)
876%
877% A description of each parameter follows:
878%
879% o hook: This function pointer is the callback function.
880%
881%
882*/
883MagickExport void MACSetEventHook(MACEventHookPtr hook)
884{
885 /*
886 We forget any previously set event hook.
887 */
888 event_hook=hook;
889}
890
891/*
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893% %
894% %
895% %
896% M A C S y s t e m C o m m a n d %
897% %
898% %
899% %
900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901%
902% Method MACSystemCommand executes the specified command and waits until it
903% terminates. The returned value is the exit status of the command.
904%
905% The format of the MACSystemCommand method is:
906%
907% int MACSystemCommand(const char * command)
908%
909% A description of each parameter follows:
910%
911% o command: This string is the command to execute.
912%
913%
914*/
915MagickExport int MACSystemCommand(const char * command)
916{
917 /*
918 We only know how to launch Ghostscript.
919 */
920 if (MacGSLaunchApplicationToFront())
921 return(-1);
922 return(MacGSExecuteCommand(command,strlen(command)));
923}
924
925/*
926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927% %
928% %
929% %
930% M A C W a r n i n g H a n d l e r %
931% %
932% %
933% %
934%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935%
936% MACWarningHandler() displays a warning reason.
937%
938% The format of the MACWarningHandler method is:
939%
940+ void MACWarningHandler(const ExceptionType warning,const char *reason,
941% const char *description)
942%
943% A description of each parameter follows:
944%
945% o warning: Specifies the numeric warning category.
946%
947% o reason: Specifies the reason to display before terminating the
948% program.
949%
950% o description: Specifies any description to the reason.
951%
952%
953*/
954MagickExport void MACWarningHandler(const ExceptionType warning,
955 const char *reason,const char *description)
956{
957 char
958 buffer[1664];
959
960 if (reason == (char *) NULL)
961 return;
962 if (description == (char *) NULL)
963 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
964 reason);
965 else
966 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
967 GetClientName(),reason,description);
968#if defined(DISABLE_SIOUX)
969 if(exception.hook != (MACErrorHookPtr) NULL)
970 exception.hook(warning, buffer);
971#else
972 (void)warning;
973 puts(buffer);
974#endif
975}
976
977#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
978/*
979%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980% %
981% %
982% %
983% o p e n d i r %
984% %
985% %
986% %
987%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
988%
989% opendir() opens the directory named by filename and associates a directory
990% stream with it.
991%
992% The format of the opendir method is:
993%
994% MagickExport DIR *opendir(char *path)
995%
996% A description of each parameter follows:
997%
998% o entry: Specifies a pointer to a DIR structure.
999%
1000%
1001*/
1002MagickExport DIR *opendir(const char *path)
1003{
1004 Str255 pathname;
1005
1006 CInfoPBRec
1007 search_info;
1008
1009 DIR
1010 *entry;
1011
1012 int
1013 error;
1014
1015 search_info.hFileInfo.ioNamePtr=0;
1016 if ((path != (char *) NULL) || (*path != '\0'))
1017 if ((path[0] != '.') || (path[1] != '\0'))
1018 {
1019 c2pstrcpy(pathname,path);
1020 search_info.hFileInfo.ioNamePtr=pathname;
1021 }
1022 search_info.hFileInfo.ioCompletion=0;
1023 search_info.hFileInfo.ioVRefNum=0;
1024 search_info.hFileInfo.ioFDirIndex=0;
1025 search_info.hFileInfo.ioDirID=0;
1026 error=PBGetCatInfoSync(&search_info);
1027 if (error != noErr)
1028 {
1029 errno=error;
1030 return((DIR *) NULL);
1031 }
1032 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1033 if (entry == (DIR *) NULL)
1034 return((DIR *) NULL);
1035 entry->d_VRefNum=search_info.hFileInfo.ioVRefNum;
1036 entry->d_DirID=search_info.hFileInfo.ioDirID;
1037 entry->d_index=1;
1038 return(entry);
1039}
1040#endif
1041
1042/*
1043%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044% %
1045% %
1046% %
1047% P r o c e s s P e n d i n g E v e n t s %
1048% %
1049% %
1050% %
1051%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052%
1053% ProcessPendingEvents() processes any pending events. This prevents
1054% ImageMagick from monopolizing the processor.
1055%
1056% The format of the ProcessPendingEvents method is:
1057%
1058% ProcessPendingEvents(text)
1059%
1060% A description of each parameter follows:
1061%
1062% o text: A character string representing the current process.
1063%
1064%
1065*/
1066MagickExport void ProcessPendingEvents(const char *text)
1067{
1068#if defined(DISABLE_SIOUX)
1069 if (event_hook != (MACEventHookPtr) NULL)
1070 event_hook(text);
1071#else
1072 static const char
1073 *mark = (char *) NULL;
1074
1075 EventRecord
1076 event;
1077
1078 while (WaitNextEvent(everyEvent,&event,0L,nil))
1079 SIOUXHandleOneEvent(&event);
1080 if (isatty(STDIN_FILENO) && (text != mark))
1081 {
1082 (void) puts(text);
1083 mark=text;
1084 }
1085#endif
1086}
1087
1088#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1089/*
1090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1091% %
1092% %
1093% %
1094% r e a d d i r %
1095% %
1096% %
1097% %
1098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1099%
1100% readdir() returns a pointer to a structure representing the directory entry
1101% at the current position in the directory stream to which entry refers.
1102%
1103% The format of the readdir
1104%
1105% struct dirent *readdir(DIR *entry)
1106%
1107% A description of each parameter follows:
1108%
1109% o entry: Specifies a pointer to a DIR structure.
1110%
1111%
1112*/
1113MagickExport struct dirent *readdir(DIR *entry)
1114{
1115 CInfoPBRec
1116 search_info;
1117
1118 int
1119 error;
1120
1121 static struct dirent
1122 dir_entry;
1123
1124 static unsigned char
1125 pathname[MaxTextExtent];
1126
1127 if (entry == (DIR *) NULL)
1128 return((struct dirent *) NULL);
1129 search_info.hFileInfo.ioCompletion=0;
1130 search_info.hFileInfo.ioNamePtr=pathname;
1131 search_info.hFileInfo.ioVRefNum=0;
1132 search_info.hFileInfo.ioFDirIndex=entry->d_index;
1133 search_info.hFileInfo.ioDirID=entry->d_DirID;
1134 error=PBGetCatInfoSync(&search_info);
1135 if (error != noErr)
1136 {
1137 errno=error;
1138 return((struct dirent *) NULL);
1139 }
1140 entry->d_index++;
1141 p2cstrcpy(dir_entry.d_name,search_info.hFileInfo.ioNamePtr);
1142 dir_entry.d_namlen=strlen(dir_entry.d_name);
1143 return(&dir_entry);
1144}
1145#endif
1146
1147/*
1148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149% %
1150% %
1151% %
1152% R e a d P I C T I m a g e %
1153% %
1154% %
1155% %
1156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1157%
1158% ReadPICTImage() reads an Apple Macintosh QuickDraw/PICT image file using
1159% MacOS QuickDraw methods and returns it. It allocates the memory necessary
1160% for the new Image structure and returns a pointer to the new image.
1161%
1162% This method was written and contributed by spd@daphne.cps.unizar.es
1163% (feel free to copy and use it as you want. No warranty).
1164%
1165% The format of the ReadPICTImage method is:
1166%
1167% Image *ReadPICTImage(const ImageInfo *image_info,
1168% ExceptionInfo *exception)
1169%
1170% A description of each parameter follows:
1171%
1172% o image: Method ReadPICTImage returns a pointer to the image after
1173% reading. A null image is returned if there is a memory shortage or
1174% if the image cannot be read.
1175%
1176% o image_info: the image info..
1177%
1178% o exception: return any errors or warnings in this structure.
1179%
1180*/
1181
1182static inline size_t MagickMax(const size_t x,const size_t y)
1183{
1184 if (x > y)
1185 return(x);
1186 return(y);
1187}
1188
1189MagickExport Image *ReadPICTImage(const ImageInfo *image_info,
1190 ExceptionInfo *exception)
1191{
1192#define PICTHeaderSize 512
1193
1194 CodecType
1195 codec;
1196
1197 GDHandle
1198 device;
1199
1200 GWorldPtr
1201 graphic_world,
1202 port;
1203
1204 Image
1205 *image;
1206
1207 int
1208 depth,
1209 status;
1210
1211 long
1212 y;
1213
1214 MagickBooleanType
1215 proceed,
1216 status;
1217
1218 PicHandle
1219 picture_handle;
1220
1221 PictInfo
1222 picture_info;
1223
1224 QDErr
1225 theErr = noErr;
1226
1227 Rect
1228 rectangle;
1229
1230 RGBColor
1231 Pixel;
1232
1233 short
1234 colormap_id;
1235
1236 /*
1237 Open image file.
1238 */
1239 image=AcquireImage(image_info);
1240 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
1241 if (status == MagickFalse)
1242 return(NULL);
1243 picture_handle=(PicHandle) NewHandle(MagickMax(GetBlobSize(image)-
1244 PICTHeaderSize,PICTHeaderSize));
1245 if (picture_handle == nil)
1246 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1247 HLock((Handle) picture_handle);
1248 (void) ReadBlob(image,PICTHeaderSize,*(unsigned char **) picture_handle);
1249 status=ReadBlob(image,GetBlobSize(image)-PICTHeaderSize,*(unsigned char **)
1250 picture_handle);
1251 if (status == MagickFalse)
1252 {
1253 DisposeHandle((Handle) picture_handle);
1254 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1255 }
1256 GetGWorld(&port,&device);
1257 theErr=NewGWorld(&graphic_world,0,&(**picture_handle).picFrame,nil,nil,
1258 useTempMem | keepLocal);
1259 if ((theErr != noErr) && (graphic_world == nil))
1260 {
1261 DisposeHandle((Handle) picture_handle);
1262 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1263 }
1264 HUnlock((Handle) picture_handle);
1265 SetGWorld(graphic_world,nil);
1266 theErr=GetPictInfo(picture_handle,&picture_info,0,1,systemMethod,0);
1267 if (theErr != noErr)
1268 {
1269 DisposeGWorld(graphic_world);
1270 DisposeHandle((Handle) picture_handle);
1271 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1272 }
1273#if defined(DISABLE_QUICKTIME)
1274 codec='unkn';
1275 colormap_id=(-1);
1276 depth=picture_info.depth;
1277#else
1278 BottleneckTest(picture_handle,&codec,&depth,&colormap_id);
1279#endif
1280 switch (codec)
1281 {
1282 case 'rpza':
1283 case 'jpeg':
1284 case 'rle ':
1285 case 'raw ':
1286 case 'smc ':
1287 {
1288 if (depth > 200)
1289 {
1290 depth-=32;
1291 picture_info.theColorTable=GetCTable(colormap_id);
1292 }
1293 break;
1294 }
1295 default:
1296 {
1297 depth=picture_info.depth;
1298 if (depth <= 8)
1299 (void) GetPictInfo(picture_handle,&picture_info,returnColorTable,
1300 (short) (1 << picture_info.depth),systemMethod,0);
1301 break;
1302 }
1303 }
1304 image->x_resolution=(picture_info.hRes) >> 16;
1305 image->y_resolution=(picture_info.vRes) >> 16;
1306 image->units=PixelsPerInchResolution;
1307 image->columns=picture_info.sourceRect.right-picture_info.sourceRect.left;
1308 image->rows=picture_info.sourceRect.bottom-picture_info.sourceRect.top;
1309 if ((depth <= 8) && ((*(picture_info.theColorTable))->ctSize != 0))
1310 {
1311 unsigned long
1312 number_colors;
1313
1314 /*
1315 Colormapped PICT image.
1316 */
1317 number_colors=(*(picture_info.theColorTable))->ctSize;
1318 if (!AcquireImageColormap(image,number_colors))
1319 {
1320 if (picture_info.theColorTable != nil)
1321 DisposeHandle((Handle) picture_info.theColorTable);
1322 DisposeGWorld(graphic_world);
1323 DisposeHandle((Handle) picture_handle);
1324 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1325 }
1326 for (x=0; x < image->colors; x++)
1327 {
1328 image->colormap[x].red=
1329 (*(picture_info.theColorTable))->ctTable[x].rgb.red;
1330 image->colormap[x].green=
1331 (*(picture_info.theColorTable))->ctTable[x].rgb.green;
1332 image->colormap[x].blue=
1333 (*(picture_info.theColorTable))->ctTable[x].rgb.blue;
1334 }
1335 }
1336 SetRect(&rectangle,0,0,image->columns,image->rows);
1337 (void) UpdateGWorld(&graphic_world,depth,&rectangle,
1338 picture_info.theColorTable,nil,0);
1339 LockPixels(GetGWorldPixMap(graphic_world)); /*->portPixMap); */
1340 EraseRect(&rectangle);
1341 DrawPicture(picture_handle,&rectangle);
1342 if ((depth <= 8) && (colormap_id == -1))
1343 {
1344 DisposeHandle((Handle) picture_info.theColorTable);
1345 picture_info.theColorTable=nil;
1346 }
1347 DisposeHandle((Handle) picture_handle);
1348 /*
1349 Convert PICT pixels to pixel packets.
1350 */
1351 for (y=0; y < image->rows; y++)
1352 {
1353 register IndexPacket
1354 *__restrict indexes;
1355
1356 register long
1357 x;
1358
1359 register PixelPacket
1360 *__restrict q;
1361
1362 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1363 if (q == (PixelPacket *) NULL)
1364 break;
1365 indexes=GetAuthenticIndexQueue(image);
1366 for (x=0; x < image->columns; x++)
1367 {
1368 GetCPixel(x,y,&Pixel);
1369 q->red=ScaleCharToQuantum(Pixel.red & 0xff);
1370 q->green=ScaleCharToQuantum(Pixel.green & 0xff);
1371 q->blue=ScaleCharToQuantum(Pixel.blue & 0xff);
1372 if (image->storage_class == PseudoClass)
1373 indexes[x]=Color2Index(&Pixel);
1374 q++;
1375 }
1376 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1377 break;
1378 proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
1379 if (proceed == MagickFalse)
1380 break;
1381 }
1382 UnlockPixels(GetGWorldPixMap(graphic_world));
1383 SetGWorld(port,device);
1384 if (picture_info.theColorTable != nil)
1385 DisposeHandle((Handle) picture_info.theColorTable);
1386 DisposeGWorld(graphic_world);
1387 (void) CloseBlob(image);
1388 return(image);
1389}
1390
1391/*
1392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393% %
1394% %
1395% %
1396% S e a r c h F o r F i l e %
1397% %
1398% %
1399% %
1400%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401%
1402% SearchForFile() searches for a file.
1403%
1404%
1405*/
1406static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file,
1407 short count)
1408{
1409 char
1410 *buffer;
1411
1412 CInfoPBRec
1413 search1_info,
1414 search2_info;
1415
1416 FSSpec
1417 application;
1418
1419 HParamBlockRec
1420 parameter_info;
1421
1422 long
1423 buffer_size = 16384;
1424
1425 OSErr
1426 error;
1427
1428 ProcessInfoRec
1429 application_info;
1430
1431 ProcessSerialNumber
1432 serial_number;
1433
1434 serial_number.lowLongOfPSN=kCurrentProcess;
1435 serial_number.highLongOfPSN=0;
1436 application_info.processInfoLength=sizeof(ProcessInfoRec);
1437 application_info.processName=NULL;
1438 application_info.processAppSpec=(&application);
1439 GetProcessInformation(&serial_number,&application_info);
1440 buffer=NewPtr(buffer_size);
1441 if (buffer == (char *) NULL)
1442 return(false);
1443 parameter_info.csParam.ioCompletion=NULL;
1444 parameter_info.csParam.ioNamePtr=NULL;
1445 parameter_info.csParam.ioVRefNum=application.vRefNum;
1446 parameter_info.csParam.ioMatchPtr=file;
1447 parameter_info.csParam.ioReqMatchCount=count;
1448 parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo;
1449 parameter_info.csParam.ioSearchInfo1=&search1_info;
1450 parameter_info.csParam.ioSearchInfo2=&search2_info;
1451 parameter_info.csParam.ioSearchTime=0;
1452 parameter_info.csParam.ioCatPosition.initialize=0;
1453 parameter_info.csParam.ioOptBuffer=buffer;
1454 parameter_info.csParam.ioOptBufSize=buffer_size;
1455 search1_info.hFileInfo.ioNamePtr=NULL;
1456 search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type;
1457 search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1458 search1_info.hFileInfo.ioFlAttrib=0;
1459 search1_info.hFileInfo.ioFlParID=0;
1460 search2_info=search1_info;
1461 search2_info.hFileInfo.ioFlAttrib=0x10;
1462 search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1463 search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1);
1464 search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0;
1465 search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0;
1466 search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0;
1467 search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0;
1468 search2_info.hFileInfo.ioFlParID=0;
1469 error=PBCatSearchSync((CSParamPtr) &parameter_info);
1470 DisposePtr(buffer);
1471 if (parameter_info.csParam.ioReqMatchCount ==
1472 parameter_info.csParam.ioActMatchCount)
1473 error=eofErr;
1474 if (parameter_info.csParam.ioActMatchCount == 0)
1475 error=0;
1476 return(error == eofErr);
1477}
1478
1479#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1480/*
1481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1482% %
1483% %
1484% %
1485% s e e k d i r %
1486% %
1487% %
1488% %
1489%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1490%
1491% seekdir() sets the position of the next readdir() operation on the directory
1492% stream.
1493%
1494% The format of the seekdir method is:
1495%
1496% void seekdir(DIR *entry,long position)
1497%
1498% A description of each parameter follows:
1499%
1500% o entry: Specifies a pointer to a DIR structure.
1501%
1502% o position: specifies the position associated with the directory
1503% stream.
1504%
1505%
1506%
1507*/
1508MagickExport void seekdir(DIR *entry,long position)
1509{
1510 assert(entry != (DIR *) NULL);
1511 entry->d_index=position;
1512}
1513#endif
1514
1515/*
1516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1517% %
1518% %
1519% %
1520% S e t A p p l i c a t i o n T y p e %
1521% %
1522% %
1523% %
1524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1525%
1526% SetApplicationType() sets the file type of an image.
1527%
1528% The format of the SetApplicationType method is:
1529%
1530% void SetApplicationType(const char *filename,const char *magick,
1531% OSType application)
1532%
1533% A description of each parameter follows:
1534%
1535% o filename: Specifies the name of the file.
1536%
1537% o filename: Specifies the file type.
1538%
1539% o application: Specifies the type of the application.
1540%
1541*/
1542
1543static inline size_t MagickMin(const size_t x,const size_t y)
1544{
1545 if (x < y)
1546 return(x);
1547 return(y);
1548}
1549
1550MagickExport void SetApplicationType(const char *filename,const char *magick,
1551 OSType application)
1552{
1553 FSSpec
1554 file_specification;
1555
1556 OSType
1557 filetype;
1558
1559 Str255
1560 name;
1561
1562 assert(filename != (char *) NULL);
1563 if (image->debug != MagickFalse)
1564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1565 assert(magick != (const char *) NULL);
1566 filetype=' ';
1567 (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick),
1568 4));
1569 if (LocaleCompare(magick,"JPG") == 0)
1570 (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent);
1571 c2pstrcpy(name,filename);
1572 FSMakeFSSpec(0,0,name,&file_specification);
1573 FSpCreate(&file_specification,application,filetype,smSystemScript);
1574}
1575
1576#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1577/*
1578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1579% %
1580% %
1581% %
1582% t e l l d i r %
1583% %
1584% %
1585% %
1586%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1587%
1588% Method telldir returns the current location associated with the
1589% named directory stream.
1590%
1591% The format of the telldir method is:
1592%
1593% telldir(DIR *entry)
1594%
1595% A description of each parameter follows:
1596%
1597% o entry: Specifies a pointer to a DIR structure.
1598%
1599%
1600*/
1601MagickExport long telldir(DIR *entry)
1602{
1603 return(entry->d_index);
1604}
1605#endif
1606
1607#endif