]> granicus.if.org Git - imagemagick/blobdiff - magick/utility.c
(no commit message)
[imagemagick] / magick / utility.c
index 2a010ff907b817587f0312f4d41887c6a2380ee8..f1a350baa0d075651c728e0fad3c77312abef1a8 100644 (file)
@@ -266,6 +266,7 @@ MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
 MagickExport void AppendImageFormat(const char *format,char *filename)
 {
   char
+    extension[MaxTextExtent],
     root[MaxTextExtent];
 
   assert(format != (char *) NULL);
@@ -282,6 +283,20 @@ MagickExport void AppendImageFormat(const char *format,char *filename)
       (void) CopyMagickString(filename,message,MaxTextExtent);
       return;
     }
+  GetPathComponent(filename,ExtensionPath,extension);
+  if ((LocaleCompare(extension,"Z") == 0) ||
+      (LocaleCompare(extension,"bz2") == 0) ||
+      (LocaleCompare(extension,"gz") == 0) ||
+      (LocaleCompare(extension,"wmz") == 0) ||
+      (LocaleCompare(extension,"svgz") == 0))
+    {
+      GetPathComponent(filename,RootPath,root);
+      (void) CopyMagickString(filename,root,MaxTextExtent);
+      GetPathComponent(filename,RootPath,root);
+      (void) FormatMagickString(filename,MaxTextExtent,"%s.%s.%s",root,format,
+        extension);
+      return;
+    }
   GetPathComponent(filename,RootPath,root);
   (void) FormatMagickString(filename,MaxTextExtent,"%s.%s",root,format);
 }
@@ -500,7 +515,7 @@ MagickExport char *Base64Encode(const unsigned char *blob,
   remainder=blob_length % 3;
   if (remainder != 0)
     {
-      long
+      ssize_t
         j;
 
       unsigned char
@@ -509,7 +524,7 @@ MagickExport char *Base64Encode(const unsigned char *blob,
       code[0]='\0';
       code[1]='\0';
       code[2]='\0';
-      for (j=0; j < (long) remainder; j++)
+      for (j=0; j < (ssize_t) remainder; j++)
         code[j]=(*p++);
       encode[i++]=Base64[(int) (code[0] >> 2)];
       encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
@@ -540,7 +555,7 @@ MagickExport char *Base64Encode(const unsigned char *blob,
 %
 %  The format of the ChopPathComponents method is:
 %
-%      ChopPathComponents(char *path,unsigned long components)
+%      ChopPathComponents(char *path,size_t components)
 %
 %  A description of each parameter follows:
 %
@@ -549,12 +564,12 @@ MagickExport char *Base64Encode(const unsigned char *blob,
 %    o components:  The number of components to chop.
 %
 */
-MagickExport void ChopPathComponents(char *path,const unsigned long components)
+MagickExport void ChopPathComponents(char *path,const size_t components)
 {
-  register long
+  register ssize_t
     i;
 
-  for (i=0; i < (long) components; i++)
+  for (i=0; i < (ssize_t) components; i++)
     GetPathComponent(path,HeadPath,path);
 }
 \f
@@ -680,15 +695,15 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
     home_directory[MaxTextExtent],
     **vector;
 
-  long
+  ssize_t
     count,
     parameters;
 
-  register long
+  register ssize_t
     i,
     j;
 
-  unsigned long
+  size_t
     number_files;
 
   /*
@@ -706,7 +721,7 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
   */
   *home_directory='\0';
   count=0;
-  for (i=0; i < (long) *number_arguments; i++)
+  for (i=0; i < (ssize_t) *number_arguments; i++)
   {
     char
       **filelist,
@@ -735,7 +750,7 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
         for (j=0; j < parameters; j++)
         {
           i++;
-          if (i == (long) *number_arguments)
+          if (i == (ssize_t) *number_arguments)
             break;
           option=(*arguments)[i];
           vector[count++]=ConstantString(option);
@@ -774,7 +789,7 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
           *exception;
 
         int
-          number_images;
+          length;
 
         /*
           Generate file list from file list (e.g. @filelist.txt).
@@ -785,24 +800,23 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
         if (files == (char *) NULL)
           continue;
         StripString(files);
-        filelist=StringToArgv(files,&number_images);
+        filelist=StringToArgv(files,&length);
+        if (filelist == (char **) NULL)
+          continue;
         files=DestroyString(files);
-        number_files=(unsigned long) number_images;
-        if (filelist != (char **) NULL)
-          {
-            number_files--;
-            for (j=0; j < (long) number_files; j++)
-              filelist[j]=filelist[j+1];
-          }
+        filelist[0]=DestroyString(filelist[0]);
+        for (j=0; j < (ssize_t) (length-1); j++)
+          filelist[j]=filelist[j+1];
+        number_files=(size_t) length-1;
       }
     if (filelist == (char **) NULL)
       continue;
-    for (j=0; j < (long) number_files; j++)
+    for (j=0; j < (ssize_t) number_files; j++)
       if (IsPathDirectory(filelist[j]) <= 0)
         break;
-    if (j == (long) number_files)
+    if (j == (ssize_t) number_files)
       {
-        for (j=0; j < (long) number_files; j++)
+        for (j=0; j < (ssize_t) number_files; j++)
           filelist[j]=DestroyString(filelist[j]);
         filelist=(char **) RelinquishMagickMemory(filelist);
         continue;
@@ -814,17 +828,38 @@ MagickExport MagickBooleanType ExpandFilenames(int *number_arguments,
       count+number_files+1,sizeof(*vector));
     if (vector == (char **) NULL)
       return(MagickFalse);
-    for (j=0; j < (long) number_files; j++)
+    for (j=0; j < (ssize_t) number_files; j++)
     {
+      option=filelist[j];
+      parameters=ParseMagickOption(MagickCommandOptions,MagickFalse,option);
+      if (parameters > 0)
+        {
+          ssize_t
+            k;
+
+          /*
+            Do not expand command option parameters.
+          */
+          vector[count++]=ConstantString(option);
+          for (k=0; k < parameters; k++)
+          {
+            j++;
+            if (j == (ssize_t) number_files)
+              break;
+            option=filelist[j];
+            vector[count++]=ConstantString(option);
+          }
+          continue;
+        }
       (void) CopyMagickString(filename,path,MaxTextExtent);
       if (*path != '\0')
         (void) ConcatenateMagickString(filename,DirectorySeparator,
           MaxTextExtent);
       (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
       filelist[j]=DestroyString(filelist[j]);
-      if (strlen(filename) >= MaxTextExtent)
+      if (strlen(filename) >= (MaxTextExtent-1))
         ThrowFatalException(OptionFatalError,"FilenameTruncated");
-      if (IsPathDirectory(filename) == 0)
+      if (IsPathDirectory(filename) <= 0)
         {
           char
             path[MaxTextExtent];
@@ -918,13 +953,13 @@ MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
     ssize_t
       count;
 
-    (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/exe",
-      (long) getpid());
+    (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%.20g/exe",
+      (double) getpid());
     count=readlink(link_path,execution_path,PATH_MAX);
     if (count == -1)
       {
-        (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%ld/file",
-          (long) getpid());
+        (void) FormatMagickString(link_path,MaxTextExtent,"/proc/%.20g/file",
+          (double) getpid());
         count=readlink(link_path,execution_path,PATH_MAX);
       }
     if ((count > 0) && (count <= (ssize_t) PATH_MAX))
@@ -963,7 +998,7 @@ MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
       }
   }
 #endif
-#if defined(__WINDOWS__)
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
   NTGetExecutionPath(path,extent);
 #endif
 #if defined(__GNU__)
@@ -972,7 +1007,7 @@ MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
       *program_name,
       *execution_path;
 
-    long
+    ssize_t
       count;
 
     count=0;
@@ -1020,22 +1055,22 @@ MagickExport MagickBooleanType GetExecutionPath(char *path,const size_t extent)
 %
 %  The format of the GetMagickPageSize method is:
 %
-%      long GetMagickPageSize()
+%      ssize_t GetMagickPageSize()
 %
 */
-MagickExport long GetMagickPageSize(void)
+MagickExport ssize_t GetMagickPageSize(void)
 {
-  static long
+  static ssize_t
     page_size = -1;
 
   if (page_size > 0)
     return(page_size);
 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGE_SIZE)
-  page_size=sysconf(_SC_PAGE_SIZE);
-#endif
+  page_size=(ssize_t) sysconf(_SC_PAGE_SIZE);
+#else
 #if defined(MAGICKCORE_HAVE_GETPAGESIZE)
-  if (page_size <= 0)
-    page_size=getpagesize();
+  page_size=(ssize_t) getpagesize();
+#endif
 #endif
   if (page_size <= 0)
     page_size=16384;
@@ -1162,17 +1197,17 @@ static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
   length=UTF8ToUTF16(source,(wchar_t *) NULL);
   if (length == 0)
     {
-      register long
+      register ssize_t
         i;
 
       /*
         Not UTF-8, just copy.
       */
-      length=strlen(source);
+      length=strlen((const char *) source);
       utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
       if (utf16 == (wchar_t *) NULL)
         return((wchar_t *) NULL);
-      for (i=0; i <= (long) length; i++)
+      for (i=0; i <= (ssize_t) length; i++)
         utf16[i]=source[i];
       return(utf16);
     }
@@ -1202,7 +1237,7 @@ MagickExport MagickBooleanType GetPathAttributes(const char *path,
     wchar_t
       *unicode_path;
 
-    unicode_path=ConvertUTF8ToUTF16(path);
+    unicode_path=ConvertUTF8ToUTF16((const unsigned char *) path);
     if (unicode_path == (wchar_t *) NULL)
       return(MagickFalse);
     status=wstat(unicode_path,(struct stat *) attributes) == 0 ? MagickTrue :
@@ -1266,6 +1301,16 @@ MagickExport void GetPathComponent(const char *path,PathType type,
   if (path[1] != ":")
 #endif
   for (p=component; *p != '\0'; p++)
+  {
+    if ((*p == '%') && (*(p+1) == '['))
+      {
+        /*
+          Skip over %[...].
+        */
+        for (p++; (*p != ']') && (*p != '\0'); p++) ;
+        if (*p == '\0')
+          break;
+      }
     if ((*p == ':') && (IsPathDirectory(path) < 0) &&
         (IsPathAccessible(path) == MagickFalse))
       {
@@ -1280,6 +1325,7 @@ MagickExport void GetPathComponent(const char *path,PathType type,
             *q=(*++p);
         break;
       }
+  }
   *subimage='\0';
   p=component;
   if (*p != '\0')
@@ -1394,7 +1440,7 @@ MagickExport void GetPathComponent(const char *path,PathType type,
 %  The format of the GetPathComponents method is:
 %
 %      char **GetPathComponents(const char *path,
-%        unsigned long *number_componenets)
+%        size_t *number_componenets)
 %
 %  A description of each parameter follows:
 %
@@ -1404,7 +1450,7 @@ MagickExport void GetPathComponent(const char *path,PathType type,
 %
 */
 MagickExport char **GetPathComponents(const char *path,
-  unsigned long *number_components)
+  size_t *number_components)
 {
   char
     **components;
@@ -1413,7 +1459,7 @@ MagickExport char **GetPathComponents(const char *path,
     *p,
     *q;
 
-  register long
+  register ssize_t
     i;
 
   if (path == (char *) NULL)
@@ -1427,7 +1473,7 @@ MagickExport char **GetPathComponents(const char *path,
   if (components == (char **) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   p=path;
-  for (i=0; i < (long) *number_components; i++)
+  for (i=0; i < (ssize_t) *number_components; i++)
   {
     for (q=p; *q != '\0'; q++)
       if (IsBasenameSeparator(*q))
@@ -1585,7 +1631,7 @@ MagickExport MagickBooleanType IsMagickTrue(const char *value)
 %  The format of the ListFiles function is:
 %
 %      char **ListFiles(const char *directory,const char *pattern,
-%        long *number_entries)
+%        ssize_t *number_entries)
 %
 %  A description of each parameter follows:
 %
@@ -1636,7 +1682,7 @@ static inline int MagickReadDirectory(DIR *directory,struct dirent *entry,
 }
 
 MagickExport char **ListFiles(const char *directory,const char *pattern,
-  unsigned long *number_entries)
+  size_t *number_entries)
 {
   char
     **filelist;
@@ -1648,7 +1694,7 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
     *buffer,
     *entry;
 
-  unsigned long
+  size_t
     max_entries;
 
   /*
@@ -1657,7 +1703,7 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
   assert(directory != (const char *) NULL);
   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",directory);
   assert(pattern != (const char *) NULL);
-  assert(number_entries != (unsigned long *) NULL);
+  assert(number_entries != (size_t *) NULL);
   *number_entries=0;
   current_directory=opendir(directory);
   if (current_directory == (DIR *) NULL)
@@ -1676,7 +1722,8 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
   /*
     Save the current and change to the new directory.
   */
-  buffer=(struct dirent *) AcquireAlignedMemory(1,sizeof(*buffer)+FILENAME_MAX+1);
+  buffer=(struct dirent *) AcquireAlignedMemory(1,sizeof(*buffer)+
+    FILENAME_MAX+1);
   if (buffer == (struct dirent *) NULL)
     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
   while ((MagickReadDirectory(current_directory,buffer,&entry) == 0) &&
@@ -1685,7 +1732,7 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
     if (*entry->d_name == '.')
       continue;
     if ((IsPathDirectory(entry->d_name) > 0) ||
-#if defined(__WINDOWS__)
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
         (GlobExpression(entry->d_name,pattern,MagickTrue) != MagickFalse))
 #else
         (GlobExpression(entry->d_name,pattern,MagickFalse) != MagickFalse))
@@ -1716,9 +1763,6 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
         }
 #endif
         filelist[*number_entries]=(char *) AcquireString(entry->d_name);
-        if (IsPathDirectory(entry->d_name) > 0)
-          (void) ConcatenateMagickString(filelist[*number_entries],
-            DirectorySeparator,MaxTextExtent);
         (*number_entries)++;
       }
   }
@@ -1739,6 +1783,73 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
 %                                                                             %
 %                                                                             %
 %                                                                             %
+%   M a g i c k D e l a y                                                     %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  MagickDelay() suspends program execution for the number of milliseconds
+%  specified.
+%
+%  The format of the Delay method is:
+%
+%      void MagickDelay(const MagickSizeType milliseconds)
+%
+%  A description of each parameter follows:
+%
+%    o milliseconds: Specifies the number of milliseconds to delay before
+%      returning.
+%
+*/
+MagickExport void MagickDelay(const MagickSizeType milliseconds)
+{
+  if (milliseconds == 0)
+    return;
+#if defined(MAGICKCORE_HAVE_NANOSLEEP)
+  {
+    struct timespec
+      timer;
+
+    timer.tv_sec=(time_t) (milliseconds/1000);
+    timer.tv_nsec=(milliseconds % 1000)*1000*1000;
+    (void) nanosleep(&timer,(struct timespec *) NULL);
+  }
+#elif defined(MAGICKCORE_HAVE_USLEEP)
+  usleep(1000*milliseconds);
+#elif defined(MAGICKCORE_HAVE_SELECT)
+  {
+    struct timeval
+      timer;
+
+    timer.tv_sec=(long) milliseconds/1000;
+    timer.tv_usec=(long) (milliseconds % 1000)*1000;
+    (void) select(0,(XFD_SET *) NULL,(XFD_SET *) NULL,(XFD_SET *) NULL,&timer);
+  }
+#elif defined(MAGICKCORE_HAVE_POLL)
+  (void) poll((struct pollfd *) NULL,0,(int) milliseconds);
+#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
+  Sleep((long) milliseconds);
+#elif defined(vms)
+  {
+    float
+      timer;
+
+    timer=milliseconds/1000.0;
+    lib$wait(&timer);
+  }
+#elif defined(__BEOS__)
+  snooze(1000*milliseconds);
+#else
+# error "Time delay method not defined."
+#endif
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
 %  M u l t i l i n e C e n s u s                                              %
 %                                                                             %
 %                                                                             %
@@ -1750,7 +1861,7 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
 %
 %  The format of the MultilineCenus method is:
 %
-%      unsigned long MultilineCensus(const char *label)
+%      size_t MultilineCensus(const char *label)
 %
 %  A description of each parameter follows.
 %
@@ -1758,9 +1869,9 @@ MagickExport char **ListFiles(const char *directory,const char *pattern,
 %
 %
 */
-MagickExport unsigned long MultilineCensus(const char *label)
+MagickExport size_t MultilineCensus(const char *label)
 {
-  unsigned long
+  size_t
     number_lines;
 
   /*
@@ -1816,10 +1927,10 @@ MagickExport FILE *OpenMagickStream(const char *path,const char *mode)
       *unicode_mode,
       *unicode_path;
 
-    unicode_path=ConvertUTF8ToUTF16(path);
+    unicode_path=ConvertUTF8ToUTF16((const unsigned char *) path);
     if (unicode_path == (wchar_t *) NULL)
       return((FILE *) NULL);
-    unicode_mode=ConvertUTF8ToUTF16(mode);
+    unicode_mode=ConvertUTF8ToUTF16((const unsigned char *) mode);
     if (unicode_mode == (wchar_t *) NULL)
       {
         unicode_path=(wchar_t *) RelinquishMagickMemory(unicode_path);
@@ -1885,7 +1996,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
   PolicyRights
     rights;
 
-  register long
+  register ssize_t
     i;
 
   status=(-1);
@@ -1899,7 +2010,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
       errno=EPERM;
       (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
         "NotAuthorized","`%s'",arguments[1]);
-      for (i=0; i < number_arguments; i++)
+      for (i=0; i < (ssize_t) number_arguments; i++)
         arguments[i]=DestroyString(arguments[i]);
       arguments=(char **) RelinquishMagickMemory(arguments);
       return(-1);
@@ -1961,7 +2072,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
           }
     }
 #endif
-#elif defined(__WINDOWS__)
+#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
   {
     int
       mode;
@@ -1969,7 +2080,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
     mode=_P_WAIT;
     if (asynchronous != MagickFalse)
       mode=_P_NOWAIT;
-    status=spawnvp(mode,arguments[1],arguments+1);
+    status=spawnvp(mode,arguments[1],(const char **) (arguments+1));
   }
 #elif defined(macintosh)
   status=MACSystemCommand(shell_command);
@@ -1983,7 +2094,7 @@ MagickExport int SystemCommand(const MagickBooleanType asynchronous,
       "`%s' (%d)",command,status);
   if (shell_command != command)
     shell_command=DestroyString(shell_command);
-  for (i=0; i < number_arguments; i++)
+  for (i=0; i < (ssize_t) number_arguments; i++)
     arguments[i]=DestroyString(arguments[i]);
   arguments=(char **) RelinquishMagickMemory(arguments);
   return(status);