]> granicus.if.org Git - imagemagick/blob - MagickCore/mac.c
864eff0a1f7ae39fee474e9397246e5406614223
[imagemagick] / MagickCore / mac.c
1 /*
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-2014 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 \f
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 "MagickCore/studio.h"
66 #include "MagickCore/blob.h"
67 #include "MagickCore/client.h"
68 #include "MagickCore/exception.h"
69 #include "MagickCore/exception-private.h"
70 #include "MagickCore/image-private.h"
71 #include "MagickCore/list.h"
72 #include "MagickCore/magick.h"
73 #include "MagickCore/monitor.h"
74 #include "MagickCore/monitor-private.h"
75 #include "MagickCore/quantum.h"
76 #include "MagickCore/string_.h"
77 #include "MagickCore/utility.h"
78 #include "MagickCore/mac.h"
79 \f
80 /*
81   Global declaractions.
82 */
83 ImageDescriptionHandle
84   image_description = nil;
85 \f
86 /*
87   Forward declaractions.
88 */
89 static Boolean
90   SearchForFile(OSType,OSType,FSSpec *,short);
91
92 static 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 \f
106 /*
107   Static declarations
108  */
109 #if defined(DISABLE_SIOUX)
110 static MACEventHookPtr
111   event_hook = nil;
112
113 static MACErrorHookPtr
114   exception.hook = nil;
115 #endif
116 \f
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
147 static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle,
148   short arcAngle)
149 {
150 #pragma unused (verb,r,startAngle,arcAngle)
151 }
152
153 static 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
159 static pascal void LineMethod(Point newPt)
160 {
161 #pragma unused (newPt)
162 }
163
164 static pascal void OvalMethod(GrafVerb verb,Rect *r)
165 {
166 #pragma unused (verb,r)
167 }
168
169 static pascal void PolyMethod(GrafVerb verb,PolyHandle poly)
170 {
171 #pragma unused (verb,poly)
172 }
173
174 static pascal void RectMethod(GrafVerb verb,Rect *r)
175 {
176 #pragma unused (verb,r)
177 }
178
179 static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn)
180 {
181 #pragma unused (verb,rgn)
182 }
183
184 static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth,
185   short ovalHeight)
186 {
187 #pragma unused (verb,r,ovalWidth,ovalHeight)
188 }
189
190 static 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   Ptr
197     data;
198
199   ssize_t
200     size;
201
202   GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil);
203 }
204
205 static 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)
212 static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth,
213   short *colormap_id)
214 {
215   CQDProcs
216     bottlenecks;
217
218   int
219     status;
220
221   Rect
222     rectangle;
223
224   ssize_t
225     version;
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 \f
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 */
306 MagickExport 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 \f
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 */
339 MagickExport int Exit(int status)
340 {
341 #if !defined(DISABLE_SIOUX)
342   (void) FormatLocaleFile(stdout,"Select File->Quit to exit.\n");
343 #endif
344   exit(status);
345   return(0);
346 }
347 \f
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 */
373 MagickExport 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 \f
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
410 static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume,
411   size_t *free_bytes,size_t *total_bytes)
412 {
413   HParamBlockRec
414     pb;
415
416   OSErr
417     result;
418
419   size_t
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=(size_t) 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
444 MagickExport MagickBooleanType MACIsMagickConflict(const char *magick)
445 {
446   size_t
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 \f
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 */
499 MagickExport 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) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
509       reason);
510   else
511     (void) FormatLocaleString(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 \f
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 static void MACFatalErrorHandler(const ExceptionType severity,
559   const char *reason,const char *description)
560 {
561   char
562     buffer[3*MaxTextExtent];
563
564   if (reason == (char *) NULL)
565     return;
566   if (description == (char *) NULL)
567     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
568       reason);
569   else
570     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
571       GetClientName(),reason,description);
572   if(exception.hook != (MACErrorHookPtr) NULL)
573     exception.hook(severity, buffer);
574   else
575     {
576       MagickCoreTerminus();
577       exit(severity);
578     }
579 }
580 #endif
581 \f
582 /*
583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
584 %                                                                             %
585 %                                                                             %
586 %                                                                             %
587 %   M a c G S E x e c u t e C o m m a n d                                     %
588 %                                                                             %
589 %                                                                             %
590 %                                                                             %
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592 %
593 %  MacGSExecuteCommand() executes the Ghostscript command.
594 %
595 %
596 */
597 static OSErr MacGSExecuteCommand(const char *command,ssize_t length)
598 {
599   AEAddressDesc
600     event_descriptor;
601
602   AEDesc
603     reply = {typeNull, NULL};
604
605   AppleEvent
606     event = {typeNull, NULL};
607
608   DescType
609     descriptor_type;
610
611   int
612     error;
613
614   OSType
615     id = 'gsVR';
616
617   Size
618     actualSize;
619
620   /*
621     Send the Apple Event.
622   */
623   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
624   (void) AECreateAppleEvent(id,'exec',&event_descriptor,-1,kAnyTransactionID,
625     &event);
626   (void) AEPutParamPtr(&event,keyDirectObject,typeChar,command,length);
627   (void) AESend(&event,&reply,kAEWaitReply+kAENeverInteract,kAENormalPriority,
628     kNoTimeOut,NULL,NULL);
629   /*
630     Handle the reply and exit.
631   */
632   (void) AEGetParamPtr(&reply,keyDirectObject,typeInteger,&descriptor_type,
633     &error,sizeof(error),&actualSize);
634   (void) AEDisposeDesc(&event_descriptor);
635   (void) AEDisposeDesc(&event);
636   if (reply.descriptorType != NULL)
637     AEDisposeDesc(&reply);
638   return((OSErr) error);
639 }
640 \f
641 /*
642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
643 %                                                                             %
644 %                                                                             %
645 %                                                                             %
646 %   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                       %
647 %                                                                             %
648 %                                                                             %
649 %                                                                             %
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651 %
652 %  MacGSLaunchApplicationCore() launches the Ghostscript command.
653 %
654 %
655 */
656 static OSErr MacGSLaunchApplicationCore(ssize_t flags)
657 {
658   FSSpec
659     file_info;
660
661   LaunchParamBlockRec
662     launch_info;
663
664   OSErr
665     error;
666
667   if (!SearchForFile('gsVR','APPL',&file_info,1))
668     return(-43);
669   launch_info.launchBlockID=extendedBlock;
670   launch_info.launchEPBLength=extendedBlockLen;
671   launch_info.launchFileFlags=0;
672   launch_info.launchControlFlags=launchContinue+launchNoFileFlags+flags;
673   launch_info.launchAppSpec=(&file_info);
674   launch_info.launchAppParameters=nil;
675   error=LaunchApplication(&launch_info);
676   return(error);
677 }
678 \f
679 /*
680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681 %                                                                             %
682 %                                                                             %
683 %                                                                             %
684 %   M a c G S L a u n c h A p p l i c a t i o n                               %
685 %                                                                             %
686 %                                                                             %
687 %                                                                             %
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689 %
690 %  MacGSLaunchApplication() launches the Ghostscript command.
691 %
692 %
693 */
694 static OSErr MacGSLaunchApplication(void)
695 {
696   return(MacGSLaunchApplicationCore(launchDontSwitch));
697 }
698 \f
699 /*
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 %                                                                             %
702 %                                                                             %
703 %                                                                             %
704 %   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                 %
705 %                                                                             %
706 %                                                                             %
707 %                                                                             %
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709 %
710 %  MacGSLaunchApplicationToFront() moves the Ghostscript window to the front.
711 %
712 %
713 */
714 static OSErr MacGSLaunchApplicationToFront(void)
715 {
716   return(MacGSLaunchApplicationCore(0));
717 }
718 \f
719 /*
720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721 %                                                                             %
722 %                                                                             %
723 %                                                                             %
724 %   M a c G S Q u i t A p p l i c a t i o n                                   %
725 %                                                                             %
726 %                                                                             %
727 %                                                                             %
728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
729 %
730 %  MacGSQuitApplication() quits the Ghostscript application.
731 %
732 %
733 */
734 static void MacGSQuitApplication(void)
735 {
736   AEAddressDesc
737     event_descriptor;
738
739   AEDesc
740     reply = {typeNull, NULL};
741
742   AppleEvent
743     event = {typeNull, NULL};
744
745   OSType
746     id = 'GPLT';
747
748   /*
749     Send the Apple Event.
750   */
751   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
752   (void) AECreateAppleEvent(typeAppleEvent,kAEQuitApplication,
753     &event_descriptor,-1,kAnyTransactionID,&event);
754   (void) AESend(&event,&reply,kAENoReply,kAENormalPriority,kNoTimeOut,NULL,
755     NULL);
756   /*
757     Clean up and exit.
758   */
759   (void) AEDisposeDesc(&event_descriptor);
760   (void) AEDisposeDesc(&event);
761   if (reply.descriptorType != NULL)
762     AEDisposeDesc(&reply);
763 }
764 \f
765 /*
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 %                                                                             %
768 %                                                                             %
769 %                                                                             %
770 %   M a c G S S e t W o r k i n g F o l d e r                                 %
771 %                                                                             %
772 %                                                                             %
773 %                                                                             %
774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775 %
776 %  MacGSSetWorkingFolder() set the Ghostscript working folder.
777 %
778 %
779 */
780 static OSErr MacGSSetWorkingFolder(char *directory)
781 {
782   AEDesc
783     application_descriptor,
784     event_descriptor,
785     object,
786     path_descriptor,
787     type_descriptor,
788     reply;
789
790   AppleEvent
791     event;
792
793   DescType
794     folder_type = 'wfdr';
795
796   OSErr
797     error;
798
799   OSType
800     id = 'GPLT';
801
802   /*
803     Send the Apple Event.
804   */
805   AECreateDesc(typeNull,NULL,0,&application_descriptor);
806   AECreateDesc(typeChar,directory,strlen(directory),&path_descriptor);
807   (void) AECreateDesc(typeType,&folder_type,sizeof(DescType),&type_descriptor);
808   CreateObjSpecifier(cProperty,&application_descriptor,formPropertyID,
809     &type_descriptor,0,&object);
810   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
811   (void) AECreateAppleEvent(kAECoreSuite,kAESetData,&event_descriptor,-1,
812     kAnyTransactionID,&event);
813   (void) AEPutParamDesc(&event,keyDirectObject,&object);
814   (void) AEPutParamDesc(&event,keyAEData,&path_descriptor);
815   error=AESend(&event,&reply,kAENoReply+kAENeverInteract,kAENormalPriority,
816     kNoTimeOut,NULL,NULL);
817   (void) AEDisposeDesc(&event);
818   (void) AEDisposeDesc(&event_descriptor);
819   (void) AEDisposeDesc(&object);
820   (void) AEDisposeDesc(&type_descriptor);
821   (void) AEDisposeDesc(&path_descriptor);
822   (void) AEDisposeDesc(&application_descriptor);
823   return(error);
824 }
825 \f
826 /*
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 %                                                                             %
829 %                                                                             %
830 %                                                                             %
831 %   M A C S e t E r r o r H o o k                                             %
832 %                                                                             %
833 %                                                                             %
834 %                                                                             %
835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 %
837 %   MACSetErrorHook sets a callback function which is called if any error
838 %   occurs within ImageMagick.
839 %
840 %  The format of the MACSetErrorHook method is:
841 %
842 %      int MACSetErrorHook(MACErrorHookPtr hook)
843 %
844 %  A description of each parameter follows:
845 %
846 %    o hook: This function pointer is the callback function.
847 %
848 %
849 */
850 MagickExport void MACSetErrorHook(MACErrorHookPtr hook)
851 {
852   /*
853     We forget any previously set exception.hook.
854   */
855   exception.hook=hook;
856 }
857 \f
858 /*
859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860 %                                                                             %
861 %                                                                             %
862 %                                                                             %
863 %   M A C S e t E v e n t H o o k                                             %
864 %                                                                             %
865 %                                                                             %
866 %                                                                             %
867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868 %
869 %   MACSetEventHook sets a callback function which is called every time
870 %   ImageMagick likes to release the processor.
871 %
872 %  The format of the MACSetEventHook method is:
873 %
874 %      int MACSetEventHook(MACEventHookPtr hook)
875 %
876 %  A description of each parameter follows:
877 %
878 %    o hook: This function pointer is the callback function.
879 %
880 %
881 */
882 MagickExport void MACSetEventHook(MACEventHookPtr hook)
883 {
884   /*
885     We forget any previously set event hook.
886    */
887   event_hook=hook;
888 }
889 \f
890 /*
891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 %                                                                             %
893 %                                                                             %
894 %                                                                             %
895 %   M A C S y s t e m C o m m a n d                                           %
896 %                                                                             %
897 %                                                                             %
898 %                                                                             %
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900 %
901 %   Method MACSystemCommand executes the specified command and waits until it
902 %   terminates.  The returned value is the exit status of the command.
903 %
904 %  The format of the MACSystemCommand method is:
905 %
906 %      int MACSystemCommand(MagickFalse,const char * command)
907 %
908 %  A description of each parameter follows:
909 %
910 %    o command: This string is the command to execute.
911 %
912 */
913 MagickExport int MACSystemCommand(const char * command)
914 {
915   /*
916     We only know how to launch Ghostscript.
917   */
918   if (MacGSLaunchApplicationToFront())
919     return(-1);
920   return(MacGSExecuteCommand(command,strlen(command)));
921 }
922 \f
923 /*
924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
925 %                                                                             %
926 %                                                                             %
927 %                                                                             %
928 %   M A C W a r n i n g H a n d l e r                                         %
929 %                                                                             %
930 %                                                                             %
931 %                                                                             %
932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933 %
934 %  MACWarningHandler() displays a warning reason.
935 %
936 %  The format of the MACWarningHandler method is:
937 %
938 +      void MACWarningHandler(const ExceptionType warning,const char *reason,
939 %        const char *description)
940 %
941 %  A description of each parameter follows:
942 %
943 %    o warning: Specifies the numeric warning category.
944 %
945 %    o reason: Specifies the reason to display before terminating the
946 %      program.
947 %
948 %    o description: Specifies any description to the reason.
949 %
950 %
951 */
952 MagickExport void MACWarningHandler(const ExceptionType warning,
953   const char *reason,const char *description)
954 {
955   char
956     buffer[1664];
957
958   if (reason == (char *) NULL)
959     return;
960   if (description == (char *) NULL)
961     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
962       reason);
963   else
964     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
965       GetClientName(),reason,description);
966 #if defined(DISABLE_SIOUX)
967   if(exception.hook != (MACErrorHookPtr) NULL)
968     exception.hook(warning, buffer);
969 #else
970   (void)warning;
971   puts(buffer);
972 #endif
973 }
974 \f
975 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
976 /*
977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978 %                                                                             %
979 %                                                                             %
980 %                                                                             %
981 %   o p e n d i r                                                             %
982 %                                                                             %
983 %                                                                             %
984 %                                                                             %
985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986 %
987 %  opendir() opens the directory named by filename and associates a directory
988 %  stream with it.
989 %
990 %  The format of the opendir method is:
991 %
992 %      MagickExport DIR *opendir(char *path)
993 %
994 %  A description of each parameter follows:
995 %
996 %    o entry: Specifies a pointer to a DIR structure.
997 %
998 %
999 */
1000 MagickExport DIR *opendir(const char *path)
1001 {
1002   Str255 pathname;
1003
1004   CInfoPBRec
1005     search_info;
1006
1007   DIR
1008     *entry;
1009
1010   int
1011     error;
1012
1013   search_info.hFileInfo.ioNamePtr=0;
1014   if ((path != (char *) NULL) || (*path != '\0'))
1015     if ((path[0] != '.') || (path[1] != '\0'))
1016       {
1017         c2pstrcpy(pathname,path);
1018         search_info.hFileInfo.ioNamePtr=pathname;
1019       }
1020   search_info.hFileInfo.ioCompletion=0;
1021   search_info.hFileInfo.ioVRefNum=0;
1022   search_info.hFileInfo.ioFDirIndex=0;
1023   search_info.hFileInfo.ioDirID=0;
1024   error=PBGetCatInfoSync(&search_info);
1025   if (error != noErr)
1026     {
1027       errno=error;
1028       return((DIR *) NULL);
1029     }
1030   entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1031   if (entry == (DIR *) NULL)
1032     return((DIR *) NULL);
1033   entry->d_VRefNum=search_info.hFileInfo.ioVRefNum;
1034   entry->d_DirID=search_info.hFileInfo.ioDirID;
1035   entry->d_index=1;
1036   return(entry);
1037 }
1038 #endif
1039 \f
1040 /*
1041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042 %                                                                             %
1043 %                                                                             %
1044 %                                                                             %
1045 %   P r o c e s s P e n d i n g E v e n t s                                   %
1046 %                                                                             %
1047 %                                                                             %
1048 %                                                                             %
1049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050 %
1051 %  ProcessPendingEvents() processes any pending events.  This prevents
1052 %  ImageMagick from monopolizing the processor.
1053 %
1054 %  The format of the ProcessPendingEvents method is:
1055 %
1056 %      ProcessPendingEvents(text)
1057 %
1058 %  A description of each parameter follows:
1059 %
1060 %    o text: A character string representing the current process.
1061 %
1062 %
1063 */
1064 MagickExport void ProcessPendingEvents(const char *text)
1065 {
1066 #if defined(DISABLE_SIOUX)
1067   if (event_hook != (MACEventHookPtr) NULL)
1068     event_hook(text);
1069 #else
1070   static const char
1071     *mark = (char *) NULL;
1072
1073   EventRecord
1074     event;
1075
1076   while (WaitNextEvent(everyEvent,&event,0L,nil))
1077     SIOUXHandleOneEvent(&event);
1078   if (isatty(STDIN_FILENO) && (text != mark))
1079     {
1080       (void) puts(text);
1081       mark=text;
1082     }
1083 #endif
1084 }
1085 \f
1086 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1087 /*
1088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1089 %                                                                             %
1090 %                                                                             %
1091 %                                                                             %
1092 %   r e a d d i r                                                             %
1093 %                                                                             %
1094 %                                                                             %
1095 %                                                                             %
1096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1097 %
1098 %  readdir() returns a pointer to a structure representing the directory entry
1099 %  at the current position in the directory stream to which entry refers.
1100 %
1101 %  The format of the readdir
1102 %
1103 %      struct dirent *readdir(DIR *entry)
1104 %
1105 %  A description of each parameter follows:
1106 %
1107 %    o entry: Specifies a pointer to a DIR structure.
1108 %
1109 %
1110 */
1111 MagickExport struct dirent *readdir(DIR *entry)
1112 {
1113   CInfoPBRec
1114     search_info;
1115
1116   int
1117     error;
1118
1119   static struct dirent
1120     dir_entry;
1121
1122   static unsigned char
1123     pathname[MaxTextExtent];
1124
1125   if (entry == (DIR *) NULL)
1126     return((struct dirent *) NULL);
1127   search_info.hFileInfo.ioCompletion=0;
1128   search_info.hFileInfo.ioNamePtr=pathname;
1129   search_info.hFileInfo.ioVRefNum=0;
1130   search_info.hFileInfo.ioFDirIndex=entry->d_index;
1131   search_info.hFileInfo.ioDirID=entry->d_DirID;
1132   error=PBGetCatInfoSync(&search_info);
1133   if (error != noErr)
1134     {
1135       errno=error;
1136       return((struct dirent *) NULL);
1137     }
1138   entry->d_index++;
1139   p2cstrcpy(dir_entry.d_name,search_info.hFileInfo.ioNamePtr);
1140   dir_entry.d_namlen=strlen(dir_entry.d_name);
1141   return(&dir_entry);
1142 }
1143 #endif
1144 \f
1145 /*
1146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147 %                                                                             %
1148 %                                                                             %
1149 %                                                                             %
1150 %  R e a d P I C T I m a g e                                                  %
1151 %                                                                             %
1152 %                                                                             %
1153 %                                                                             %
1154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 %
1156 %  ReadPICTImage() reads an Apple Macintosh QuickDraw/PICT image file using
1157 %  MacOS QuickDraw methods and returns it.  It allocates the memory necessary
1158 %  for the new Image structure and returns a pointer to the new image.
1159 %
1160 %  This method was written and contributed by spd@daphne.cps.unizar.es
1161 %  (feel free to copy and use it as you want. No warranty).
1162 %
1163 %  The format of the ReadPICTImage method is:
1164 %
1165 %      Image *ReadPICTImage(const ImageInfo *image_info,
1166 %        ExceptionInfo *exception)
1167 %
1168 %  A description of each parameter follows:
1169 %
1170 %    o image:  Method ReadPICTImage returns a pointer to the image after
1171 %      reading.  A null image is returned if there is a memory shortage or
1172 %      if the image cannot be read.
1173 %
1174 %    o image_info: the image info..
1175 %
1176 %    o exception: return any errors or warnings in this structure.
1177 %
1178 */
1179
1180 static inline size_t MagickMax(const size_t x,const size_t y)
1181 {
1182   if (x > y)
1183     return(x);
1184   return(y);
1185 }
1186
1187 MagickExport Image *ReadPICTImage(const ImageInfo *image_info,
1188   ExceptionInfo *exception)
1189 {
1190 #define PICTHeaderSize    512
1191
1192   CodecType
1193     codec;
1194
1195   GDHandle
1196     device;
1197
1198   GWorldPtr
1199     graphic_world,
1200     port;
1201
1202   Image
1203     *image;
1204
1205   int
1206     depth,
1207     status;
1208
1209   MagickBooleanType
1210     proceed,
1211     status;
1212
1213   PicHandle
1214     picture_handle;
1215
1216   PictInfo
1217     picture_info;
1218
1219   QDErr
1220     theErr = noErr;
1221
1222   Rect
1223     rectangle;
1224
1225   RGBColor
1226     Pixel;
1227
1228   short
1229     colormap_id;
1230
1231   ssize_t
1232     y;
1233
1234   /*
1235     Open image file.
1236   */
1237   image=AcquireImage(image_info,exception);
1238   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
1239   if (status == MagickFalse)
1240     return(NULL);
1241   picture_handle=(PicHandle) NewHandle(MagickMax(GetBlobSize(image)-
1242     PICTHeaderSize,PICTHeaderSize));
1243   if (picture_handle == nil)
1244     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1245   HLock((Handle) picture_handle);
1246   (void) ReadBlob(image,PICTHeaderSize,*(unsigned char **) picture_handle);
1247   status=ReadBlob(image,GetBlobSize(image)-PICTHeaderSize,*(unsigned char **)
1248     picture_handle);
1249   if (status == MagickFalse)
1250     {
1251       DisposeHandle((Handle) picture_handle);
1252       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1253     }
1254   GetGWorld(&port,&device);
1255   theErr=NewGWorld(&graphic_world,0,&(**picture_handle).picFrame,nil,nil,
1256     useTempMem | keepLocal);
1257   if ((theErr != noErr) && (graphic_world == nil))
1258     {
1259       DisposeHandle((Handle) picture_handle);
1260       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1261     }
1262   HUnlock((Handle) picture_handle);
1263   SetGWorld(graphic_world,nil);
1264   theErr=GetPictInfo(picture_handle,&picture_info,0,1,systemMethod,0);
1265   if (theErr != noErr)
1266     {
1267       DisposeGWorld(graphic_world);
1268       DisposeHandle((Handle) picture_handle);
1269       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1270     }
1271 #if defined(DISABLE_QUICKTIME)
1272   codec='unkn';
1273   colormap_id=(-1);
1274   depth=picture_info.depth;
1275 #else
1276   BottleneckTest(picture_handle,&codec,&depth,&colormap_id);
1277 #endif
1278   switch (codec)
1279   {
1280     case 'rpza':
1281     case 'jpeg':
1282     case 'rle ':
1283     case 'raw ':
1284     case 'smc ':
1285     {
1286       if (depth > 200)
1287         {
1288           depth-=32;
1289           picture_info.theColorTable=GetCTable(colormap_id);
1290         }
1291       break;
1292     }
1293     default:
1294     {
1295       depth=picture_info.depth;
1296       if (depth <= 8)
1297         (void) GetPictInfo(picture_handle,&picture_info,returnColorTable,
1298           (short) (1 << picture_info.depth),systemMethod,0);
1299       break;
1300     }
1301   }
1302   image->resolution.x=(picture_info.hRes) >> 16;
1303   image->resolution.y=(picture_info.vRes) >> 16;
1304   image->units=PixelsPerInchResolution;
1305   image->columns=picture_info.sourceRect.right-picture_info.sourceRect.left;
1306   image->rows=picture_info.sourceRect.bottom-picture_info.sourceRect.top;
1307   if ((depth <= 8) && ((*(picture_info.theColorTable))->ctSize != 0))
1308     {
1309       size_t
1310         number_colors;
1311
1312       /*
1313         Colormapped PICT image.
1314       */
1315       number_colors=(*(picture_info.theColorTable))->ctSize;
1316       if (!AcquireImageColormap(image,number_colors))
1317         {
1318           if (picture_info.theColorTable != nil)
1319             DisposeHandle((Handle) picture_info.theColorTable);
1320           DisposeGWorld(graphic_world);
1321           DisposeHandle((Handle) picture_handle);
1322           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1323         }
1324       for (x=0; x < image->colors; x++)
1325       {
1326         image->colormap[x].red=
1327           (*(picture_info.theColorTable))->ctTable[x].rgb.red;
1328         image->colormap[x].green=
1329           (*(picture_info.theColorTable))->ctTable[x].rgb.green;
1330         image->colormap[x].blue=
1331           (*(picture_info.theColorTable))->ctTable[x].rgb.blue;
1332       }
1333     }
1334   SetRect(&rectangle,0,0,image->columns,image->rows);
1335   (void) UpdateGWorld(&graphic_world,depth,&rectangle,
1336     picture_info.theColorTable,nil,0);
1337   LockPixels(GetGWorldPixMap(graphic_world));  /*->portPixMap); */
1338   EraseRect(&rectangle);
1339   DrawPicture(picture_handle,&rectangle);
1340   if ((depth <= 8) && (colormap_id == -1))
1341     {
1342       DisposeHandle((Handle) picture_info.theColorTable);
1343       picture_info.theColorTable=nil;
1344     }
1345   DisposeHandle((Handle) picture_handle);
1346   /*
1347     Convert PICT pixels to pixel packets.
1348   */
1349   for (y=0; y < image->rows; y++)
1350   {
1351     register ssize_t
1352       x;
1353
1354     register Quantum
1355       *restrict q;
1356
1357     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1358     if (q == (Quantum *) NULL)
1359       break;
1360     for (x=0; x < image->columns; x++)
1361     {
1362       GetCPixel(x,y,&Pixel);
1363       SetPixelRed(image,ScaleCharToQuantum(Pixel.red & 0xff),q);
1364       SetPixelGreen(image,ScaleCharToQuantum(Pixel.green & 0xff),q);
1365       SetPixelBlue(image,ScaleCharToQuantum(Pixel.blue & 0xff),q);
1366       if (image->storage_class == PseudoClass)
1367         SetPixelIndex(image,Color2Index(&Pixel),q);
1368       q+=GetPixelChannels(image);
1369     }
1370     if (SyncAuthenticPixels(image,exception) == MagickFalse)
1371       break;
1372     proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
1373     if (proceed == MagickFalse)
1374       break;
1375   }
1376   UnlockPixels(GetGWorldPixMap(graphic_world));
1377   SetGWorld(port,device);
1378   if (picture_info.theColorTable != nil)
1379     DisposeHandle((Handle) picture_info.theColorTable);
1380   DisposeGWorld(graphic_world);
1381   (void) CloseBlob(image);
1382   return(image);
1383 }
1384 \f
1385 /*
1386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1387 %                                                                             %
1388 %                                                                             %
1389 %                                                                             %
1390 %   S e a r c h F o r F i l e                                                 %
1391 %                                                                             %
1392 %                                                                             %
1393 %                                                                             %
1394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1395 %
1396 %  SearchForFile() searches for a file.
1397 %
1398 %
1399 */
1400 static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file,
1401   short count)
1402 {
1403   char
1404     *buffer;
1405
1406   CInfoPBRec
1407     search1_info,
1408     search2_info;
1409
1410   FSSpec
1411     application;
1412
1413   HParamBlockRec
1414     parameter_info;
1415
1416   OSErr
1417     error;
1418
1419   ProcessInfoRec
1420     application_info;
1421
1422   ProcessSerialNumber
1423     serial_number;
1424
1425   ssize_t
1426     buffer_size = 16384;
1427
1428   serial_number.lowLongOfPSN=kCurrentProcess;
1429   serial_number.highLongOfPSN=0;
1430   application_info.processInfoLength=sizeof(ProcessInfoRec);
1431   application_info.processName=NULL;
1432   application_info.processAppSpec=(&application);
1433   GetProcessInformation(&serial_number,&application_info);
1434   buffer=NewPtr(buffer_size);
1435   if (buffer == (char *) NULL)
1436     return(false);
1437   parameter_info.csParam.ioCompletion=NULL;
1438   parameter_info.csParam.ioNamePtr=NULL;
1439   parameter_info.csParam.ioVRefNum=application.vRefNum;
1440   parameter_info.csParam.ioMatchPtr=file;
1441   parameter_info.csParam.ioReqMatchCount=count;
1442   parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo;
1443   parameter_info.csParam.ioSearchInfo1=&search1_info;
1444   parameter_info.csParam.ioSearchInfo2=&search2_info;
1445   parameter_info.csParam.ioSearchTime=0;
1446   parameter_info.csParam.ioCatPosition.initialize=0;
1447   parameter_info.csParam.ioOptBuffer=buffer;
1448   parameter_info.csParam.ioOptBufSize=buffer_size;
1449   search1_info.hFileInfo.ioNamePtr=NULL;
1450   search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type;
1451   search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1452   search1_info.hFileInfo.ioFlAttrib=0;
1453   search1_info.hFileInfo.ioFlParID=0;
1454   search2_info=search1_info;
1455   search2_info.hFileInfo.ioFlAttrib=0x10;
1456   search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1457   search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1);
1458   search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0;
1459   search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0;
1460   search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0;
1461   search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0;
1462   search2_info.hFileInfo.ioFlParID=0;
1463   error=PBCatSearchSync((CSParamPtr) &parameter_info);
1464   DisposePtr(buffer);
1465   if (parameter_info.csParam.ioReqMatchCount ==
1466       parameter_info.csParam.ioActMatchCount)
1467     error=eofErr;
1468   if (parameter_info.csParam.ioActMatchCount == 0)
1469     error=0;
1470   return(error == eofErr);
1471 }
1472 \f
1473 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1474 /*
1475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1476 %                                                                             %
1477 %                                                                             %
1478 %                                                                             %
1479 %   s e e k d i r                                                             %
1480 %                                                                             %
1481 %                                                                             %
1482 %                                                                             %
1483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484 %
1485 %  seekdir() sets the position of the next readdir() operation on the directory
1486 %  stream.
1487 %
1488 %  The format of the seekdir method is:
1489 %
1490 %      void seekdir(DIR *entry,ssize_t position)
1491 %
1492 %  A description of each parameter follows:
1493 %
1494 %    o entry: Specifies a pointer to a DIR structure.
1495 %
1496 %    o position: specifies the position associated with the directory
1497 %      stream.
1498 %
1499 %
1500 %
1501 */
1502 MagickExport void seekdir(DIR *entry,ssize_t position)
1503 {
1504   assert(entry != (DIR *) NULL);
1505   entry->d_index=position;
1506 }
1507 #endif
1508 \f
1509 /*
1510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1511 %                                                                             %
1512 %                                                                             %
1513 %                                                                             %
1514 %   S e t A p p l i c a t i o n T y p e                                       %
1515 %                                                                             %
1516 %                                                                             %
1517 %                                                                             %
1518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1519 %
1520 %  SetApplicationType() sets the file type of an image.
1521 %
1522 %  The format of the SetApplicationType method is:
1523 %
1524 %      void SetApplicationType(const char *filename,const char *magick,
1525 %        OSType application)
1526 %
1527 %  A description of each parameter follows:
1528 %
1529 %    o filename: Specifies the name of the file.
1530 %
1531 %    o filename: Specifies the file type.
1532 %
1533 %    o application: Specifies the type of the application.
1534 %
1535 */
1536
1537 static inline size_t MagickMin(const size_t x,const size_t y)
1538 {
1539   if (x < y)
1540     return(x);
1541   return(y);
1542 }
1543
1544 MagickExport void SetApplicationType(const char *filename,const char *magick,
1545   OSType application)
1546 {
1547   FSSpec
1548     file_specification;
1549
1550   OSType
1551     filetype;
1552
1553   Str255
1554     name;
1555
1556   assert(filename != (char *) NULL);
1557   if (image->debug != MagickFalse)
1558     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1559   assert(magick != (const char *) NULL);
1560   filetype='    ';
1561   (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick),
1562     4));
1563   if (LocaleCompare(magick,"JPG") == 0)
1564     (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent);
1565   c2pstrcpy(name,filename);
1566   FSMakeFSSpec(0,0,name,&file_specification);
1567   FSpCreate(&file_specification,application,filetype,smSystemScript);
1568 }
1569 \f
1570 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1571 /*
1572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1573 %                                                                             %
1574 %                                                                             %
1575 %                                                                             %
1576 %   t e l l d i r                                                             %
1577 %                                                                             %
1578 %                                                                             %
1579 %                                                                             %
1580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1581 %
1582 %   Method telldir returns the current location associated  with  the
1583 %   named directory stream.
1584 %
1585 %  The format of the telldir method is:
1586 %
1587 %      telldir(DIR *entry)
1588 %
1589 %  A description of each parameter follows:
1590 %
1591 %    o entry: Specifies a pointer to a DIR structure.
1592 %
1593 %
1594 */
1595 MagickExport ssize_t telldir(DIR *entry)
1596 {
1597   return(entry->d_index);
1598 }
1599 #endif
1600
1601 #endif