blob: cbe40614304d003406ff7f258abb6f0a339fae43 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% M M AAA CCCC %
7% MM MM A A C %
8% M M M AAAAA C %
9% M M A A C %
10% M M A A CCCC %
11% %
12% %
13% Macintosh Utility Methods for MagickCore %
14% %
15% Software Design %
16% John Cristy %
17% September 1996 %
18% %
19% %
cristy16af1cb2009-12-11 21:38:29 +000020% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% The directory methods are strongly based on similar methods written
37% by Steve Summit, scs@eskimo.com. The Ghostscript launch code is strongly
38% based on Dave Schooley's Mac Gnuplot and contributed by
39% schindall@wave14i.nrl.navy.mil. Mac-centric improvements contributed by
40% leonardr@digapp.com.
41%
42%
43*/
44
45#if defined(macintosh)
46/*
47 Include declarations.
48*/
49#define _X_H
50#define _WIDGET_H
51#include <AppleEvents.h>
52#include <AERegistry.h>
53#include <AEObjects.h>
54#include <AEPackObject.h>
55#include <Processes.h>
56#include <QuickDraw.h>
57#include <QDOffscreen.h>
58#include <Palettes.h>
59#include <ImageCompression.h>
60#include <PictUtils.h>
61#include <Files.h>
62#include <Gestalt.h>
63#include <TextUtils.h>
64#define ColorInfo KolorInfo
65#include "magick/studio.h"
66#include "magick/blob.h"
67#include "magick/client.h"
68#include "magick/exception.h"
69#include "magick/exception-private.h"
70#include "magick/image-private.h"
71#include "magick/list.h"
72#include "magick/magick.h"
73#include "magick/monitor.h"
74#include "magick/monitor-private.h"
75#include "magick/quantum.h"
76#include "magick/string_.h"
77#include "magick/utility.h"
78#include "magick/mac.h"
79
80/*
81 Global declaractions.
82*/
83ImageDescriptionHandle
84 image_description = nil;
85
86/*
87 Forward declaractions.
88*/
89static Boolean
90 SearchForFile(OSType,OSType,FSSpec *,short);
91
92static pascal void
93 ArcMethod(GrafVerb,Rect *,short,short),
94 BitsMethod(BitMap *,Rect *,Rect *,short,RgnHandle),
95 FilenameToFSSpec(const char *filename,FSSpec *fsspec),
96 LineMethod(Point),
97 OvalMethod(GrafVerb,Rect *),
98 PolyMethod(GrafVerb,PolyHandle),
99 RRectMethod(GrafVerb,Rect *,short,short),
100 RectMethod(GrafVerb,Rect *),
101 RegionMethod(GrafVerb,RgnHandle),
102 StandardPixmap(PixMapPtr,Rect *,MatrixRecordPtr,short,RgnHandle,PixMapPtr,
103 Rect *,short),
104 TextMethod(short,Ptr,Point,Point);
105
106/*
107 Static declarations
108 */
109#if defined(DISABLE_SIOUX)
110static MACEventHookPtr
111 event_hook = nil;
112
113static MACErrorHookPtr
114 exception.hook = nil;
115#endif
116
117/*
118%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
119% %
120% %
121% %
122% B o t t l e n e c k T e s t %
123% %
124% %
125% %
126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
127%
128% BottleneckTest() intercepts any compressed images.
129%
130% The format of the BottleneckTest method is:
131%
132% int BottleneckTest(const char *magick)
133%
134% A description of each parameter follows:
135%
136% o picture: Specifies a pointer to a PicHandle structure.
137%
138% o codec: the code type is returned in this CodecType pointer structure.
139%
140% o depth: the image depth is returned as an integer pointer.
141%
142% o colormap_id: the colormap ID is returned in this short pointer.
143%
144%
145*/
146
147static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle,
148 short arcAngle)
149{
150#pragma unused (verb,r,startAngle,arcAngle)
151}
152
153static pascal void BitsMethod(BitMap *bitPtr,Rect *source_rectangle,
154 Rect *dstRect,short mode,RgnHandle maskRgn)
155{
156#pragma unused (bitPtr,source_rectangle,dstRect,mode,maskRgn)
157}
158
159static pascal void LineMethod(Point newPt)
160{
161#pragma unused (newPt)
162}
163
164static pascal void OvalMethod(GrafVerb verb,Rect *r)
165{
166#pragma unused (verb,r)
167}
168
169static pascal void PolyMethod(GrafVerb verb,PolyHandle poly)
170{
171#pragma unused (verb,poly)
172}
173
174static pascal void RectMethod(GrafVerb verb,Rect *r)
175{
176#pragma unused (verb,r)
177}
178
179static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn)
180{
181#pragma unused (verb,rgn)
182}
183
184static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth,
185 short ovalHeight)
186{
187#pragma unused (verb,r,ovalWidth,ovalHeight)
188}
189
190static pascal void StandardPixmap(PixMapPtr source,Rect *source_rectangle,
191 MatrixRecordPtr matrix,short mode,RgnHandle mask,PixMapPtr matte,
192 Rect *matte_rectangle,short flags)
193{
194#pragma unused (source_rectangle,matrix,mode,mask,matte,matte_rectangle,flags)
195
cristybb503372010-05-27 20:51:26 +0000196 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000197 size;
198
199 Ptr
200 data;
201
202 GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil);
203}
204
205static pascal void TextMethod(short byteCount,Ptr textBuf,Point numer,
206 Point denom)
207{
208#pragma unused (byteCount,textBuf,numer,denom)
209}
210
211#if !defined(DISABLE_QUICKTIME)
212static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth,
213 short *colormap_id)
214{
215 CQDProcs
216 bottlenecks;
217
218 int
219 status;
220
cristybb503372010-05-27 20:51:26 +0000221 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000222 version;
223
224 Rect
225 rectangle;
226
227 status=Gestalt(gestaltQuickTime,&version);
228 if (status != noErr)
229 {
230 ParamText("\pQuickTime not installed. Please install, then try again.",
231 "\p","\p","\p");
232 Alert(128,nil);
233 return(-1);
234 }
235 /*
236 Define our own bottlenecks to do nothing.
237 */
238 SetStdCProcs(&bottlenecks);
239 bottlenecks.textProc=NewQDTextUPP(&TextMethod);
240 bottlenecks.lineProc=NewQDLineUPP(&LineMethod);
241 bottlenecks.rectProc=NewQDRectUPP(&RectMethod);
242 bottlenecks.rRectProc=NewQDRRectUPP(&RRectMethod);
243 bottlenecks.ovalProc=NewQDOvalUPP(&OvalMethod);
244 bottlenecks.arcProc=NewQDArcUPP(&ArcMethod);
245 bottlenecks.polyProc=NewQDPolyUPP(&PolyMethod);
246 bottlenecks.rgnProc=NewQDRgnUPP(&RegionMethod);
247 bottlenecks.bitsProc=NewQDBitsUPP(&BitsMethod);
248 bottlenecks.newProc1=(UniversalProcPtr) NewStdPixUPP(&StandardPixmap);
249 /*
250 Install our custom bottlenecks to intercept any compressed images.
251 */
252 (*(qd.thePort)).grafProcs=(QDProcs *) &bottlenecks;
253 DrawPicture(picture,&((**picture).picFrame));
254 PaintRect(&rectangle);
255 (*(qd.thePort)).grafProcs=0L;
256 /*
257 Initialize our return values.
258 */
259 *codec='unkn';
260 *depth=0;
261 *colormap_id=(-1);
262 if (image_description != nil)
263 {
264 *codec=(**image_description).cType;
265 *depth=(**image_description).depth;
266 *colormap_id=(**image_description).clutID;
267 }
268 DisposeQDTextUPP(bottlenecks.textProc);
269 DisposeQDLineUPP(bottlenecks.lineProc);
270 DisposeQDRectUPP(bottlenecks.rectProc);
271 DisposeQDRRectUPP(bottlenecks.rRectProc);
272 DisposeQDOvalUPP(bottlenecks.ovalProc);
273 DisposeQDArcUPP(bottlenecks.arcProc);
274 DisposeQDPolyUPP(bottlenecks.polyProc);
275 DisposeQDRgnUPP(bottlenecks.rgnProc);
276 DisposeQDBitsUPP(bottlenecks.bitsProc);
277 DisposeStdPixUPP(bottlenecks.newProc1);
278 return(0);
279}
280#endif
281
282#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
283/*
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285% %
286% %
287% %
288% c l o s e d i r %
289% %
290% %
291% %
292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293%
294% closedir() closes the named directory stream and frees the DIR structure.
295%
296% The format of the closedir method is:
297%
298% closedir(entry)
299%
300% A description of each parameter follows:
301%
302% o entry: Specifies a pointer to a DIR structure.
303%
304%
305*/
306MagickExport void closedir(DIR *entry)
307{
308 if (image->debug != MagickFalse)
309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
310 assert(entry != (DIR *) NULL);
311 RelinquishMagickMemory(entry);
312}
313#endif
314
315/*
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317% %
318% %
319% %
320% E x i t %
321% %
322% %
323% %
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325%
326% Exit() exits the process.
327%
328% The format of the exit method is:
329%
330% Exit(status)
331%
332% A description of each parameter follows:
333%
334% o status: an integer value representing the status of the terminating
335% process.
336%
337%
338*/
339MagickExport int Exit(int status)
340{
341#if !defined(DISABLE_SIOUX)
342 (void) fprintf(stdout,"Select File->Quit to exit.\n");
343#endif
344 exit(status);
345 return(0);
346}
347
348/*
349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350% %
351% %
352% %
353% F i l e n a m e T o F S S p e c %
354% %
355% %
356% %
357%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
358%
359% FilenameToFSSpec() sets the file type of an image.
360%
361% The format of the FilenameToFSSpec method is:
362%
363% FilenameToFSSpec(filename,fsspec)
364%
365% A description of each parameter follows:
366%
367% o filename: Specifies the name of the file.
368%
369% o fsspec: A pointer to type FSSpec.
370%
371%
372*/
373MagickExport void pascal FilenameToFSSpec(const char *filename,FSSpec *fsspec)
374{
375 Str255
376 name;
377
378 assert(filename != (char *) NULL);
379 c2pstrcpy(name,filename);
380 FSMakeFSSpec(0,0,name,fsspec);
381}
382
383/*
384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385% %
386% %
387% %
388% I s M a g i c k C o n f l i c t %
389% %
390% %
391% %
392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393%
394% MACIsMagickConflict() returns true if the image format conflicts with a
395% logical drive (.e.g. X:).
396%
397% Contributed by Mark Gavin of Digital Applications, Inc.
398%
399% The format of the MACIsMagickConflict method is:
400%
401% status=MACIsMagickConflict(magick)
402%
403% A description of each parameter follows:
404%
405% o magick: Specifies the image format.
406%
407%
408*/
409
410static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume,
cristybb503372010-05-27 20:51:26 +0000411 size_t *free_bytes,size_t *total_bytes)
cristy3ed852e2009-09-05 21:47:34 +0000412{
413 HParamBlockRec
414 pb;
415
416 OSErr
417 result;
418
cristybb503372010-05-27 20:51:26 +0000419 size_t
cristy3ed852e2009-09-05 21:47:34 +0000420 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;
cristybb503372010-05-27 20:51:26 +0000436 blocksize=(size_t) pb.volumeParam.ioVAlBlkSiz;
cristy3ed852e2009-09-05 21:47:34 +0000437 allocation_blocks=(unsigned short) pb.volumeParam.ioVNmAlBlks;
438 free_blocks=(unsigned short) pb.volumeParam.ioVFrBlk;
439 *free_bytes=free_blocks*blocksize;
440 *total_bytes=allocation_blocks*blocksize;
441 return(result);
442}
443
444MagickExport MagickBooleanType MACIsMagickConflict(const char *magick)
445{
cristybb503372010-05-27 20:51:26 +0000446 size_t
cristy3ed852e2009-09-05 21:47:34 +0000447 free_bytes,
448 number_bytes;
449
450 OSErr
451 status;
452
453 short
454 volume;
455
456 Str255
457 volume_name;
458
459 assert(magick != (char *) NULL);
460 if (image->debug != MagickFalse)
461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick);
462 (void) CopyMagickString((char *) volume_name,magick,MaxTextExtent);
463 c2pstr((char *) volume_name);
464 if (volume_name[volume_name[0]] != ':')
465 volume_name[++volume_name[0]]=':';
466 status=HGetVInfo(-1,volume_name,&volume,&free_bytes,&number_bytes);
467 return(status != 0 ? MagickFalse : MagickTrue);
468}
469
470/*
471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472% %
473% %
474% %
475+ M A C E r r o r H a n d l e r %
476% %
477% %
478% %
479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480%
481% MACErrorHandler() displays an error reason and then terminates the program.
482%
483% The format of the MACErrorHandler method is:
484%
485% void MACErrorHandler(const ExceptionType error,const char *reason,
486% const char *description)
487%
488% A description of each parameter follows:
489%
490% o exception: Specifies the numeric error category.
491%
492% o reason: Specifies the reason to display before terminating the
493% program.
494%
495% o description: Specifies any description to the reason.
496%
497%
498*/
499MagickExport void MACErrorHandler(const ExceptionType error,const char *reason,
500 const char *description)
501{
502 char
503 buffer[3*MaxTextExtent];
504
505 if (reason == (char *) NULL)
506 return;
507 if (description == (char *) NULL)
508 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
509 reason);
510 else
511 (void) FormatMagickString(buffer,MaxTextExtent,"%s: %s (%s).\n",
512 GetClientName(),reason,description);
513#if defined(DISABLE_SIOUX)
514 if(exception.hook != (MACErrorHookPtr) NULL)
515 exception.hook(error,buffer);
516 else
517 {
518 MagickCoreTerminus();
519 exit(error);
520 }
521#else
522 puts(buffer);
523 MagickCoreTerminus();
524 exit(error);
525#endif
526}
527
528#if defined(DISABLE_SIOUX)
529/*
530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531% %
532% %
533% %
534+ M A C F a t a l E r r o r H a n d l e r %
535% %
536% %
537% %
538%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539%
540% MACFatalErrorHandler() displays an error reason and then terminates the
541% program.
542%
543% The format of the MACFatalErrorHandler method is:
544%
545% void MACFatalErrorHandler(const ExceptionType severity,
546% const char *reason,const char *description)
547%
548% A description of each parameter follows:
549%
550% o severity: Specifies the numeric error category.
551%
552% o reason: Specifies the reason to display before terminating the
553% program.
554%
555% o description: Specifies any description to the reason.
556%
cristy3ed852e2009-09-05 21:47:34 +0000557*/
558static 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) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
568 reason);
569 else
570 (void) FormatMagickString(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
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*/
cristybb503372010-05-27 20:51:26 +0000597static OSErr MacGSExecuteCommand(const char *command,ssize_t length)
cristy3ed852e2009-09-05 21:47:34 +0000598{
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
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*/
cristybb503372010-05-27 20:51:26 +0000656static OSErr MacGSLaunchApplicationCore(ssize_t flags)
cristy3ed852e2009-09-05 21:47:34 +0000657{
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
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*/
694static OSErr MacGSLaunchApplication(void)
695{
696 return(MacGSLaunchApplicationCore(launchDontSwitch));
697}
698
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*/
714static OSErr MacGSLaunchApplicationToFront(void)
715{
716 return(MacGSLaunchApplicationCore(0));
717}
718
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*/
734static 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
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*/
780static 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
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*/
850MagickExport void MACSetErrorHook(MACErrorHookPtr hook)
851{
852 /*
853 We forget any previously set exception.hook.
854 */
855 exception.hook=hook;
856}
857
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*/
882MagickExport void MACSetEventHook(MACEventHookPtr hook)
883{
884 /*
885 We forget any previously set event hook.
886 */
887 event_hook=hook;
888}
889
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%
cristy6de4bc22010-01-12 17:10:35 +0000906% int MACSystemCommand(MagickFalse,const char * command)
cristy3ed852e2009-09-05 21:47:34 +0000907%
908% A description of each parameter follows:
909%
910% o command: This string is the command to execute.
911%
cristy3ed852e2009-09-05 21:47:34 +0000912*/
913MagickExport 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
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*/
952MagickExport 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) FormatMagickString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
962 reason);
963 else
964 (void) FormatMagickString(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
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*/
1000MagickExport 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 }
cristy73bd4a52010-10-05 11:24:23 +00001030 entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
cristy3ed852e2009-09-05 21:47:34 +00001031 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
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*/
1064MagickExport 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
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*/
1111MagickExport 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
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
1180static 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
1187MagickExport 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
cristybb503372010-05-27 20:51:26 +00001209 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001210 y;
1211
1212 MagickBooleanType
1213 proceed,
1214 status;
1215
1216 PicHandle
1217 picture_handle;
1218
1219 PictInfo
1220 picture_info;
1221
1222 QDErr
1223 theErr = noErr;
1224
1225 Rect
1226 rectangle;
1227
1228 RGBColor
1229 Pixel;
1230
1231 short
1232 colormap_id;
1233
1234 /*
1235 Open image file.
1236 */
1237 image=AcquireImage(image_info);
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->x_resolution=(picture_info.hRes) >> 16;
1303 image->y_resolution=(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 {
cristybb503372010-05-27 20:51:26 +00001309 size_t
cristy3ed852e2009-09-05 21:47:34 +00001310 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 IndexPacket
cristyc47d1f82009-11-26 01:44:43 +00001352 *restrict indexes;
cristy3ed852e2009-09-05 21:47:34 +00001353
cristybb503372010-05-27 20:51:26 +00001354 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001355 x;
1356
1357 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +00001358 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +00001359
1360 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1361 if (q == (PixelPacket *) NULL)
1362 break;
1363 indexes=GetAuthenticIndexQueue(image);
1364 for (x=0; x < image->columns; x++)
1365 {
1366 GetCPixel(x,y,&Pixel);
1367 q->red=ScaleCharToQuantum(Pixel.red & 0xff);
1368 q->green=ScaleCharToQuantum(Pixel.green & 0xff);
1369 q->blue=ScaleCharToQuantum(Pixel.blue & 0xff);
1370 if (image->storage_class == PseudoClass)
1371 indexes[x]=Color2Index(&Pixel);
1372 q++;
1373 }
1374 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1375 break;
1376 proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
1377 if (proceed == MagickFalse)
1378 break;
1379 }
1380 UnlockPixels(GetGWorldPixMap(graphic_world));
1381 SetGWorld(port,device);
1382 if (picture_info.theColorTable != nil)
1383 DisposeHandle((Handle) picture_info.theColorTable);
1384 DisposeGWorld(graphic_world);
1385 (void) CloseBlob(image);
1386 return(image);
1387}
1388
1389/*
1390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391% %
1392% %
1393% %
1394% S e a r c h F o r F i l e %
1395% %
1396% %
1397% %
1398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1399%
1400% SearchForFile() searches for a file.
1401%
1402%
1403*/
1404static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file,
1405 short count)
1406{
1407 char
1408 *buffer;
1409
1410 CInfoPBRec
1411 search1_info,
1412 search2_info;
1413
1414 FSSpec
1415 application;
1416
1417 HParamBlockRec
1418 parameter_info;
1419
cristybb503372010-05-27 20:51:26 +00001420 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001421 buffer_size = 16384;
1422
1423 OSErr
1424 error;
1425
1426 ProcessInfoRec
1427 application_info;
1428
1429 ProcessSerialNumber
1430 serial_number;
1431
1432 serial_number.lowLongOfPSN=kCurrentProcess;
1433 serial_number.highLongOfPSN=0;
1434 application_info.processInfoLength=sizeof(ProcessInfoRec);
1435 application_info.processName=NULL;
1436 application_info.processAppSpec=(&application);
1437 GetProcessInformation(&serial_number,&application_info);
1438 buffer=NewPtr(buffer_size);
1439 if (buffer == (char *) NULL)
1440 return(false);
1441 parameter_info.csParam.ioCompletion=NULL;
1442 parameter_info.csParam.ioNamePtr=NULL;
1443 parameter_info.csParam.ioVRefNum=application.vRefNum;
1444 parameter_info.csParam.ioMatchPtr=file;
1445 parameter_info.csParam.ioReqMatchCount=count;
1446 parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo;
1447 parameter_info.csParam.ioSearchInfo1=&search1_info;
1448 parameter_info.csParam.ioSearchInfo2=&search2_info;
1449 parameter_info.csParam.ioSearchTime=0;
1450 parameter_info.csParam.ioCatPosition.initialize=0;
1451 parameter_info.csParam.ioOptBuffer=buffer;
1452 parameter_info.csParam.ioOptBufSize=buffer_size;
1453 search1_info.hFileInfo.ioNamePtr=NULL;
1454 search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type;
1455 search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1456 search1_info.hFileInfo.ioFlAttrib=0;
1457 search1_info.hFileInfo.ioFlParID=0;
1458 search2_info=search1_info;
1459 search2_info.hFileInfo.ioFlAttrib=0x10;
1460 search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
1461 search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1);
1462 search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0;
1463 search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0;
1464 search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0;
1465 search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0;
1466 search2_info.hFileInfo.ioFlParID=0;
1467 error=PBCatSearchSync((CSParamPtr) &parameter_info);
1468 DisposePtr(buffer);
1469 if (parameter_info.csParam.ioReqMatchCount ==
1470 parameter_info.csParam.ioActMatchCount)
1471 error=eofErr;
1472 if (parameter_info.csParam.ioActMatchCount == 0)
1473 error=0;
1474 return(error == eofErr);
1475}
1476
1477#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1478/*
1479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1480% %
1481% %
1482% %
1483% s e e k d i r %
1484% %
1485% %
1486% %
1487%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1488%
1489% seekdir() sets the position of the next readdir() operation on the directory
1490% stream.
1491%
1492% The format of the seekdir method is:
1493%
cristybb503372010-05-27 20:51:26 +00001494% void seekdir(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001495%
1496% A description of each parameter follows:
1497%
1498% o entry: Specifies a pointer to a DIR structure.
1499%
1500% o position: specifies the position associated with the directory
1501% stream.
1502%
1503%
1504%
1505*/
cristybb503372010-05-27 20:51:26 +00001506MagickExport void seekdir(DIR *entry,ssize_t position)
cristy3ed852e2009-09-05 21:47:34 +00001507{
1508 assert(entry != (DIR *) NULL);
1509 entry->d_index=position;
1510}
1511#endif
1512
1513/*
1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515% %
1516% %
1517% %
1518% S e t A p p l i c a t i o n T y p e %
1519% %
1520% %
1521% %
1522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1523%
1524% SetApplicationType() sets the file type of an image.
1525%
1526% The format of the SetApplicationType method is:
1527%
1528% void SetApplicationType(const char *filename,const char *magick,
1529% OSType application)
1530%
1531% A description of each parameter follows:
1532%
1533% o filename: Specifies the name of the file.
1534%
1535% o filename: Specifies the file type.
1536%
1537% o application: Specifies the type of the application.
1538%
1539*/
1540
1541static inline size_t MagickMin(const size_t x,const size_t y)
1542{
1543 if (x < y)
1544 return(x);
1545 return(y);
1546}
1547
1548MagickExport void SetApplicationType(const char *filename,const char *magick,
1549 OSType application)
1550{
1551 FSSpec
1552 file_specification;
1553
1554 OSType
1555 filetype;
1556
1557 Str255
1558 name;
1559
1560 assert(filename != (char *) NULL);
1561 if (image->debug != MagickFalse)
1562 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1563 assert(magick != (const char *) NULL);
1564 filetype=' ';
1565 (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick),
1566 4));
1567 if (LocaleCompare(magick,"JPG") == 0)
1568 (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent);
1569 c2pstrcpy(name,filename);
1570 FSMakeFSSpec(0,0,name,&file_specification);
1571 FSpCreate(&file_specification,application,filetype,smSystemScript);
1572}
1573
1574#if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
1575/*
1576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1577% %
1578% %
1579% %
1580% t e l l d i r %
1581% %
1582% %
1583% %
1584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1585%
1586% Method telldir returns the current location associated with the
1587% named directory stream.
1588%
1589% The format of the telldir method is:
1590%
1591% telldir(DIR *entry)
1592%
1593% A description of each parameter follows:
1594%
1595% o entry: Specifies a pointer to a DIR structure.
1596%
1597%
1598*/
cristybb503372010-05-27 20:51:26 +00001599MagickExport ssize_t telldir(DIR *entry)
cristy3ed852e2009-09-05 21:47:34 +00001600{
1601 return(entry->d_index);
1602}
1603#endif
1604
1605#endif