MagickCore  6.7.7
mac.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                            M   M   AAA    CCCC                              %
00007 %                            MM MM  A   A  C                                  %
00008 %                            M M M  AAAAA  C                                  %
00009 %                            M   M  A   A  C                                  %
00010 %                            M   M  A   A   CCCC                              %
00011 %                                                                             %
00012 %                                                                             %
00013 %                    Macintosh Utility Methods for MagickCore                 %
00014 %                                                                             %
00015 %                               Software Design                               %
00016 %                                 John Cristy                                 %
00017 %                                September 1996                               %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %  The directory methods are strongly based on similar methods written
00037 %  by Steve Summit, scs@eskimo.com.  The Ghostscript launch code is strongly
00038 %  based on Dave Schooley's Mac Gnuplot and contributed by
00039 %  schindall@wave14i.nrl.navy.mil.  Mac-centric improvements contributed by
00040 %  leonardr@digapp.com.
00041 %
00042 %
00043 */
00044 
00045 #if defined(macintosh)
00046 /*
00047   Include declarations.
00048 */
00049 #define _X_H
00050 #define _WIDGET_H
00051 #include <AppleEvents.h>
00052 #include <AERegistry.h>
00053 #include <AEObjects.h>
00054 #include <AEPackObject.h>
00055 #include <Processes.h>
00056 #include <QuickDraw.h>
00057 #include <QDOffscreen.h>
00058 #include <Palettes.h>
00059 #include <ImageCompression.h>
00060 #include <PictUtils.h>
00061 #include <Files.h>
00062 #include <Gestalt.h>
00063 #include <TextUtils.h>
00064 #define ColorInfo  KolorInfo
00065 #include "MagickCore/studio.h"
00066 #include "MagickCore/blob.h"
00067 #include "MagickCore/client.h"
00068 #include "MagickCore/exception.h"
00069 #include "MagickCore/exception-private.h"
00070 #include "MagickCore/image-private.h"
00071 #include "MagickCore/list.h"
00072 #include "MagickCore/magick.h"
00073 #include "MagickCore/monitor.h"
00074 #include "MagickCore/monitor-private.h"
00075 #include "MagickCore/quantum.h"
00076 #include "MagickCore/string_.h"
00077 #include "MagickCore/utility.h"
00078 #include "MagickCore/mac.h"
00079 
00080 /*
00081   Global declaractions.
00082 */
00083 ImageDescriptionHandle
00084   image_description = nil;
00085 
00086 /*
00087   Forward declaractions.
00088 */
00089 static Boolean
00090   SearchForFile(OSType,OSType,FSSpec *,short);
00091 
00092 static pascal void
00093   ArcMethod(GrafVerb,Rect *,short,short),
00094   BitsMethod(BitMap *,Rect *,Rect *,short,RgnHandle),
00095   FilenameToFSSpec(const char *filename,FSSpec *fsspec),
00096   LineMethod(Point),
00097   OvalMethod(GrafVerb,Rect *),
00098   PolyMethod(GrafVerb,PolyHandle),
00099   RRectMethod(GrafVerb,Rect *,short,short),
00100   RectMethod(GrafVerb,Rect *),
00101   RegionMethod(GrafVerb,RgnHandle),
00102   StandardPixmap(PixMapPtr,Rect *,MatrixRecordPtr,short,RgnHandle,PixMapPtr,
00103     Rect *,short),
00104   TextMethod(short,Ptr,Point,Point);
00105 
00106 /*
00107   Static declarations
00108  */
00109 #if defined(DISABLE_SIOUX)
00110 static MACEventHookPtr
00111   event_hook = nil;
00112 
00113 static MACErrorHookPtr
00114   exception.hook = nil;
00115 #endif
00116 
00117 /*
00118 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00119 %                                                                             %
00120 %                                                                             %
00121 %                                                                             %
00122 %   B o t t l e n e c k T e s t                                               %
00123 %                                                                             %
00124 %                                                                             %
00125 %                                                                             %
00126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00127 %
00128 %  BottleneckTest() intercepts any compressed images.
00129 %
00130 %  The format of the BottleneckTest method is:
00131 %
00132 %      int BottleneckTest(const char *magick)
00133 %
00134 %  A description of each parameter follows:
00135 %
00136 %    o picture: Specifies a pointer to a PicHandle structure.
00137 %
00138 %    o codec: the code type is returned in this CodecType pointer structure.
00139 %
00140 %    o depth: the image depth is returned as an integer pointer.
00141 %
00142 %    o colormap_id: the colormap ID is returned in this short pointer.
00143 %
00144 %
00145 */
00146 
00147 static pascal void ArcMethod(GrafVerb verb,Rect *r,short startAngle,
00148   short arcAngle)
00149 {
00150 #pragma unused (verb,r,startAngle,arcAngle)
00151 }
00152 
00153 static pascal void BitsMethod(BitMap *bitPtr,Rect *source_rectangle,
00154   Rect *dstRect,short mode,RgnHandle maskRgn)
00155 {
00156 #pragma unused (bitPtr,source_rectangle,dstRect,mode,maskRgn)
00157 }
00158 
00159 static pascal void LineMethod(Point newPt)
00160 {
00161 #pragma unused (newPt)
00162 }
00163 
00164 static pascal void OvalMethod(GrafVerb verb,Rect *r)
00165 {
00166 #pragma unused (verb,r)
00167 }
00168 
00169 static pascal void PolyMethod(GrafVerb verb,PolyHandle poly)
00170 {
00171 #pragma unused (verb,poly)
00172 }
00173 
00174 static pascal void RectMethod(GrafVerb verb,Rect *r)
00175 {
00176 #pragma unused (verb,r)
00177 }
00178 
00179 static pascal void RegionMethod(GrafVerb verb,RgnHandle rgn)
00180 {
00181 #pragma unused (verb,rgn)
00182 }
00183 
00184 static pascal void RRectMethod(GrafVerb verb,Rect *r,short ovalWidth,
00185   short ovalHeight)
00186 {
00187 #pragma unused (verb,r,ovalWidth,ovalHeight)
00188 }
00189 
00190 static pascal void StandardPixmap(PixMapPtr source,Rect *source_rectangle,
00191   MatrixRecordPtr matrix,short mode,RgnHandle mask,PixMapPtr matte,
00192   Rect *matte_rectangle,short flags)
00193 {
00194 #pragma unused (source_rectangle,matrix,mode,mask,matte,matte_rectangle,flags)
00195 
00196   Ptr
00197     data;
00198 
00199   ssize_t
00200     size;
00201 
00202   GetCompressedPixMapInfo(source,&image_description,&data,&size,nil,nil);
00203 }
00204 
00205 static pascal void TextMethod(short byteCount,Ptr textBuf,Point numer,
00206   Point denom)
00207 {
00208 #pragma unused (byteCount,textBuf,numer,denom)
00209 }
00210 
00211 #if !defined(DISABLE_QUICKTIME)
00212 static short BottleneckTest(PicHandle picture,CodecType *codec,int *depth,
00213   short *colormap_id)
00214 {
00215   CQDProcs
00216     bottlenecks;
00217 
00218   int
00219     status;
00220 
00221   Rect
00222     rectangle;
00223 
00224   ssize_t
00225     version;
00226 
00227   status=Gestalt(gestaltQuickTime,&version);
00228   if (status != noErr)
00229     {
00230       ParamText("\pQuickTime not installed.  Please install, then try again.",
00231         "\p","\p","\p");
00232       Alert(128,nil);
00233       return(-1);
00234     }
00235   /*
00236     Define our own bottlenecks to do nothing.
00237   */
00238   SetStdCProcs(&bottlenecks);
00239   bottlenecks.textProc=NewQDTextUPP(&TextMethod);
00240   bottlenecks.lineProc=NewQDLineUPP(&LineMethod);
00241   bottlenecks.rectProc=NewQDRectUPP(&RectMethod);
00242   bottlenecks.rRectProc=NewQDRRectUPP(&RRectMethod);
00243   bottlenecks.ovalProc=NewQDOvalUPP(&OvalMethod);
00244   bottlenecks.arcProc=NewQDArcUPP(&ArcMethod);
00245   bottlenecks.polyProc=NewQDPolyUPP(&PolyMethod);
00246   bottlenecks.rgnProc=NewQDRgnUPP(&RegionMethod);
00247   bottlenecks.bitsProc=NewQDBitsUPP(&BitsMethod);
00248   bottlenecks.newProc1=(UniversalProcPtr) NewStdPixUPP(&StandardPixmap);
00249   /*
00250     Install our custom bottlenecks to intercept any compressed images.
00251   */
00252   (*(qd.thePort)).grafProcs=(QDProcs *) &bottlenecks;
00253   DrawPicture(picture,&((**picture).picFrame));
00254   PaintRect(&rectangle);
00255   (*(qd.thePort)).grafProcs=0L;
00256   /*
00257     Initialize our return values.
00258   */
00259   *codec='unkn';
00260   *depth=0;
00261   *colormap_id=(-1);
00262   if (image_description != nil)
00263     {
00264       *codec=(**image_description).cType;
00265       *depth=(**image_description).depth;
00266       *colormap_id=(**image_description).clutID;
00267     }
00268   DisposeQDTextUPP(bottlenecks.textProc);
00269   DisposeQDLineUPP(bottlenecks.lineProc);
00270   DisposeQDRectUPP(bottlenecks.rectProc);
00271   DisposeQDRRectUPP(bottlenecks.rRectProc);
00272   DisposeQDOvalUPP(bottlenecks.ovalProc);
00273   DisposeQDArcUPP(bottlenecks.arcProc);
00274   DisposeQDPolyUPP(bottlenecks.polyProc);
00275   DisposeQDRgnUPP(bottlenecks.rgnProc);
00276   DisposeQDBitsUPP(bottlenecks.bitsProc);
00277   DisposeStdPixUPP(bottlenecks.newProc1);
00278   return(0);
00279 }
00280 #endif
00281 
00282 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
00283 /*
00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00285 %                                                                             %
00286 %                                                                             %
00287 %                                                                             %
00288 %   c l o s e d i r                                                           %
00289 %                                                                             %
00290 %                                                                             %
00291 %                                                                             %
00292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00293 %
00294 %  closedir() closes the named directory stream and frees the DIR structure.
00295 %
00296 %  The format of the closedir method is:
00297 %
00298 %      closedir(entry)
00299 %
00300 %  A description of each parameter follows:
00301 %
00302 %    o entry: Specifies a pointer to a DIR structure.
00303 %
00304 %
00305 */
00306 MagickExport void closedir(DIR *entry)
00307 {
00308   if (image->debug != MagickFalse)
00309     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00310   assert(entry != (DIR *) NULL);
00311   RelinquishMagickMemory(entry);
00312 }
00313 #endif
00314 
00315 /*
00316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00317 %                                                                             %
00318 %                                                                             %
00319 %                                                                             %
00320 %   E x i t                                                                   %
00321 %                                                                             %
00322 %                                                                             %
00323 %                                                                             %
00324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00325 %
00326 %  Exit() exits the process.
00327 %
00328 %  The format of the exit method is:
00329 %
00330 %      Exit(status)
00331 %
00332 %  A description of each parameter follows:
00333 %
00334 %    o status: an integer value representing the status of the terminating
00335 %      process.
00336 %
00337 %
00338 */
00339 MagickExport int Exit(int status)
00340 {
00341 #if !defined(DISABLE_SIOUX)
00342   (void) FormatLocaleFile(stdout,"Select File->Quit to exit.\n");
00343 #endif
00344   exit(status);
00345   return(0);
00346 }
00347 
00348 /*
00349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00350 %                                                                             %
00351 %                                                                             %
00352 %                                                                             %
00353 %   F i l e n a m e T o F S S p e c                                           %
00354 %                                                                             %
00355 %                                                                             %
00356 %                                                                             %
00357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00358 %
00359 %  FilenameToFSSpec() sets the file type of an image.
00360 %
00361 %  The format of the FilenameToFSSpec method is:
00362 %
00363 %      FilenameToFSSpec(filename,fsspec)
00364 %
00365 %  A description of each parameter follows:
00366 %
00367 %    o filename: Specifies the name of the file.
00368 %
00369 %    o fsspec: A pointer to type FSSpec.
00370 %
00371 %
00372 */
00373 MagickExport void pascal FilenameToFSSpec(const char *filename,FSSpec *fsspec)
00374 {
00375   Str255
00376     name;
00377 
00378   assert(filename != (char *) NULL);
00379   c2pstrcpy(name,filename);
00380   FSMakeFSSpec(0,0,name,fsspec);
00381 }
00382 
00383 /*
00384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00385 %                                                                             %
00386 %                                                                             %
00387 %                                                                             %
00388 %   I s M a g i c k C o n f l i c t                                           %
00389 %                                                                             %
00390 %                                                                             %
00391 %                                                                             %
00392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00393 %
00394 %  MACIsMagickConflict() returns true if the image format conflicts with a
00395 %  logical drive (.e.g. X:).
00396 %
00397 %  Contributed by Mark Gavin of Digital Applications, Inc.
00398 %
00399 %  The format of the MACIsMagickConflict method is:
00400 %
00401 %      status=MACIsMagickConflict(magick)
00402 %
00403 %  A description of each parameter follows:
00404 %
00405 %    o magick: Specifies the image format.
00406 %
00407 %
00408 */
00409 
00410 static OSErr HGetVInfo(short volume_index,StringPtr volume_name,short *volume,
00411   size_t *free_bytes,size_t *total_bytes)
00412 {
00413   HParamBlockRec
00414     pb;
00415 
00416   OSErr
00417     result;
00418 
00419   size_t
00420     blocksize;
00421 
00422   unsigned short
00423     allocation_blocks,
00424     free_blocks;
00425 
00426   /*
00427     Use the File Manager to get the real vRefNum.
00428   */
00429   pb.volumeParam.ioVRefNum=0;
00430   pb.volumeParam.ioNamePtr=volume_name;
00431   pb.volumeParam.ioVolIndex=volume_index;
00432   result=PBHGetVInfoSync(&pb);
00433   if (result != noErr)
00434     return(result);
00435   *volume=pb.volumeParam.ioVRefNum;
00436   blocksize=(size_t) pb.volumeParam.ioVAlBlkSiz;
00437   allocation_blocks=(unsigned short) pb.volumeParam.ioVNmAlBlks;
00438   free_blocks=(unsigned short) pb.volumeParam.ioVFrBlk;
00439   *free_bytes=free_blocks*blocksize;
00440   *total_bytes=allocation_blocks*blocksize;
00441   return(result);
00442 }
00443 
00444 MagickExport MagickBooleanType MACIsMagickConflict(const char *magick)
00445 {
00446   size_t
00447     free_bytes,
00448     number_bytes;
00449 
00450   OSErr
00451     status;
00452 
00453   short
00454     volume;
00455 
00456   Str255
00457     volume_name;
00458 
00459   assert(magick != (char *) NULL);
00460   if (image->debug != MagickFalse)
00461     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick);
00462   (void) CopyMagickString((char *) volume_name,magick,MaxTextExtent);
00463   c2pstr((char *) volume_name);
00464   if (volume_name[volume_name[0]] != ':')
00465     volume_name[++volume_name[0]]=':';
00466   status=HGetVInfo(-1,volume_name,&volume,&free_bytes,&number_bytes);
00467   return(status != 0 ? MagickFalse : MagickTrue);
00468 }
00469 
00470 /*
00471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00472 %                                                                             %
00473 %                                                                             %
00474 %                                                                             %
00475 +   M A C E r r o r H a n d l e r                                             %
00476 %                                                                             %
00477 %                                                                             %
00478 %                                                                             %
00479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00480 %
00481 %  MACErrorHandler() displays an error reason and then terminates the program.
00482 %
00483 %  The format of the MACErrorHandler method is:
00484 %
00485 %      void MACErrorHandler(const ExceptionType error,const char *reason,
00486 %        const char *description)
00487 %
00488 %  A description of each parameter follows:
00489 %
00490 %    o exception: Specifies the numeric error category.
00491 %
00492 %    o reason: Specifies the reason to display before terminating the
00493 %      program.
00494 %
00495 %    o description: Specifies any description to the reason.
00496 %
00497 %
00498 */
00499 MagickExport void MACErrorHandler(const ExceptionType error,const char *reason,
00500   const char *description)
00501 {
00502   char
00503     buffer[3*MaxTextExtent];
00504 
00505   if (reason == (char *) NULL)
00506     return;
00507   if (description == (char *) NULL)
00508     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
00509       reason);
00510   else
00511     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
00512       GetClientName(),reason,description);
00513 #if defined(DISABLE_SIOUX)
00514   if(exception.hook != (MACErrorHookPtr) NULL)
00515     exception.hook(error,buffer);
00516   else
00517     {
00518       MagickCoreTerminus();
00519       exit(error);
00520     }
00521 #else
00522   puts(buffer);
00523   MagickCoreTerminus();
00524   exit(error);
00525 #endif
00526 }
00527 
00528 #if defined(DISABLE_SIOUX)
00529 /*
00530 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00531 %                                                                             %
00532 %                                                                             %
00533 %                                                                             %
00534 +   M A C F a t a l E r r o r H a n d l e r                                   %
00535 %                                                                             %
00536 %                                                                             %
00537 %                                                                             %
00538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00539 %
00540 %  MACFatalErrorHandler() displays an error reason and then terminates the
00541 %  program.
00542 %
00543 %  The format of the MACFatalErrorHandler method is:
00544 %
00545 %      void MACFatalErrorHandler(const ExceptionType severity,
00546 %        const char *reason,const char *description)
00547 %
00548 %  A description of each parameter follows:
00549 %
00550 %    o severity: Specifies the numeric error category.
00551 %
00552 %    o reason: Specifies the reason to display before terminating the
00553 %      program.
00554 %
00555 %    o description: Specifies any description to the reason.
00556 %
00557 */
00558 static void MACFatalErrorHandler(const ExceptionType severity,
00559   const char *reason,const char *description)
00560 {
00561   char
00562     buffer[3*MaxTextExtent];
00563 
00564   if (reason == (char *) NULL)
00565     return;
00566   if (description == (char *) NULL)
00567     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
00568       reason);
00569   else
00570     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
00571       GetClientName(),reason,description);
00572   if(exception.hook != (MACErrorHookPtr) NULL)
00573     exception.hook(severity, buffer);
00574   else
00575     {
00576       MagickCoreTerminus();
00577       exit(severity);
00578     }
00579 }
00580 #endif
00581 
00582 /*
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %                                                                             %
00585 %                                                                             %
00586 %                                                                             %
00587 %   M a c G S E x e c u t e C o m m a n d                                     %
00588 %                                                                             %
00589 %                                                                             %
00590 %                                                                             %
00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00592 %
00593 %  MacGSExecuteCommand() executes the Ghostscript command.
00594 %
00595 %
00596 */
00597 static OSErr MacGSExecuteCommand(const char *command,ssize_t length)
00598 {
00599   AEAddressDesc
00600     event_descriptor;
00601 
00602   AEDesc
00603     reply = {typeNull, NULL};
00604 
00605   AppleEvent
00606     event = {typeNull, NULL};
00607 
00608   DescType
00609     descriptor_type;
00610 
00611   int
00612     error;
00613 
00614   OSType
00615     id = 'gsVR';
00616 
00617   Size
00618     actualSize;
00619 
00620   /*
00621     Send the Apple Event.
00622   */
00623   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
00624   (void) AECreateAppleEvent(id,'exec',&event_descriptor,-1,kAnyTransactionID,
00625     &event);
00626   (void) AEPutParamPtr(&event,keyDirectObject,typeChar,command,length);
00627   (void) AESend(&event,&reply,kAEWaitReply+kAENeverInteract,kAENormalPriority,
00628     kNoTimeOut,NULL,NULL);
00629   /*
00630     Handle the reply and exit.
00631   */
00632   (void) AEGetParamPtr(&reply,keyDirectObject,typeInteger,&descriptor_type,
00633     &error,sizeof(error),&actualSize);
00634   (void) AEDisposeDesc(&event_descriptor);
00635   (void) AEDisposeDesc(&event);
00636   if (reply.descriptorType != NULL)
00637     AEDisposeDesc(&reply);
00638   return((OSErr) error);
00639 }
00640 
00641 /*
00642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00643 %                                                                             %
00644 %                                                                             %
00645 %                                                                             %
00646 %   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                       %
00647 %                                                                             %
00648 %                                                                             %
00649 %                                                                             %
00650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00651 %
00652 %  MacGSLaunchApplicationCore() launches the Ghostscript command.
00653 %
00654 %
00655 */
00656 static OSErr MacGSLaunchApplicationCore(ssize_t flags)
00657 {
00658   FSSpec
00659     file_info;
00660 
00661   LaunchParamBlockRec
00662     launch_info;
00663 
00664   OSErr
00665     error;
00666 
00667   if (!SearchForFile('gsVR','APPL',&file_info,1))
00668     return(-43);
00669   launch_info.launchBlockID=extendedBlock;
00670   launch_info.launchEPBLength=extendedBlockLen;
00671   launch_info.launchFileFlags=0;
00672   launch_info.launchControlFlags=launchContinue+launchNoFileFlags+flags;
00673   launch_info.launchAppSpec=(&file_info);
00674   launch_info.launchAppParameters=nil;
00675   error=LaunchApplication(&launch_info);
00676   return(error);
00677 }
00678 
00679 /*
00680 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00681 %                                                                             %
00682 %                                                                             %
00683 %                                                                             %
00684 %   M a c G S L a u n c h A p p l i c a t i o n                               %
00685 %                                                                             %
00686 %                                                                             %
00687 %                                                                             %
00688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00689 %
00690 %  MacGSLaunchApplication() launches the Ghostscript command.
00691 %
00692 %
00693 */
00694 static OSErr MacGSLaunchApplication(void)
00695 {
00696   return(MacGSLaunchApplicationCore(launchDontSwitch));
00697 }
00698 
00699 /*
00700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00701 %                                                                             %
00702 %                                                                             %
00703 %                                                                             %
00704 %   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                 %
00705 %                                                                             %
00706 %                                                                             %
00707 %                                                                             %
00708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00709 %
00710 %  MacGSLaunchApplicationToFront() moves the Ghostscript window to the front.
00711 %
00712 %
00713 */
00714 static OSErr MacGSLaunchApplicationToFront(void)
00715 {
00716   return(MacGSLaunchApplicationCore(0));
00717 }
00718 
00719 /*
00720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00721 %                                                                             %
00722 %                                                                             %
00723 %                                                                             %
00724 %   M a c G S Q u i t A p p l i c a t i o n                                   %
00725 %                                                                             %
00726 %                                                                             %
00727 %                                                                             %
00728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00729 %
00730 %  MacGSQuitApplication() quits the Ghostscript application.
00731 %
00732 %
00733 */
00734 static void MacGSQuitApplication(void)
00735 {
00736   AEAddressDesc
00737     event_descriptor;
00738 
00739   AEDesc
00740     reply = {typeNull, NULL};
00741 
00742   AppleEvent
00743     event = {typeNull, NULL};
00744 
00745   OSType
00746     id = 'GPLT';
00747 
00748   /*
00749     Send the Apple Event.
00750   */
00751   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
00752   (void) AECreateAppleEvent(typeAppleEvent,kAEQuitApplication,
00753     &event_descriptor,-1,kAnyTransactionID,&event);
00754   (void) AESend(&event,&reply,kAENoReply,kAENormalPriority,kNoTimeOut,NULL,
00755     NULL);
00756   /*
00757     Clean up and exit.
00758   */
00759   (void) AEDisposeDesc(&event_descriptor);
00760   (void) AEDisposeDesc(&event);
00761   if (reply.descriptorType != NULL)
00762     AEDisposeDesc(&reply);
00763 }
00764 
00765 /*
00766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00767 %                                                                             %
00768 %                                                                             %
00769 %                                                                             %
00770 %   M a c G S S e t W o r k i n g F o l d e r                                 %
00771 %                                                                             %
00772 %                                                                             %
00773 %                                                                             %
00774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00775 %
00776 %  MacGSSetWorkingFolder() set the Ghostscript working folder.
00777 %
00778 %
00779 */
00780 static OSErr MacGSSetWorkingFolder(char *directory)
00781 {
00782   AEDesc
00783     application_descriptor,
00784     event_descriptor,
00785     object,
00786     path_descriptor,
00787     type_descriptor,
00788     reply;
00789 
00790   AppleEvent
00791     event;
00792 
00793   DescType
00794     folder_type = 'wfdr';
00795 
00796   OSErr
00797     error;
00798 
00799   OSType
00800     id = 'GPLT';
00801 
00802   /*
00803     Send the Apple Event.
00804   */
00805   AECreateDesc(typeNull,NULL,0,&application_descriptor);
00806   AECreateDesc(typeChar,directory,strlen(directory),&path_descriptor);
00807   (void) AECreateDesc(typeType,&folder_type,sizeof(DescType),&type_descriptor);
00808   CreateObjSpecifier(cProperty,&application_descriptor,formPropertyID,
00809     &type_descriptor,0,&object);
00810   (void) AECreateDesc(typeApplSignature,&id,sizeof(id),&event_descriptor);
00811   (void) AECreateAppleEvent(kAECoreSuite,kAESetData,&event_descriptor,-1,
00812     kAnyTransactionID,&event);
00813   (void) AEPutParamDesc(&event,keyDirectObject,&object);
00814   (void) AEPutParamDesc(&event,keyAEData,&path_descriptor);
00815   error=AESend(&event,&reply,kAENoReply+kAENeverInteract,kAENormalPriority,
00816     kNoTimeOut,NULL,NULL);
00817   (void) AEDisposeDesc(&event);
00818   (void) AEDisposeDesc(&event_descriptor);
00819   (void) AEDisposeDesc(&object);
00820   (void) AEDisposeDesc(&type_descriptor);
00821   (void) AEDisposeDesc(&path_descriptor);
00822   (void) AEDisposeDesc(&application_descriptor);
00823   return(error);
00824 }
00825 
00826 /*
00827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00828 %                                                                             %
00829 %                                                                             %
00830 %                                                                             %
00831 %   M A C S e t E r r o r H o o k                                             %
00832 %                                                                             %
00833 %                                                                             %
00834 %                                                                             %
00835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00836 %
00837 %   MACSetErrorHook sets a callback function which is called if any error
00838 %   occurs within ImageMagick.
00839 %
00840 %  The format of the MACSetErrorHook method is:
00841 %
00842 %      int MACSetErrorHook(MACErrorHookPtr hook)
00843 %
00844 %  A description of each parameter follows:
00845 %
00846 %    o hook: This function pointer is the callback function.
00847 %
00848 %
00849 */
00850 MagickExport void MACSetErrorHook(MACErrorHookPtr hook)
00851 {
00852   /*
00853     We forget any previously set exception.hook.
00854   */
00855   exception.hook=hook;
00856 }
00857 
00858 /*
00859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00860 %                                                                             %
00861 %                                                                             %
00862 %                                                                             %
00863 %   M A C S e t E v e n t H o o k                                             %
00864 %                                                                             %
00865 %                                                                             %
00866 %                                                                             %
00867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00868 %
00869 %   MACSetEventHook sets a callback function which is called every time
00870 %   ImageMagick likes to release the processor.
00871 %
00872 %  The format of the MACSetEventHook method is:
00873 %
00874 %      int MACSetEventHook(MACEventHookPtr hook)
00875 %
00876 %  A description of each parameter follows:
00877 %
00878 %    o hook: This function pointer is the callback function.
00879 %
00880 %
00881 */
00882 MagickExport void MACSetEventHook(MACEventHookPtr hook)
00883 {
00884   /*
00885     We forget any previously set event hook.
00886    */
00887   event_hook=hook;
00888 }
00889 
00890 /*
00891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00892 %                                                                             %
00893 %                                                                             %
00894 %                                                                             %
00895 %   M A C S y s t e m C o m m a n d                                           %
00896 %                                                                             %
00897 %                                                                             %
00898 %                                                                             %
00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00900 %
00901 %   Method MACSystemCommand executes the specified command and waits until it
00902 %   terminates.  The returned value is the exit status of the command.
00903 %
00904 %  The format of the MACSystemCommand method is:
00905 %
00906 %      int MACSystemCommand(MagickFalse,const char * command)
00907 %
00908 %  A description of each parameter follows:
00909 %
00910 %    o command: This string is the command to execute.
00911 %
00912 */
00913 MagickExport int MACSystemCommand(const char * command)
00914 {
00915   /*
00916     We only know how to launch Ghostscript.
00917   */
00918   if (MacGSLaunchApplicationToFront())
00919     return(-1);
00920   return(MacGSExecuteCommand(command,strlen(command)));
00921 }
00922 
00923 /*
00924 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00925 %                                                                             %
00926 %                                                                             %
00927 %                                                                             %
00928 %   M A C W a r n i n g H a n d l e r                                         %
00929 %                                                                             %
00930 %                                                                             %
00931 %                                                                             %
00932 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00933 %
00934 %  MACWarningHandler() displays a warning reason.
00935 %
00936 %  The format of the MACWarningHandler method is:
00937 %
00938 +      void MACWarningHandler(const ExceptionType warning,const char *reason,
00939 %        const char *description)
00940 %
00941 %  A description of each parameter follows:
00942 %
00943 %    o warning: Specifies the numeric warning category.
00944 %
00945 %    o reason: Specifies the reason to display before terminating the
00946 %      program.
00947 %
00948 %    o description: Specifies any description to the reason.
00949 %
00950 %
00951 */
00952 MagickExport void MACWarningHandler(const ExceptionType warning,
00953   const char *reason,const char *description)
00954 {
00955   char
00956     buffer[1664];
00957 
00958   if (reason == (char *) NULL)
00959     return;
00960   if (description == (char *) NULL)
00961     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s.\n",GetClientName(),
00962       reason);
00963   else
00964     (void) FormatLocaleString(buffer,MaxTextExtent,"%s: %s (%s).\n",
00965       GetClientName(),reason,description);
00966 #if defined(DISABLE_SIOUX)
00967   if(exception.hook != (MACErrorHookPtr) NULL)
00968     exception.hook(warning, buffer);
00969 #else
00970   (void)warning;
00971   puts(buffer);
00972 #endif
00973 }
00974 
00975 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
00976 /*
00977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00978 %                                                                             %
00979 %                                                                             %
00980 %                                                                             %
00981 %   o p e n d i r                                                             %
00982 %                                                                             %
00983 %                                                                             %
00984 %                                                                             %
00985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00986 %
00987 %  opendir() opens the directory named by filename and associates a directory
00988 %  stream with it.
00989 %
00990 %  The format of the opendir method is:
00991 %
00992 %      MagickExport DIR *opendir(char *path)
00993 %
00994 %  A description of each parameter follows:
00995 %
00996 %    o entry: Specifies a pointer to a DIR structure.
00997 %
00998 %
00999 */
01000 MagickExport DIR *opendir(const char *path)
01001 {
01002   Str255 pathname;
01003 
01004   CInfoPBRec
01005     search_info;
01006 
01007   DIR
01008     *entry;
01009 
01010   int
01011     error;
01012 
01013   search_info.hFileInfo.ioNamePtr=0;
01014   if ((path != (char *) NULL) || (*path != '\0'))
01015     if ((path[0] != '.') || (path[1] != '\0'))
01016       {
01017         c2pstrcpy(pathname,path);
01018         search_info.hFileInfo.ioNamePtr=pathname;
01019       }
01020   search_info.hFileInfo.ioCompletion=0;
01021   search_info.hFileInfo.ioVRefNum=0;
01022   search_info.hFileInfo.ioFDirIndex=0;
01023   search_info.hFileInfo.ioDirID=0;
01024   error=PBGetCatInfoSync(&search_info);
01025   if (error != noErr)
01026     {
01027       errno=error;
01028       return((DIR *) NULL);
01029     }
01030   entry=(DIR *) AcquireMagickMemory(sizeof(DIR));
01031   if (entry == (DIR *) NULL)
01032     return((DIR *) NULL);
01033   entry->d_VRefNum=search_info.hFileInfo.ioVRefNum;
01034   entry->d_DirID=search_info.hFileInfo.ioDirID;
01035   entry->d_index=1;
01036   return(entry);
01037 }
01038 #endif
01039 
01040 /*
01041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01042 %                                                                             %
01043 %                                                                             %
01044 %                                                                             %
01045 %   P r o c e s s P e n d i n g E v e n t s                                   %
01046 %                                                                             %
01047 %                                                                             %
01048 %                                                                             %
01049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01050 %
01051 %  ProcessPendingEvents() processes any pending events.  This prevents
01052 %  ImageMagick from monopolizing the processor.
01053 %
01054 %  The format of the ProcessPendingEvents method is:
01055 %
01056 %      ProcessPendingEvents(text)
01057 %
01058 %  A description of each parameter follows:
01059 %
01060 %    o text: A character string representing the current process.
01061 %
01062 %
01063 */
01064 MagickExport void ProcessPendingEvents(const char *text)
01065 {
01066 #if defined(DISABLE_SIOUX)
01067   if (event_hook != (MACEventHookPtr) NULL)
01068     event_hook(text);
01069 #else
01070   static const char
01071     *mark = (char *) NULL;
01072 
01073   EventRecord
01074     event;
01075 
01076   while (WaitNextEvent(everyEvent,&event,0L,nil))
01077     SIOUXHandleOneEvent(&event);
01078   if (isatty(STDIN_FILENO) && (text != mark))
01079     {
01080       (void) puts(text);
01081       mark=text;
01082     }
01083 #endif
01084 }
01085 
01086 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
01087 /*
01088 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01089 %                                                                             %
01090 %                                                                             %
01091 %                                                                             %
01092 %   r e a d d i r                                                             %
01093 %                                                                             %
01094 %                                                                             %
01095 %                                                                             %
01096 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01097 %
01098 %  readdir() returns a pointer to a structure representing the directory entry
01099 %  at the current position in the directory stream to which entry refers.
01100 %
01101 %  The format of the readdir
01102 %
01103 %      struct dirent *readdir(DIR *entry)
01104 %
01105 %  A description of each parameter follows:
01106 %
01107 %    o entry: Specifies a pointer to a DIR structure.
01108 %
01109 %
01110 */
01111 MagickExport struct dirent *readdir(DIR *entry)
01112 {
01113   CInfoPBRec
01114     search_info;
01115 
01116   int
01117     error;
01118 
01119   static struct dirent
01120     dir_entry;
01121 
01122   static unsigned char
01123     pathname[MaxTextExtent];
01124 
01125   if (entry == (DIR *) NULL)
01126     return((struct dirent *) NULL);
01127   search_info.hFileInfo.ioCompletion=0;
01128   search_info.hFileInfo.ioNamePtr=pathname;
01129   search_info.hFileInfo.ioVRefNum=0;
01130   search_info.hFileInfo.ioFDirIndex=entry->d_index;
01131   search_info.hFileInfo.ioDirID=entry->d_DirID;
01132   error=PBGetCatInfoSync(&search_info);
01133   if (error != noErr)
01134     {
01135       errno=error;
01136       return((struct dirent *) NULL);
01137     }
01138   entry->d_index++;
01139   p2cstrcpy(dir_entry.d_name,search_info.hFileInfo.ioNamePtr);
01140   dir_entry.d_namlen=strlen(dir_entry.d_name);
01141   return(&dir_entry);
01142 }
01143 #endif
01144 
01145 /*
01146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01147 %                                                                             %
01148 %                                                                             %
01149 %                                                                             %
01150 %  R e a d P I C T I m a g e                                                  %
01151 %                                                                             %
01152 %                                                                             %
01153 %                                                                             %
01154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01155 %
01156 %  ReadPICTImage() reads an Apple Macintosh QuickDraw/PICT image file using
01157 %  MacOS QuickDraw methods and returns it.  It allocates the memory necessary
01158 %  for the new Image structure and returns a pointer to the new image.
01159 %
01160 %  This method was written and contributed by spd@daphne.cps.unizar.es
01161 %  (feel free to copy and use it as you want. No warranty).
01162 %
01163 %  The format of the ReadPICTImage method is:
01164 %
01165 %      Image *ReadPICTImage(const ImageInfo *image_info,
01166 %        ExceptionInfo *exception)
01167 %
01168 %  A description of each parameter follows:
01169 %
01170 %    o image:  Method ReadPICTImage returns a pointer to the image after
01171 %      reading.  A null image is returned if there is a memory shortage or
01172 %      if the image cannot be read.
01173 %
01174 %    o image_info: the image info..
01175 %
01176 %    o exception: return any errors or warnings in this structure.
01177 %
01178 */
01179 
01180 static inline size_t MagickMax(const size_t x,const size_t y)
01181 {
01182   if (x > y)
01183     return(x);
01184   return(y);
01185 }
01186 
01187 MagickExport Image *ReadPICTImage(const ImageInfo *image_info,
01188   ExceptionInfo *exception)
01189 {
01190 #define PICTHeaderSize    512
01191 
01192   CodecType
01193     codec;
01194 
01195   GDHandle
01196     device;
01197 
01198   GWorldPtr
01199     graphic_world,
01200     port;
01201 
01202   Image
01203     *image;
01204 
01205   int
01206     depth,
01207     status;
01208 
01209   MagickBooleanType
01210     proceed,
01211     status;
01212 
01213   PicHandle
01214     picture_handle;
01215 
01216   PictInfo
01217     picture_info;
01218 
01219   QDErr
01220     theErr = noErr;
01221 
01222   Rect
01223     rectangle;
01224 
01225   RGBColor
01226     Pixel;
01227 
01228   short
01229     colormap_id;
01230 
01231   ssize_t
01232     y;
01233 
01234   /*
01235     Open image file.
01236   */
01237   image=AcquireImage(image_info,exception);
01238   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
01239   if (status == MagickFalse)
01240     return(NULL);
01241   picture_handle=(PicHandle) NewHandle(MagickMax(GetBlobSize(image)-
01242     PICTHeaderSize,PICTHeaderSize));
01243   if (picture_handle == nil)
01244     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
01245   HLock((Handle) picture_handle);
01246   (void) ReadBlob(image,PICTHeaderSize,*(unsigned char **) picture_handle);
01247   status=ReadBlob(image,GetBlobSize(image)-PICTHeaderSize,*(unsigned char **)
01248     picture_handle);
01249   if (status == MagickFalse)
01250     {
01251       DisposeHandle((Handle) picture_handle);
01252       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
01253     }
01254   GetGWorld(&port,&device);
01255   theErr=NewGWorld(&graphic_world,0,&(**picture_handle).picFrame,nil,nil,
01256     useTempMem | keepLocal);
01257   if ((theErr != noErr) && (graphic_world == nil))
01258     {
01259       DisposeHandle((Handle) picture_handle);
01260       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
01261     }
01262   HUnlock((Handle) picture_handle);
01263   SetGWorld(graphic_world,nil);
01264   theErr=GetPictInfo(picture_handle,&picture_info,0,1,systemMethod,0);
01265   if (theErr != noErr)
01266     {
01267       DisposeGWorld(graphic_world);
01268       DisposeHandle((Handle) picture_handle);
01269       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
01270     }
01271 #if defined(DISABLE_QUICKTIME)
01272   codec='unkn';
01273   colormap_id=(-1);
01274   depth=picture_info.depth;
01275 #else
01276   BottleneckTest(picture_handle,&codec,&depth,&colormap_id);
01277 #endif
01278   switch (codec)
01279   {
01280     case 'rpza':
01281     case 'jpeg':
01282     case 'rle ':
01283     case 'raw ':
01284     case 'smc ':
01285     {
01286       if (depth > 200)
01287         {
01288           depth-=32;
01289           picture_info.theColorTable=GetCTable(colormap_id);
01290         }
01291       break;
01292     }
01293     default:
01294     {
01295       depth=picture_info.depth;
01296       if (depth <= 8)
01297         (void) GetPictInfo(picture_handle,&picture_info,returnColorTable,
01298           (short) (1 << picture_info.depth),systemMethod,0);
01299       break;
01300     }
01301   }
01302   image->resolution.x=(picture_info.hRes) >> 16;
01303   image->resolution.y=(picture_info.vRes) >> 16;
01304   image->units=PixelsPerInchResolution;
01305   image->columns=picture_info.sourceRect.right-picture_info.sourceRect.left;
01306   image->rows=picture_info.sourceRect.bottom-picture_info.sourceRect.top;
01307   if ((depth <= 8) && ((*(picture_info.theColorTable))->ctSize != 0))
01308     {
01309       size_t
01310         number_colors;
01311 
01312       /*
01313         Colormapped PICT image.
01314       */
01315       number_colors=(*(picture_info.theColorTable))->ctSize;
01316       if (!AcquireImageColormap(image,number_colors))
01317         {
01318           if (picture_info.theColorTable != nil)
01319             DisposeHandle((Handle) picture_info.theColorTable);
01320           DisposeGWorld(graphic_world);
01321           DisposeHandle((Handle) picture_handle);
01322           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
01323         }
01324       for (x=0; x < image->colors; x++)
01325       {
01326         image->colormap[x].red=
01327           (*(picture_info.theColorTable))->ctTable[x].rgb.red;
01328         image->colormap[x].green=
01329           (*(picture_info.theColorTable))->ctTable[x].rgb.green;
01330         image->colormap[x].blue=
01331           (*(picture_info.theColorTable))->ctTable[x].rgb.blue;
01332       }
01333     }
01334   SetRect(&rectangle,0,0,image->columns,image->rows);
01335   (void) UpdateGWorld(&graphic_world,depth,&rectangle,
01336     picture_info.theColorTable,nil,0);
01337   LockPixels(GetGWorldPixMap(graphic_world));  /*->portPixMap); */
01338   EraseRect(&rectangle);
01339   DrawPicture(picture_handle,&rectangle);
01340   if ((depth <= 8) && (colormap_id == -1))
01341     {
01342       DisposeHandle((Handle) picture_info.theColorTable);
01343       picture_info.theColorTable=nil;
01344     }
01345   DisposeHandle((Handle) picture_handle);
01346   /*
01347     Convert PICT pixels to pixel packets.
01348   */
01349   for (y=0; y < image->rows; y++)
01350   {
01351     register ssize_t
01352       x;
01353 
01354     register Quantum
01355       *restrict q;
01356 
01357     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
01358     if (q == (Quantum *) NULL)
01359       break;
01360     for (x=0; x < image->columns; x++)
01361     {
01362       GetCPixel(x,y,&Pixel);
01363       SetPixelRed(image,ScaleCharToQuantum(Pixel.red & 0xff),q);
01364       SetPixelGreen(image,ScaleCharToQuantum(Pixel.green & 0xff),q);
01365       SetPixelBlue(image,ScaleCharToQuantum(Pixel.blue & 0xff),q);
01366       if (image->storage_class == PseudoClass)
01367         SetPixelIndex(image,Color2Index(&Pixel),q);
01368       q+=GetPixelChannels(image);
01369     }
01370     if (SyncAuthenticPixels(image,exception) == MagickFalse)
01371       break;
01372     proceed=SetImageProgress(image,LoadImageTag,y,image->rows);
01373     if (proceed == MagickFalse)
01374       break;
01375   }
01376   UnlockPixels(GetGWorldPixMap(graphic_world));
01377   SetGWorld(port,device);
01378   if (picture_info.theColorTable != nil)
01379     DisposeHandle((Handle) picture_info.theColorTable);
01380   DisposeGWorld(graphic_world);
01381   (void) CloseBlob(image);
01382   return(image);
01383 }
01384 
01385 /*
01386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01387 %                                                                             %
01388 %                                                                             %
01389 %                                                                             %
01390 %   S e a r c h F o r F i l e                                                 %
01391 %                                                                             %
01392 %                                                                             %
01393 %                                                                             %
01394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01395 %
01396 %  SearchForFile() searches for a file.
01397 %
01398 %
01399 */
01400 static Boolean SearchForFile(OSType creator_type,OSType file_type,FSSpec *file,
01401   short count)
01402 {
01403   char
01404     *buffer;
01405 
01406   CInfoPBRec
01407     search1_info,
01408     search2_info;
01409 
01410   FSSpec
01411     application;
01412 
01413   HParamBlockRec
01414     parameter_info;
01415 
01416   OSErr
01417     error;
01418 
01419   ProcessInfoRec
01420     application_info;
01421 
01422   ProcessSerialNumber
01423     serial_number;
01424 
01425   ssize_t
01426     buffer_size = 16384;
01427 
01428   serial_number.lowLongOfPSN=kCurrentProcess;
01429   serial_number.highLongOfPSN=0;
01430   application_info.processInfoLength=sizeof(ProcessInfoRec);
01431   application_info.processName=NULL;
01432   application_info.processAppSpec=(&application);
01433   GetProcessInformation(&serial_number,&application_info);
01434   buffer=NewPtr(buffer_size);
01435   if (buffer == (char *) NULL)
01436     return(false);
01437   parameter_info.csParam.ioCompletion=NULL;
01438   parameter_info.csParam.ioNamePtr=NULL;
01439   parameter_info.csParam.ioVRefNum=application.vRefNum;
01440   parameter_info.csParam.ioMatchPtr=file;
01441   parameter_info.csParam.ioReqMatchCount=count;
01442   parameter_info.csParam.ioSearchBits=fsSBFlFndrInfo;
01443   parameter_info.csParam.ioSearchInfo1=&search1_info;
01444   parameter_info.csParam.ioSearchInfo2=&search2_info;
01445   parameter_info.csParam.ioSearchTime=0;
01446   parameter_info.csParam.ioCatPosition.initialize=0;
01447   parameter_info.csParam.ioOptBuffer=buffer;
01448   parameter_info.csParam.ioOptBufSize=buffer_size;
01449   search1_info.hFileInfo.ioNamePtr=NULL;
01450   search1_info.hFileInfo.ioFlFndrInfo.fdType=file_type;
01451   search1_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
01452   search1_info.hFileInfo.ioFlAttrib=0;
01453   search1_info.hFileInfo.ioFlParID=0;
01454   search2_info=search1_info;
01455   search2_info.hFileInfo.ioFlAttrib=0x10;
01456   search2_info.hFileInfo.ioFlFndrInfo.fdCreator=creator_type;
01457   search2_info.hFileInfo.ioFlFndrInfo.fdType=(-1);
01458   search2_info.hFileInfo.ioFlFndrInfo.fdFlags=0;
01459   search2_info.hFileInfo.ioFlFndrInfo.fdLocation.h=0;
01460   search2_info.hFileInfo.ioFlFndrInfo.fdLocation.v=0;
01461   search2_info.hFileInfo.ioFlFndrInfo.fdFldr=0;
01462   search2_info.hFileInfo.ioFlParID=0;
01463   error=PBCatSearchSync((CSParamPtr) &parameter_info);
01464   DisposePtr(buffer);
01465   if (parameter_info.csParam.ioReqMatchCount ==
01466       parameter_info.csParam.ioActMatchCount)
01467     error=eofErr;
01468   if (parameter_info.csParam.ioActMatchCount == 0)
01469     error=0;
01470   return(error == eofErr);
01471 }
01472 
01473 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
01474 /*
01475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01476 %                                                                             %
01477 %                                                                             %
01478 %                                                                             %
01479 %   s e e k d i r                                                             %
01480 %                                                                             %
01481 %                                                                             %
01482 %                                                                             %
01483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01484 %
01485 %  seekdir() sets the position of the next readdir() operation on the directory
01486 %  stream.
01487 %
01488 %  The format of the seekdir method is:
01489 %
01490 %      void seekdir(DIR *entry,ssize_t position)
01491 %
01492 %  A description of each parameter follows:
01493 %
01494 %    o entry: Specifies a pointer to a DIR structure.
01495 %
01496 %    o position: specifies the position associated with the directory
01497 %      stream.
01498 %
01499 %
01500 %
01501 */
01502 MagickExport void seekdir(DIR *entry,ssize_t position)
01503 {
01504   assert(entry != (DIR *) NULL);
01505   entry->d_index=position;
01506 }
01507 #endif
01508 
01509 /*
01510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01511 %                                                                             %
01512 %                                                                             %
01513 %                                                                             %
01514 %   S e t A p p l i c a t i o n T y p e                                       %
01515 %                                                                             %
01516 %                                                                             %
01517 %                                                                             %
01518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01519 %
01520 %  SetApplicationType() sets the file type of an image.
01521 %
01522 %  The format of the SetApplicationType method is:
01523 %
01524 %      void SetApplicationType(const char *filename,const char *magick,
01525 %        OSType application)
01526 %
01527 %  A description of each parameter follows:
01528 %
01529 %    o filename: Specifies the name of the file.
01530 %
01531 %    o filename: Specifies the file type.
01532 %
01533 %    o application: Specifies the type of the application.
01534 %
01535 */
01536 
01537 static inline size_t MagickMin(const size_t x,const size_t y)
01538 {
01539   if (x < y)
01540     return(x);
01541   return(y);
01542 }
01543 
01544 MagickExport void SetApplicationType(const char *filename,const char *magick,
01545   OSType application)
01546 {
01547   FSSpec
01548     file_specification;
01549 
01550   OSType
01551     filetype;
01552 
01553   Str255
01554     name;
01555 
01556   assert(filename != (char *) NULL);
01557   if (image->debug != MagickFalse)
01558     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
01559   assert(magick != (const char *) NULL);
01560   filetype='    ';
01561   (void) CopyMagickString((char *) &filetype,magick,MagickMin(strlen(magick),
01562     4));
01563   if (LocaleCompare(magick,"JPG") == 0)
01564     (void) CopyMagickString((char *) &filetype,"JPEG",MaxTextExtent);
01565   c2pstrcpy(name,filename);
01566   FSMakeFSSpec(0,0,name,&file_specification);
01567   FSpCreate(&file_specification,application,filetype,smSystemScript);
01568 }
01569 
01570 #if !defined(_MAGICKCORE_POSIX_SUPPORT_VERSION)
01571 /*
01572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01573 %                                                                             %
01574 %                                                                             %
01575 %                                                                             %
01576 %   t e l l d i r                                                             %
01577 %                                                                             %
01578 %                                                                             %
01579 %                                                                             %
01580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01581 %
01582 %   Method telldir returns the current location associated  with  the
01583 %   named directory stream.
01584 %
01585 %  The format of the telldir method is:
01586 %
01587 %      telldir(DIR *entry)
01588 %
01589 %  A description of each parameter follows:
01590 %
01591 %    o entry: Specifies a pointer to a DIR structure.
01592 %
01593 %
01594 */
01595 MagickExport ssize_t telldir(DIR *entry)
01596 {
01597   return(entry->d_index);
01598 }
01599 #endif
01600 
01601 #endif