MagickCore  6.9.12-67
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
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 % Cristy %
17 % September 1996 %
18 % %
19 % %
20 % Copyright 1999-2021 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 % https://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/pixel-accessor.h"
76 #include "magick/quantum.h"
77 #include "magick/string_.h"
78 #include "magick/utility.h"
79 #include "magick/mac.h"
80 
81 /*
82  Global declaractions.
83 */
84 ImageDescriptionHandle
85  image_description = nil;
86 
87 /*
88  Forward declaractions.
89 */
90 static Boolean
91  SearchForFile(OSType,OSType,FSSpec *,short);
92 
93 static pascal void
94  ArcMethod(GrafVerb,Rect *,short,short),
95  BitsMethod(BitMap *,Rect *,Rect *,short,RgnHandle),
96  FilenameToFSSpec(const char *filename,FSSpec *fsspec),
97  LineMethod(Point),
98  OvalMethod(GrafVerb,Rect *),
99  PolyMethod(GrafVerb,PolyHandle),
100  RRectMethod(GrafVerb,Rect *,short,short),
101  RectMethod(GrafVerb,Rect *),
102  RegionMethod(GrafVerb,RgnHandle),
103  StandardPixmap(PixMapPtr,Rect *,MatrixRecordPtr,short,RgnHandle,PixMapPtr,
104  Rect *,short),
105  TextMethod(short,Ptr,Point,Point);
106 
107 /*
108  Static declarations
109  */
110 #if defined(DISABLE_SIOUX)
111 static MACEventHookPtr
112  event_hook = nil;
113 
114 static MACErrorHookPtr
115  exception.hook = nil;
116 #endif
117 
118 /*
119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 % %
121 % %
122 % %
123 % B o t t l e n e c k T e s t %
124 % %
125 % %
126 % %
127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 %
129 % BottleneckTest() intercepts any compressed images.
130 %
131 % The format of the BottleneckTest method is:
132 %
133 % int BottleneckTest(const char *magick)
134 %
135 % A description of each parameter follows:
136 %
137 % o picture: Specifies a pointer to a PicHandle structure.
138 %
139 % o codec: the code type is returned in this CodecType pointer structure.
140 %
141 % o depth: the image depth is returned as an integer pointer.
142 %
143 % o colormap_id: the colormap ID is returned in this short pointer.
144 %
145 %
146 */
147 
148 static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle,
149  short arcAngle)
150 {
151 #pragma unused (verb,r,startAngle,arcAngle)
152 }
153 
154 static pascal void BitsMethod(BitMap *bitPtr,Rect *source_rectangle,
155  Rect *dstRect,short mode,RgnHandle maskRgn)
156 {
157 #pragma unused (bitPtr,source_rectangle,dstRect,mode,maskRgn)
158 }
159 
160 static pascal void LineMethod(Point newPt)
161 {
162 #pragma unused (newPt)
163 }
164 
165 static pascal void OvalMethod(GrafVerb verb,Rect *r)
166 {
167 #pragma unused (verb,r)
168 }
169 
170 static pascal void PolyMethod(GrafVerb verb,PolyHandle poly)
171 {
172 #pragma unused (verb,poly)
173 }
174 
175 static pascal void RectMethod(GrafVerb verb,Rect *r)
176 {
177 #pragma unused (verb,r)
178 }
179 
180 static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn)
181 {
182 #pragma unused (verb,rgn)
183 }
184 
185 static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth,
186  short ovalHeight)
187 {
188 #pragma unused (verb,r,ovalWidth,ovalHeight)
189 }
190 
191 static pascal void StandardPixmap(PixMapPtr source,Rect *source_rectangle,
192  MatrixRecordPtr matrix,short mode,RgnHandle mask,PixMapPtr matte,
193  Rect *matte_rectangle,short flags)
194 {
195 #pragma unused (source_rectangle,matrix,mode,mask,matte,matte_rectangle,flags)
196 
197  Ptr
198  data;
199 
200  ssize_t
201  size;
202 
203  GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil);
204 }
205 
206 static pascal void TextMethod(short byteCount,Ptr textBuf,Point numer,
207  Point denom)
208 {
209 #pragma unused (byteCount,textBuf,numer,denom)
210 }
211 
212 #if !defined(DISABLE_QUICKTIME)
213 static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth,
214  short *colormap_id)
215 {
216  CQDProcs
217  bottlenecks;
218 
219  int
220  status;
221 
222  Rect
223  rectangle;
224 
225  ssize_t
226  version;
227 
228  status=Gestalt(gestaltQuickTime,&version);
229  if (status != noErr)
230  {
231  ParamText("\pQuickTime not installed. Please install, then try again.",
232  "\p","\p","\p");
233  Alert(128,nil);
234  return(-1);
235  }
236  /*
237  Define our own bottlenecks to do nothing.
238  */
239  SetStdCProcs(&bottlenecks);
240  bottlenecks.textProc=NewQDTextUPP(&TextMethod);
241  bottlenecks.lineProc=NewQDLineUPP(&LineMethod);
242  bottlenecks.rectProc=NewQDRectUPP(&RectMethod);
243  bottlenecks.rRectProc=NewQDRRectUPP(&RRectMethod);
244  bottlenecks.ovalProc=NewQDOvalUPP(&OvalMethod);
245  bottlenecks.arcProc=NewQDArcUPP(&ArcMethod);
246  bottlenecks.polyProc=NewQDPolyUPP(&PolyMethod);
247  bottlenecks.rgnProc=NewQDRgnUPP(&RegionMethod);
248  bottlenecks.bitsProc=NewQDBitsUPP(&BitsMethod);
249  bottlenecks.newProc1=(UniversalProcPtr) NewStdPixUPP(&StandardPixmap);
250  /*
251  Install our custom bottlenecks to intercept any compressed images.
252  */
253  (*(qd.thePort)).grafProcs=(QDProcs *) &bottlenecks;
254  DrawPicture(picture,&((**picture).picFrame));
255  PaintRect(&rectangle);
256  (*(qd.thePort)).grafProcs=0L;
257  /*
258  Initialize our return values.
259  */
260  *codec='unkn';
261  *depth=0;
262  *colormap_id=(-1);
263  if (image_description != nil)
264  {
265  *codec=(**image_description).cType;
266  *depth=(**image_description).depth;
267  *colormap_id=(**image_description).clutID;
268  }
269  DisposeQDTextUPP(bottlenecks.textProc);
270  DisposeQDLineUPP(bottlenecks.lineProc);
271  DisposeQDRectUPP(bottlenecks.rectProc);
272  DisposeQDRRectUPP(bottlenecks.rRectProc);
273  DisposeQDOvalUPP(bottlenecks.ovalProc);
274  DisposeQDArcUPP(bottlenecks.arcProc);
275  DisposeQDPolyUPP(bottlenecks.polyProc);
276  DisposeQDRgnUPP(bottlenecks.rgnProc);
277  DisposeQDBitsUPP(bottlenecks.bitsProc);
278  DisposeStdPixUPP(bottlenecks.newProc1);
279  return(0);
280 }
281 #endif
282 
283 #if !defined(MAGICKCORE_POSIX_SUPPORT_VERSION)
284 /*
285 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % %
287 % %
288 % %
289 % c l o s e d i r %
290 % %
291 % %
292 % %
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 %
295 % closedir() closes the named directory stream and frees the DIR structure.
296 %
297 % The format of the closedir method is:
298 %
299 % closedir(entry)
300 %
301 % A description of each parameter follows:
302 %
303 % o entry: Specifies a pointer to a DIR structure.
304 %
305 %
306 */
307 MagickExport void closedir(DIR *entry)
308 {
309  if (IsEventLogging() != MagickFalse)
310  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
311  assert(entry != (DIR *) NULL);
312  RelinquishMagickMemory(entry);
313 }
314 #endif
315 
316 /*
317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 % %
319 % %
320 % %
321 % E x i t %
322 % %
323 % %
324 % %
325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326 %
327 % Exit() exits the process.
328 %
329 % The format of the exit method is:
330 %
331 % Exit(status)
332 %
333 % A description of each parameter follows:
334 %
335 % o status: an integer value representing the status of the terminating
336 % process.
337 %
338 %
339 */
340 MagickExport int Exit(int status)
341 {
342 #if !defined(DISABLE_SIOUX)
343  (void) FormatLocaleFile(stdout,"Select File->Quit to exit.\n");
344 #endif
345  exit(status);
346  return(0);
347 }
348 
349 /*
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 % %
352 % %
353 % %
354 % F i l e n a m e T o F S S p e c %
355 % %
356 % %
357 % %
358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359 %
360 % FilenameToFSSpec() sets the file type of an image.
361 %
362 % The format of the FilenameToFSSpec method is:
363 %
364 % FilenameToFSSpec(filename,fsspec)
365 %
366 % A description of each parameter follows:
367 %
368 % o filename: Specifies the name of the file.
369 %
370 % o fsspec: A pointer to type FSSpec.
371 %
372 %
373 */
374 MagickExport void pascal FilenameToFSSpec(const char *filename,FSSpec *fsspec)
375 {
376  Str255
377  name;
378 
379  assert(filename != (char *) NULL);
380  c2pstrcpy(name,filename);
381  FSMakeFSSpec(0,0,name,fsspec);
382 }
383 
384 /*
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386 % %
387 % %
388 % %
389 % I s M a g i c k C o n f l i c t %
390 % %
391 % %
392 % %
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 %
395 % MACIsMagickConflict() returns true if the image format conflicts with a
396 % logical drive (.e.g. X:).
397 %
398 % Contributed by Mark Gavin of Digital Applications, Inc.
399 %
400 % The format of the MACIsMagickConflict method is:
401 %
402 % status=MACIsMagickConflict(magick)
403 %
404 % A description of each parameter follows:
405 %
406 % o magick: Specifies the image format.
407 %
408 %
409 */
410 
411 static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume,
412  size_t *free_bytes,size_t *total_bytes)
413 {
414  HParamBlockRec
415  pb;
416 
417  OSErr
418  result;
419 
420  size_t
421  blocksize;
422 
423  unsigned short
424  allocation_blocks,
425  free_blocks;
426 
427  /*
428  Use the File Manager to get the real vRefNum.
429  */
430  pb.volumeParam.ioVRefNum=0;
431  pb.volumeParam.ioNamePtr=volume_name;
432  pb.volumeParam.ioVolIndex=volume_index;
433  result=PBHGetVInfoSync(&pb);
434  if (result != noErr)
435  return(result);
436  *volume=pb.volumeParam.ioVRefNum;
437  blocksize=(size_t) pb.volumeParam.ioVAlBlkSiz;
438  allocation_blocks=(unsigned short) pb.volumeParam.ioVNmAlBlks;
439  free_blocks=(unsigned short) pb.volumeParam.ioVFrBlk;
440  *free_bytes=free_blocks*blocksize;
441  *total_bytes=allocation_blocks*blocksize;
442  return(result);
443 }
444 
445 MagickExport MagickBooleanType MACIsMagickConflict(const char *magick)
446 {
447  size_t
448  free_bytes,
449  number_bytes;
450 
451  OSErr
452  status;
453 
454  short
455  volume;
456 
457  Str255
458  volume_name;
459 
460  assert(magick != (char *) NULL);
461  if (IsEventLogging() != MagickFalse)
462  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick);
463  (void) CopyMagickString((char *) volume_name,magick,MaxTextExtent);
464  c2pstr((char *) volume_name);
465  if (volume_name[volume_name[0]] != ':')
466  volume_name[++volume_name[0]]=':';
467  status=HGetVInfo(-1,volume_name,&volume,&free_bytes,&number_bytes);
468  return(status != 0 ? MagickFalse : MagickTrue);
469 }
470 
471 /*
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % %
474 % %
475 % %
476 + M A C E r r o r H a n d l e r %
477 % %
478 % %
479 % %
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %
482 % MACErrorHandler() displays an error reason and then terminates the program.
483 %
484 % The format of the MACErrorHandler method is:
485 %
486 % void MACErrorHandler(const ExceptionType error,const char *reason,
487 % const char *description)
488 %
489 % A description of each parameter follows:
490 %
491 % o exception: Specifies the numeric error category.
492 %
493 % o reason: Specifies the reason to display before terminating the
494 % program.
495 %
496 % o description: Specifies any description to the reason.
497 %
498 %
499 */
500 MagickExport void MACErrorHandler(const ExceptionType error,const char *reason,
501  const char *description)
502 {
503  char
504  buffer[3*MaxTextExtent];
505 
506  if (reason == (char *) NULL)
507  return;
508  if (description == (char *) NULL)
509  (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
510  reason);
511  else
512  (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
513  GetClientName(),reason,description);
514 #if defined(DISABLE_SIOUX)
515  if(exception.hook != (MACErrorHookPtr) NULL)
516  exception.hook(error,buffer);
517  else
518  {
519  MagickCoreTerminus();
520  exit(error);
521  }
522 #else
523  puts(buffer);
524  MagickCoreTerminus();
525  exit(error);
526 #endif
527 }
528 
529 #if defined(DISABLE_SIOUX)
530 /*
531 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532 % %
533 % %
534 % %
535 + M A C F a t a l E r r o r H a n d l e r %
536 % %
537 % %
538 % %
539 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540 %
541 % MACFatalErrorHandler() displays an error reason and then terminates the
542 % program.
543 %
544 % The format of the MACFatalErrorHandler method is:
545 %
546 % void MACFatalErrorHandler(const ExceptionType severity,
547 % const char *reason,const char *description)
548 %
549 % A description of each parameter follows:
550 %
551 % o severity: Specifies the numeric error category.
552 %
553 % o reason: Specifies the reason to display before terminating the
554 % program.
555 %
556 % o description: Specifies any description to the reason.
557 %
558 */
559 static 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) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
569  reason);
570  else
571  (void) FormatLocaleString(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 */
598 static OSErr MacGSExecuteCommand(const char *command,ssize_t 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 */
657 static OSErr MacGSLaunchApplicationCore(ssize_t 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 */
695 static 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 */
715 static 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 */
735 static 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 */
781 static 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 */
851 MagickExport 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 */
883 MagickExport 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(MagickFalse,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 MagickExport int MACSystemCommand(const char * command)
915 {
916  /*
917  We only know how to launch Ghostscript.
918  */
919  if (MacGSLaunchApplicationToFront())
920  return(-1);
921  return(MacGSExecuteCommand(command,strlen(command)));
922 }
923 
924 /*
925 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
926 % %
927 % %
928 % %
929 % M A C W a r n i n g H a n d l e r %
930 % %
931 % %
932 % %
933 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
934 %
935 % MACWarningHandler() displays a warning reason.
936 %
937 % The format of the MACWarningHandler method is:
938 %
939 + void MACWarningHandler(const ExceptionType warning,const char *reason,
940 % const char *description)
941 %
942 % A description of each parameter follows:
943 %
944 % o warning: Specifies the numeric warning category.
945 %
946 % o reason: Specifies the reason to display before terminating the
947 % program.
948 %
949 % o description: Specifies any description to the reason.
950 %
951 %
952 */
953 MagickExport void MACWarningHandler(const ExceptionType warning,
954  const char *reason,const char *description)
955 {
956  char
957  buffer[1664];
958 
959  if (reason == (char *) NULL)
960  return;
961  if (description == (char *) NULL)
962  (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
963  reason);
964  else
965  (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
966  GetClientName(),reason,description);
967 #if defined(DISABLE_SIOUX)
968  if(exception.hook != (MACErrorHookPtr) NULL)
969  exception.hook(warning, buffer);
970 #else
971  (void)warning;
972  puts(buffer);
973 #endif
974 }
975 
976 #if !defined(MAGICKCORE_POSIX_SUPPORT_VERSION)
977 /*
978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979 % %
980 % %
981 % %
982 % o p e n d i r %
983 % %
984 % %
985 % %
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 %
988 % opendir() opens the directory named by filename and associates a directory
989 % stream with it.
990 %
991 % The format of the opendir method is:
992 %
993 % MagickExport DIR *opendir(char *path)
994 %
995 % A description of each parameter follows:
996 %
997 % o entry: Specifies a pointer to a DIR structure.
998 %
999 %
1000 */
1001 MagickExport DIR *opendir(const char *path)
1002 {
1003  Str255 pathname;
1004 
1005  CInfoPBRec
1006  search_info;
1007 
1008  DIR
1009  *entry;
1010 
1011  int
1012  error;
1013 
1014  search_info.hFileInfo.ioNamePtr=0;
1015  if ((path != (char *) NULL) || (*path != '\0'))
1016  if ((path[0] != '.') || (path[1] != '\0'))
1017  {
1018  c2pstrcpy(pathname,path);
1019  search_info.hFileInfo.ioNamePtr=pathname;
1020  }
1021  search_info.hFileInfo.ioCompletion=0;
1022  search_info.hFileInfo.ioVRefNum=0;
1023  search_info.hFileInfo.ioFDirIndex=0;
1024  search_info.hFileInfo.ioDirID=0;
1025  error=PBGetCatInfoSync(&search_info);
1026  if (error != noErr)
1027  {
1028  errno=error;
1029  return((DIR *) NULL);
1030  }
1031  entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
1032  if (entry == (DIR *) NULL)
1033  return((DIR *) NULL);
1034  entry->d_VRefNum=search_info.hFileInfo.ioVRefNum;
1035  entry->d_DirID=search_info.hFileInfo.ioDirID;
1036  entry->d_index=1;
1037  return(entry);
1038 }
1039 #endif
1040 
1041 /*
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1043 % %
1044 % %
1045 % %
1046 % P r o c e s s P e n d i n g E v e n t s %
1047 % %
1048 % %
1049 % %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 %
1052 % ProcessPendingEvents() processes any pending events. This prevents
1053 % ImageMagick from monopolizing the processor.
1054 %
1055 % The format of the ProcessPendingEvents method is:
1056 %
1057 % ProcessPendingEvents(text)
1058 %
1059 % A description of each parameter follows:
1060 %
1061 % o text: A character string representing the current process.
1062 %
1063 %
1064 */
1065 MagickExport void ProcessPendingEvents(const char *text)
1066 {
1067 #if defined(DISABLE_SIOUX)
1068  if (event_hook != (MACEventHookPtr) NULL)
1069  event_hook(text);
1070 #else
1071  static const char
1072  *mark = (char *) NULL;
1073 
1074  EventRecord
1075  event;
1076 
1077  while (WaitNextEvent(everyEvent,&event,0L,nil))
1078  SIOUXHandleOneEvent(&event);
1079  if (isatty(STDIN_FILENO) && (text != mark))
1080  {
1081  (void) puts(text);
1082  mark=text;
1083  }
1084 #endif
1085 }
1086 
1087 #if !defined(MAGICKCORE_POSIX_SUPPORT_VERSION)
1088 /*
1089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1090 % %
1091 % %
1092 % %
1093 % r e a d d i r %
1094 % %
1095 % %
1096 % %
1097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1098 %
1099 % readdir() returns a pointer to a structure representing the directory entry
1100 % at the current position in the directory stream to which entry refers.
1101 %
1102 % The format of the readdir
1103 %
1104 % struct dirent *readdir(DIR *entry)
1105 %
1106 % A description of each parameter follows:
1107 %
1108 % o entry: Specifies a pointer to a DIR structure.
1109 %
1110 %
1111 */
1112 MagickExport struct dirent *readdir(DIR *entry)
1113 {
1114  CInfoPBRec
1115  search_info;
1116 
1117  int
1118  error;
1119 
1120  static struct dirent
1121  dir_entry;
1122 
1123  static unsigned char
1124  pathname[MaxTextExtent];
1125 
1126  if (entry == (DIR *) NULL)
1127  return((struct dirent *) NULL);
1128  search_info.hFileInfo.ioCompletion=0;
1129  search_info.hFileInfo.ioNamePtr=pathname;
1130  search_info.hFileInfo.ioVRefNum=0;
1131  search_info.hFileInfo.ioFDirIndex=entry->d_index;
1132  search_info.hFileInfo.ioDirID=entry->d_DirID;
1133  error=PBGetCatInfoSync(&search_info);
1134  if (error != noErr)
1135  {
1136  errno=error;
1137  return((struct dirent *) NULL);
1138  }
1139  entry->d_index++;
1140  p2cstrcpy(dir_entry.d_name,search_info.hFileInfo.ioNamePtr);
1141  dir_entry.d_namlen=strlen(dir_entry.d_name);
1142  return(&dir_entry);
1143 }
1144 #endif
1145 
1146 /*
1147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1148 % %
1149 % %
1150 % %
1151 % R e a d P I C T I m a g e %
1152 % %
1153 % %
1154 % %
1155 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1156 %
1157 % ReadPICTImage() reads an Apple Macintosh QuickDraw/PICT image file using
1158 % MacOS QuickDraw methods and returns it. It allocates the memory necessary
1159 % for the new Image structure and returns a pointer to the new image.
1160 %
1161 % This method was written and contributed by spd@daphne.cps.unizar.es
1162 % (feel free to copy and use it as you want. No warranty).
1163 %
1164 % The format of the ReadPICTImage method is:
1165 %
1166 % Image *ReadPICTImage(const ImageInfo *image_info,
1167 % ExceptionInfo *exception)
1168 %
1169 % A description of each parameter follows:
1170 %
1171 % o image: Method ReadPICTImage returns a pointer to the image after
1172 % reading. A null image is returned if there is a memory shortage or
1173 % if the image cannot be read.
1174 %
1175 % o image_info: the image info..
1176 %
1177 % o exception: return any errors or warnings in this structure.
1178 %
1179 */
1180 
1181 static inline size_t MagickMax(const size_t x,const size_t y)
1182 {
1183  if (x > y)
1184  return(x);
1185  return(y);
1186 }
1187 
1188 MagickExport Image *ReadPICTImage(const ImageInfo *image_info,
1189  ExceptionInfo *exception)
1190 {
1191 #define PICTHeaderSize 512
1192 
1193  CodecType
1194  codec;
1195 
1196  GDHandle
1197  device;
1198 
1199  GWorldPtr
1200  graphic_world,
1201  port;
1202 
1203  Image
1204  *image;
1205 
1206  int
1207  depth,
1208  status;
1209 
1210  MagickBooleanType
1211  proceed,
1212  status;
1213 
1214  PicHandle
1215  picture_handle;
1216 
1217  PictInfo
1218  picture_info;
1219 
1220  QDErr
1221  theErr = noErr;
1222 
1223  Rect
1224  rectangle;
1225 
1226  RGBColor
1227  Pixel;
1228 
1229  short
1230  colormap_id;
1231 
1232  ssize_t
1233  y;
1234 
1235  /*
1236  Open image file.
1237  */
1238  image=AcquireImage(image_info);
1239  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
1240  if (status == MagickFalse)
1241  return(NULL);
1242  picture_handle=(PicHandle) NewHandle(MagickMax(GetBlobSize(image)-
1243  PICTHeaderSize,PICTHeaderSize));
1244  if (picture_handle == nil)
1245  ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1246  HLock((Handle) picture_handle);
1247  (void) ReadBlob(image,PICTHeaderSize,*(unsigned char **) picture_handle);
1248  status=ReadBlob(image,GetBlobSize(image)-PICTHeaderSize,*(unsigned char **)
1249  picture_handle);
1250  if (status == MagickFalse)
1251  {
1252  DisposeHandle((Handle) picture_handle);
1253  ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1254  }
1255  GetGWorld(&port,&device);
1256  theErr=NewGWorld(&graphic_world,0,&(**picture_handle).picFrame,nil,nil,
1257  useTempMem | keepLocal);
1258  if ((theErr != noErr) && (graphic_world == nil))
1259  {
1260  DisposeHandle((Handle) picture_handle);
1261  ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1262  }
1263  HUnlock((Handle) picture_handle);
1264  SetGWorld(graphic_world,nil);
1265  theErr=GetPictInfo(picture_handle,&picture_info,0,1,systemMethod,0);
1266  if (theErr != noErr)
1267  {
1268  DisposeGWorld(graphic_world);
1269  DisposeHandle((Handle) picture_handle);
1270  ThrowReaderException(CorruptImageError,"UnableToReadImageData");
1271  }
1272 #if defined(DISABLE_QUICKTIME)
1273  codec='unkn';
1274  colormap_id=(-1);
1275  depth=picture_info.depth;
1276 #else
1277  BottleneckTest(picture_handle,&codec,&depth,&colormap_id);
1278 #endif
1279  switch (codec)
1280  {
1281  case 'rpza':
1282  case 'jpeg':
1283  case 'rle ':
1284  case 'raw ':
1285  case 'smc ':
1286  {
1287  if (depth > 200)
1288  {
1289  depth-=32;
1290  picture_info.theColorTable=GetCTable(colormap_id);
1291  }
1292  break;
1293  }
1294  default:
1295  {
1296  depth=picture_info.depth;
1297  if (depth <= 8)
1298  (void) GetPictInfo(picture_handle,&picture_info,returnColorTable,
1299  (short) (1 << picture_info.depth),systemMethod,0);
1300  break;
1301  }
1302  }
1303  image->x_resolution=(picture_info.hRes) >> 16;
1304  image->y_resolution=(picture_info.vRes) >> 16;
1305  image->units=PixelsPerInchResolution;
1306  image->columns=picture_info.sourceRect.right-picture_info.sourceRect.left;
1307  image->rows=picture_info.sourceRect.bottom-picture_info.sourceRect.top;
1308  if ((depth <= 8) && ((*(picture_info.theColorTable))->ctSize != 0))
1309  {
1310  size_t
1311  number_colors;
1312 
1313  /*
1314  Colormapped PICT image.
1315  */
1316  number_colors=(*(picture_info.theColorTable))->ctSize;
1317  if (!AcquireImageColormap(image,number_colors))
1318  {
1319  if (picture_info.theColorTable != nil)
1320  DisposeHandle((Handle) picture_info.theColorTable);
1321  DisposeGWorld(graphic_world);
1322  DisposeHandle((Handle) picture_handle);
1323  ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1324  }
1325  for (x=0; x < image->colors; x++)
1326  {
1327  image->colormap[x].red=
1328  (*(picture_info.theColorTable))->ctTable[x].rgb.red;
1329  image->colormap[x].green=
1330  (*(picture_info.theColorTable))->ctTable[x].rgb.green;
1331  image->colormap[x].blue=
1332  (*(picture_info.theColorTable))->ctTable[x].rgb.blue;
1333  }
1334  }
1335  SetRect(&rectangle,0,0,image->columns,image->rows);
1336  (void) UpdateGWorld(&graphic_world,depth,&rectangle,
1337  picture_info.theColorTable,nil,0);
1338  LockPixels(GetGWorldPixMap(graphic_world)); /*->portPixMap); */
1339  EraseRect(&rectangle);
1340  DrawPicture(picture_handle,&rectangle);
1341  if ((depth <= 8) && (colormap_id == -1))
1342  {
1343  DisposeHandle((Handle) picture_info.theColorTable);
1344  picture_info.theColorTable=nil;
1345  }
1346  DisposeHandle((Handle) picture_handle);
1347  /*
1348  Convert PICT pixels to pixel packets.
1349  */
1350  for (y=0; y < image->rows; y++)
1351  {
1352  IndexPacket
1353  *restrict indexes;
1354 
1355  ssize_t
1356  x;
1357 
1358  PixelPacket
1359  *restrict q;
1360 
1361  q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1362  if (q == (PixelPacket *) NULL)
1363  break;
1364  indexes=GetAuthenticIndexQueue(image);
1365  for (x=0; x < image->columns; x++)
1366  {
1367  GetCPixel(x,y,&Pixel);
1368  SetPixelRed(q,ScaleCharToQuantum(Pixel.red & 0xff));
1369  SetPixelGreen(q,ScaleCharToQuantum(Pixel.green & 0xff));
1370  SetPixelBlue(q,ScaleCharToQuantum(Pixel.blue & 0xff));
1371  if (image->storage_class == PseudoClass)
1372  SetPixelIndex(indexes+x,Color2Index(&Pixel));
1373  q++;
1374  }
1375  if (SyncAuthenticPixels(image,exception) == MagickFalse)
1376  break;
1377  proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
1378  if (proceed == MagickFalse)
1379  break;
1380  }
1381  UnlockPixels(GetGWorldPixMap(graphic_world));
1382  SetGWorld(port,device);
1383  if (picture_info.theColorTable != nil)
1384  DisposeHandle((Handle) picture_info.theColorTable);
1385  DisposeGWorld(graphic_world);
1386  (void) CloseBlob(image);
1387  return(image);
1388 }
1389 
1390 /*
1391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392 % %
1393 % %
1394 % %
1395 % S e a r c h F o r F i l e %
1396 % %
1397 % %
1398 % %
1399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1400 %
1401 % SearchForFile() searches for a file.
1402 %
1403 %
1404 */
1405 static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file,
1406  short count)
1407 {
1408  char
1409  *buffer;
1410 
1411  CInfoPBRec
1412  search1_info,
1413  search2_info;
1414 
1415  FSSpec
1416  application;
1417 
1418  HParamBlockRec
1419  parameter_info;
1420 
1421  OSErr
1422  error;
1423 
1424  ProcessInfoRec
1425  application_info;
1426 
1427  ProcessSerialNumber
1428  serial_number;
1429 
1430  ssize_t
1431  buffer_size = MagickMinBufferExtent;
1432 
1433  serial_number.lowLongOfPSN=kCurrentProcess;
1434  serial_number.highLongOfPSN=0;
1435  application_info.processInfoLength=sizeof(ProcessInfoRec);
1436  application_info.processName=NULL;
1437  application_info.processAppSpec=(&application);
1438  GetProcessInformation(&serial_number,&application_info);
1439  buffer=NewPtr(buffer_size);
1440  if (buffer == (char *) NULL)
1441  return(false);
1442  parameter_info.csParam.ioCompletion=NULL;
1443  parameter_info.csParam.ioNamePtr=NULL;
1444  parameter_info.csParam.ioVRefNum=application.vRefNum;
1445  parameter_info.csParam.ioMatchPtr=file;
1446  parameter_info.csParam.ioReqMatchCount=count;
1447  parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo;
1448  parameter_info.csParam.ioSearchInfo1=&search1_info;
1449  parameter_info.csParam.ioSearchInfo2=&search2_info;
1450  parameter_info.csParam.ioSearchTime=0;
1451  parameter_info.csParam.ioCatPosition.initialize=0;
1452  parameter_info.csParam.ioOptBuffer=buffer;
1453  parameter_info.csParam.ioOptBufSize=buffer_size;
1454  search1_info.hFileInfo.ioNamePtr=NULL;
1455  search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type;
1456  search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1457  search1_info.hFileInfo.ioFlAttrib=0;
1458  search1_info.hFileInfo.ioFlParID=0;
1459  search2_info=search1_info;
1460  search2_info.hFileInfo.ioFlAttrib=0x10;
1461  search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1462  search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1);
1463  search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0;
1464  search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0;
1465  search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0;
1466  search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0;
1467  search2_info.hFileInfo.ioFlParID=0;
1468  error=PBCatSearchSync((CSParamPtr) &parameter_info);
1469  DisposePtr(buffer);
1470  if (parameter_info.csParam.ioReqMatchCount ==
1471  parameter_info.csParam.ioActMatchCount)
1472  error=eofErr;
1473  if (parameter_info.csParam.ioActMatchCount == 0)
1474  error=0;
1475  return(error == eofErr);
1476 }
1477 
1478 #if !defined(MAGICKCORE_POSIX_SUPPORT_VERSION)
1479 /*
1480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1481 % %
1482 % %
1483 % %
1484 % s e e k d i r %
1485 % %
1486 % %
1487 % %
1488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1489 %
1490 % seekdir() sets the position of the next readdir() operation on the directory
1491 % stream.
1492 %
1493 % The format of the seekdir method is:
1494 %
1495 % void seekdir(DIR *entry,ssize_t position)
1496 %
1497 % A description of each parameter follows:
1498 %
1499 % o entry: Specifies a pointer to a DIR structure.
1500 %
1501 % o position: specifies the position associated with the directory
1502 % stream.
1503 %
1504 %
1505 %
1506 */
1507 MagickExport void seekdir(DIR *entry,ssize_t position)
1508 {
1509  assert(entry != (DIR *) NULL);
1510  entry->d_index=position;
1511 }
1512 #endif
1513 
1514 /*
1515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1516 % %
1517 % %
1518 % %
1519 % S e t A p p l i c a t i o n T y p e %
1520 % %
1521 % %
1522 % %
1523 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1524 %
1525 % SetApplicationType() sets the file type of an image.
1526 %
1527 % The format of the SetApplicationType method is:
1528 %
1529 % void SetApplicationType(const char *filename,const char *magick,
1530 % OSType application)
1531 %
1532 % A description of each parameter follows:
1533 %
1534 % o filename: Specifies the name of the file.
1535 %
1536 % o filename: Specifies the file type.
1537 %
1538 % o application: Specifies the type of the application.
1539 %
1540 */
1541 
1542 static inline size_t MagickMin(const size_t x,const size_t y)
1543 {
1544  if (x < y)
1545  return(x);
1546  return(y);
1547 }
1548 
1549 MagickExport void SetApplicationType(const char *filename,const char *magick,
1550  OSType application)
1551 {
1552  FSSpec
1553  file_specification;
1554 
1555  OSType
1556  filetype;
1557 
1558  Str255
1559  name;
1560 
1561  assert(filename != (char *) NULL);
1562  assert(magick != (const char *) NULL);
1563  if (IsEventLogging() != MagickFalse)
1564  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1565  filetype=' ';
1566  (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick),
1567  4));
1568  if (LocaleCompare(magick,"JPG") == 0)
1569  (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent);
1570  c2pstrcpy(name,filename);
1571  FSMakeFSSpec(0,0,name,&file_specification);
1572  FSpCreate(&file_specification,application,filetype,smSystemScript);
1573 }
1574 
1575 #if !defined(MAGICKCORE_POSIX_SUPPORT_VERSION)
1576 /*
1577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1578 % %
1579 % %
1580 % %
1581 % t e l l d i r %
1582 % %
1583 % %
1584 % %
1585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1586 %
1587 % Method telldir returns the current location associated with the
1588 % named directory stream.
1589 %
1590 % The format of the telldir method is:
1591 %
1592 % telldir(DIR *entry)
1593 %
1594 % A description of each parameter follows:
1595 %
1596 % o entry: Specifies a pointer to a DIR structure.
1597 %
1598 %
1599 */
1600 MagickExport ssize_t telldir(DIR *entry)
1601 {
1602  return(entry->d_index);
1603 }
1604 #endif
1605 
1606 #endif
Definition: mac.h:53
Definition: mac.h:41
Definition: image.h:152