]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/resource.c
Handle short months in png_write_iTIME()
[imagemagick] / MagickCore / resource.c
index e383d30e263b7204fcc067ffbeb1e7dd8e1b8dc4..7b00c1b741d9ddf41b60c5aff77973f709a7f1ac 100644 (file)
 %                               September 2002                                %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 %  obtain a copy of the License at                                            %
 %                                                                             %
-%    http://www.imagemagick.org/script/license.php                            %
+%    https://www.imagemagick.org/script/license.php                           %
 %                                                                             %
 %  Unless required by applicable law or agreed to in writing, software        %
 %  distributed under the License is distributed on an "AS IS" BASIS,          %
 */
 #include "MagickCore/studio.h"
 #include "MagickCore/cache.h"
+#include "MagickCore/cache-private.h"
 #include "MagickCore/configure.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/exception-private.h"
-#include "MagickCore/hashmap.h"
+#include "MagickCore/linked-list.h"
 #include "MagickCore/log.h"
 #include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
 #include "MagickCore/memory_.h"
 #include "MagickCore/nt-base-private.h"
 #include "MagickCore/option.h"
 #include "MagickCore/utility.h"
 #include "MagickCore/utility-private.h"
 \f
+/*
+  Define declarations.
+*/
+#define MagickPathTemplate "XXXXXXXXXXXX"
+\f
 /*
   Typedef declarations.
 */
 typedef struct _ResourceInfo
 {
   MagickOffsetType
+    width,
+    height,
     area,
     memory,
     map,
@@ -81,6 +90,8 @@ typedef struct _ResourceInfo
     time;
 
   MagickSizeType
+    width_limit,
+    height_limit,
     area_limit,
     memory_limit,
     map_limit,
@@ -100,6 +111,8 @@ static RandomInfo
 static ResourceInfo
   resource_info =
   {
+    MagickULLConstant(0),              /* initial width */
+    MagickULLConstant(0),              /* initial height */
     MagickULLConstant(0),              /* initial area */
     MagickULLConstant(0),              /* initial memory */
     MagickULLConstant(0),              /* initial map */
@@ -108,6 +121,8 @@ static ResourceInfo
     MagickULLConstant(0),              /* initial thread */
     MagickULLConstant(0),              /* initial throttle */
     MagickULLConstant(0),              /* initial time */
+    (INT_MAX/(5*sizeof(Quantum))),     /* width limit */
+    (INT_MAX/(5*sizeof(Quantum))),     /* height limit */
     MagickULLConstant(3072)*1024*1024, /* area limit */
     MagickULLConstant(1536)*1024*1024, /* memory limit */
     MagickULLConstant(3072)*1024*1024, /* map limit */
@@ -155,9 +170,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
   const MagickSizeType size)
 {
   char
-    resource_current[MaxTextExtent],
-    resource_limit[MaxTextExtent],
-    resource_request[MaxTextExtent];
+    resource_current[MagickFormatExtent],
+    resource_limit[MagickFormatExtent],
+    resource_request[MagickFormatExtent];
 
   MagickBooleanType
     status;
@@ -166,7 +181,8 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
     limit;
 
   status=MagickFalse;
-  (void) FormatMagickSize(size,MagickFalse,resource_request);
+  (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
+    resource_request);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
     ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
@@ -179,9 +195,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
       status=(resource_info.area_limit == MagickResourceInfinity) ||
         (size < limit) ? MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
-        resource_current);
-      (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
-        resource_limit);
+        "P",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.area_limit,MagickFalse,"P",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case MemoryResource:
@@ -192,9 +208,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.memory < limit) ? MagickTrue :
         MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.memory,MagickTrue,
-        resource_current);
-      (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case MapResource:
@@ -204,9 +220,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
       status=(resource_info.map_limit == MagickResourceInfinity) ||
         ((MagickSizeType) resource_info.map < limit) ? MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
-        resource_current);
-      (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case DiskResource:
@@ -217,9 +233,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.disk < limit) ? MagickTrue :
         MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
-        resource_current);
-      (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case FileResource:
@@ -230,9 +246,21 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.file < limit) ?
         MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
+      break;
+    }
+    case HeightResource:
+    {
+      resource_info.area=(MagickOffsetType) size;
+      limit=resource_info.height_limit;
+      status=(resource_info.area_limit == MagickResourceInfinity) ||
+        (size < limit) ? MagickTrue : MagickFalse;
+      (void) FormatMagickSize((MagickSizeType) resource_info.height,MagickFalse,
+        "P",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.height_limit,MagickFalse,"P",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case ThreadResource:
@@ -242,9 +270,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.thread < limit) ?
         MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     case ThrottleResource:
@@ -254,9 +282,9 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.throttle < limit) ?
         MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
-        MagickFalse,resource_current);
+        MagickFalse,"B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     case TimeResource:
@@ -267,9 +295,21 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         ((MagickSizeType) resource_info.time < limit) ?
         MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
+      break;
+    }
+    case WidthResource:
+    {
+      resource_info.area=(MagickOffsetType) size;
+      limit=resource_info.width_limit;
+      status=(resource_info.area_limit == MagickResourceInfinity) ||
+        (size < limit) ? MagickTrue : MagickFalse;
+      (void) FormatMagickSize((MagickSizeType) resource_info.width,MagickFalse,
+        "P",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.width_limit,MagickFalse,"P",
+        MagickFormatExtent,resource_limit);
       break;
     }
     default:
@@ -368,8 +408,8 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
   struct stat
     attributes;
 
-  (void) FormatLocaleString(path,MaxTextExtent,"magick-%.20gXXXXXXXXXXXX",
-    (double) getpid());
+  (void) FormatLocaleString(path,MagickPathExtent,"magick-%.20g"
+    MagickPathTemplate,(double) getpid());
   exception=AcquireExceptionInfo();
   directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
     exception);
@@ -380,7 +420,7 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
     directory=GetEnvironmentValue("MAGICK_TMPDIR");
   if (directory == (char *) NULL)
     directory=GetEnvironmentValue("TMPDIR");
-#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
+#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
   if (directory == (char *) NULL)
     directory=GetEnvironmentValue("TMP");
   if (directory == (char *) NULL)
@@ -396,10 +436,13 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
 #endif
   if (directory == (char *) NULL)
     return(MagickTrue);
-  value=GetPolicyValue("temporary-path");
+  value=GetPolicyValue("resource:temporary-path");
   if (value != (char *) NULL)
-    (void) CloneString(&directory,value);
-  if (strlen(directory) > (MaxTextExtent-25))
+    {
+      (void) CloneString(&directory,value);
+      value=DestroyString(value);
+    }
+  if (strlen(directory) > (MagickPathExtent-25))
     {
       directory=DestroyString(directory);
       return(MagickFalse);
@@ -411,11 +454,11 @@ MagickExport MagickBooleanType GetPathTemplate(char *path)
       return(MagickFalse);
     }
   if (directory[strlen(directory)-1] == *DirectorySeparator)
-    (void) FormatLocaleString(path,MaxTextExtent,"%smagick-%.20gXXXXXXXXXXXX",
-      directory,(double) getpid());
+    (void) FormatLocaleString(path,MagickPathExtent,
+      "%smagick-%.20g" MagickPathTemplate,directory,(double) getpid());
   else
-    (void) FormatLocaleString(path,MaxTextExtent,
-      "%s%smagick-%.20gXXXXXXXXXXXX",directory,DirectorySeparator,
+    (void) FormatLocaleString(path,MagickPathExtent,
+      "%s%smagick-%.20g" MagickPathTemplate,directory,DirectorySeparator,
       (double) getpid());
   directory=DestroyString(directory);
 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
@@ -467,7 +510,12 @@ MagickExport int AcquireUniqueFileResource(char *path)
   assert(path != (char *) NULL);
   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"...");
   if (random_info == (RandomInfo *) NULL)
-    random_info=AcquireRandomInfo();
+    {
+      LockSemaphoreInfo(resource_semaphore);
+      if (random_info == (RandomInfo *) NULL)
+        random_info=AcquireRandomInfo();
+      UnlockSemaphoreInfo(resource_semaphore);
+    }
   file=(-1);
   for (i=0; i < (ssize_t) TMP_MAX; i++)
   {
@@ -476,7 +524,7 @@ MagickExport int AcquireUniqueFileResource(char *path)
     */
     (void) GetPathTemplate(path);
     key=GetRandomKey(random_info,6);
-    p=path+strlen(path)-12;
+    p=path+strlen(path)-strlen(MagickPathTemplate);
     datum=GetStringInfoDatum(key);
     for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
     {
@@ -486,14 +534,19 @@ MagickExport int AcquireUniqueFileResource(char *path)
     key=DestroyStringInfo(key);
 #if defined(MAGICKCORE_HAVE_MKSTEMP)
     file=mkstemp(path);
+    if (file != -1)
+      {
+#if defined(MAGICKCORE_HAVE_FCHMOD)
+        (void) fchmod(file,0600);
+#endif
 #if defined(__OS2__)
-    setmode(file,O_BINARY);
+        setmode(file,O_BINARY);
 #endif
-    if (file != -1)
-      break;
+        break;
+      }
 #endif
-    key=GetRandomKey(random_info,12);
-    p=path+strlen(path)-12;
+    key=GetRandomKey(random_info,strlen(MagickPathTemplate));
+    p=path+strlen(path)-strlen(MagickPathTemplate);
     datum=GetStringInfoDatum(key);
     for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
     {
@@ -552,6 +605,16 @@ MagickExport MagickSizeType GetMagickResource(const ResourceType type)
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
+    case WidthResource:
+    {
+      resource=(MagickSizeType) resource_info.width;
+      break;
+    }
+    case HeightResource:
+    {
+      resource=(MagickSizeType) resource_info.height;
+      break;
+    }
     case AreaResource:
     {
       resource=(MagickSizeType) resource_info.area;
@@ -632,6 +695,16 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
+    case WidthResource:
+    {
+      resource=resource_info.width_limit;
+      break;
+    }
+    case HeightResource:
+    {
+      resource=resource_info.height_limit;
+      break;
+    }
     case AreaResource:
     {
       resource=resource_info.area_limit;
@@ -708,37 +781,53 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
   ExceptionInfo *magick_unused(exception))
 {
   char
-    area_limit[MaxTextExtent],
-    disk_limit[MaxTextExtent],
-    map_limit[MaxTextExtent],
-    memory_limit[MaxTextExtent],
-    time_limit[MaxTextExtent];
+    area_limit[MagickFormatExtent],
+    disk_limit[MagickFormatExtent],
+    height_limit[MagickFormatExtent],
+    map_limit[MagickFormatExtent],
+    memory_limit[MagickFormatExtent],
+    time_limit[MagickFormatExtent],
+    width_limit[MagickFormatExtent];
+
+  magick_unreferenced(exception);
 
   if (file == (const FILE *) NULL)
     file=stdout;
   if (resource_semaphore == (SemaphoreInfo *) NULL)
     ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
-  (void) FormatMagickSize(resource_info.area_limit,MagickFalse,area_limit);
-  (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
-  (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
-  (void) CopyMagickString(disk_limit,"unlimited",MaxTextExtent);
+  (void) FormatMagickSize(resource_info.width_limit,MagickFalse,"P",
+    MagickFormatExtent,width_limit);
+  (void) FormatMagickSize(resource_info.height_limit,MagickFalse,"P",
+    MagickFormatExtent,height_limit);
+  (void) FormatMagickSize(resource_info.area_limit,MagickFalse,"P",
+    MagickFormatExtent,area_limit);
+  (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
+    MagickFormatExtent,memory_limit);
+  (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
+    MagickFormatExtent,map_limit);
+  (void) CopyMagickString(disk_limit,"unlimited",MagickFormatExtent);
   if (resource_info.disk_limit != MagickResourceInfinity)
-    (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
-  (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
+    (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,"B",
+      MagickFormatExtent,disk_limit);
+  (void) CopyMagickString(time_limit,"unlimited",MagickFormatExtent);
   if (resource_info.time_limit != MagickResourceInfinity)
-    (void) FormatLocaleString(time_limit,MaxTextExtent,"%.20g",(double)
+    (void) FormatLocaleString(time_limit,MagickFormatExtent,"%.20g",(double)
       ((MagickOffsetType) resource_info.time_limit));
-  (void) FormatLocaleFile(file,"  File       Area     Memory        Map"
-    "       Disk   Thread  Throttle       Time\n");
-  (void) FormatLocaleFile(file,
-    "--------------------------------------------------------"
-    "------------------------\n");
-  (void) FormatLocaleFile(file,"%6g %10s %10s %10s %10s %8g  %8g %10s\n",
-    (double) ((MagickOffsetType) resource_info.file_limit),area_limit,
-    memory_limit,map_limit,disk_limit,(double) ((MagickOffsetType)
-    resource_info.thread_limit),(double) ((MagickOffsetType)
-    resource_info.throttle_limit),time_limit);
+  (void) FormatLocaleFile(file,"Resource limits:\n");
+  (void) FormatLocaleFile(file,"  Width: %s\n",width_limit);
+  (void) FormatLocaleFile(file,"  Height: %s\n",height_limit);
+  (void) FormatLocaleFile(file,"  Area: %s\n",area_limit);
+  (void) FormatLocaleFile(file,"  Memory: %s\n",memory_limit);
+  (void) FormatLocaleFile(file,"  Map: %s\n",map_limit);
+  (void) FormatLocaleFile(file,"  Disk: %s\n",disk_limit);
+  (void) FormatLocaleFile(file,"  File: %.20g\n",(double) ((MagickOffsetType)
+    resource_info.file_limit));
+  (void) FormatLocaleFile(file,"  Thread: %.20g\n",(double) ((MagickOffsetType)
+    resource_info.thread_limit));
+  (void) FormatLocaleFile(file,"  Throttle: %.20g\n",(double)
+    ((MagickOffsetType) resource_info.throttle_limit));
+  (void) FormatLocaleFile(file,"  Time: %s\n",time_limit);
   (void) fflush(file);
   UnlockSemaphoreInfo(resource_semaphore);
   return(MagickTrue);
@@ -773,84 +862,103 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
   const MagickSizeType size)
 {
   char
-    resource_current[MaxTextExtent],
-    resource_limit[MaxTextExtent],
-    resource_request[MaxTextExtent];
+    resource_current[MagickFormatExtent],
+    resource_limit[MagickFormatExtent],
+    resource_request[MagickFormatExtent];
 
-  (void) FormatMagickSize(size,MagickFalse,resource_request);
+  (void) FormatMagickSize(size,MagickFalse,"B",MagickFormatExtent,
+    resource_request);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
                ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
+    case WidthResource:
+    {
+      resource_info.width=(MagickOffsetType) size;
+      (void) FormatMagickSize((MagickSizeType) resource_info.width,MagickFalse,
+        "P",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.width_limit,MagickFalse,"P",
+        MagickFormatExtent,resource_limit);
+      break;
+    }
+    case HeightResource:
+    {
+      resource_info.height=(MagickOffsetType) size;
+      (void) FormatMagickSize((MagickSizeType) resource_info.height,MagickFalse,
+        "P",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.height_limit,MagickFalse,"P",
+        MagickFormatExtent,resource_limit);
+      break;
+    }
     case AreaResource:
     {
       resource_info.area=(MagickOffsetType) size;
       (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
-        resource_current);
-      (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.area_limit,MagickFalse,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case MemoryResource:
     {
       resource_info.memory-=size;
       (void) FormatMagickSize((MagickSizeType) resource_info.memory,
-        MagickTrue,resource_current);
-      (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
-        resource_limit);
+        MagickTrue,"B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case MapResource:
     {
       resource_info.map-=size;
       (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
-        resource_current);
-      (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case DiskResource:
     {
       resource_info.disk-=size;
       (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
-        resource_current);
-      (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
-        resource_limit);
+        "B",MagickFormatExtent,resource_current);
+      (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,"B",
+        MagickFormatExtent,resource_limit);
       break;
     }
     case FileResource:
     {
       resource_info.file-=size;
       (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     case ThreadResource:
     {
       (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     case ThrottleResource:
     {
       (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
-        MagickFalse,resource_current);
+        MagickFalse,"B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     case TimeResource:
     {
       resource_info.time-=size;
       (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
-        resource_current);
+        "B",MagickFormatExtent,resource_current);
       (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
-        MagickFalse,resource_limit);
+        MagickFalse,"B",MagickFormatExtent,resource_limit);
       break;
     }
     default:
@@ -887,20 +995,26 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
 {
   char
-    cache_path[MaxTextExtent];
+    cache_path[MagickPathExtent];
+
+  MagickBooleanType
+    status;
 
   assert(path != (const char *) NULL);
+  status=MagickFalse;
   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
     ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   if (temporary_resources != (SplayTreeInfo *) NULL)
-    (void) DeleteNodeFromSplayTree(temporary_resources, (const void *) path);
+    status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
   UnlockSemaphoreInfo(resource_semaphore);
-  (void) CopyMagickString(cache_path,path,MaxTextExtent);
+  (void) CopyMagickString(cache_path,path,MagickPathExtent);
   AppendImageFormat("cache",cache_path);
   (void) ShredFile(cache_path);
-  return(ShredFile(path));
+  if (status == MagickFalse)
+    status=ShredFile(path);
+  return(status);
 }
 \f
 /*
@@ -922,13 +1036,6 @@ MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
 %
 */
 
-static inline size_t MagickMax(const size_t x,const size_t y)
-{
-  if (x > y)
-    return(x);
-  return(y);
-}
-
 static inline MagickSizeType StringToSizeType(const char *string,
   const double interval)
 {
@@ -959,6 +1066,22 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
   */
   if (resource_semaphore == (SemaphoreInfo *) NULL)
     resource_semaphore=AcquireSemaphoreInfo();
+  (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
+  limit=GetEnvironmentValue("MAGICK_WIDTH_LIMIT");
+  if (limit != (char *) NULL)
+    {
+      (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
+        100.0));
+      limit=DestroyString(limit);
+    }
+  (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
+  limit=GetEnvironmentValue("MAGICK_HEIGHT_LIMIT");
+  if (limit != (char *) NULL)
+    {
+      (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
+        100.0));
+      limit=DestroyString(limit);
+    }
   pagesize=GetMagickPageSize();
   pages=(-1);
 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
@@ -1111,14 +1234,6 @@ MagickPrivate void ResourceComponentTerminus(void)
 %
 */
 
-static inline MagickSizeType MagickMin(const MagickSizeType x,
-  const MagickSizeType y)
-{
-  if (x < y)
-    return(x);
-  return(y);
-}
-
 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
   const MagickSizeType limit)
 {
@@ -1131,10 +1246,28 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
   value=(char *) NULL;
   switch (type)
   {
+    case WidthResource:
+    {
+      resource_info.width_limit=limit;
+      value=GetPolicyValue("resource:width");
+      if (value != (char *) NULL)
+        resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
+          100.0));
+      break;
+    }
+    case HeightResource:
+    {
+      resource_info.height_limit=limit;
+      value=GetPolicyValue("resource:height");
+      if (value != (char *) NULL)
+        resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
+          100.0));
+      break;
+    }
     case AreaResource:
     {
       resource_info.area_limit=limit;
-      value=GetPolicyValue("area");
+      value=GetPolicyValue("resource:area");
       if (value != (char *) NULL)
         resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
       break;
@@ -1142,7 +1275,7 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     case MemoryResource:
     {
       resource_info.memory_limit=limit;
-      value=GetPolicyValue("memory");
+      value=GetPolicyValue("resource:memory");
       if (value != (char *) NULL)
         resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
           100.0));
@@ -1151,7 +1284,7 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     case MapResource:
     {
       resource_info.map_limit=limit;
-      value=GetPolicyValue("map");
+      value=GetPolicyValue("resource:map");
       if (value != (char *) NULL)
         resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
       break;
@@ -1159,7 +1292,7 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     case DiskResource:
     {
       resource_info.disk_limit=limit;
-      value=GetPolicyValue("disk");
+      value=GetPolicyValue("resource:disk");
       if (value != (char *) NULL)
         resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
       break;
@@ -1167,7 +1300,7 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     case FileResource:
     {
       resource_info.file_limit=limit;
-      value=GetPolicyValue("file");
+      value=GetPolicyValue("resource:file");
       if (value != (char *) NULL)
         resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
       break;
@@ -1175,33 +1308,33 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     case ThreadResource:
     {
       resource_info.thread_limit=limit;
-      value=GetPolicyValue("thread");
+      value=GetPolicyValue("resource:thread");
       if (value != (char *) NULL)
         resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
           100.0));
       if (resource_info.thread_limit > GetOpenMPMaximumThreads())
         resource_info.thread_limit=GetOpenMPMaximumThreads();
-      else if (resource_info.thread_limit == 0)
-        resource_info.thread_limit=1;
+      else
+        if (resource_info.thread_limit == 0)
+          resource_info.thread_limit=1;
       break;
     }
     case ThrottleResource:
     {
       resource_info.throttle_limit=limit;
-      value=GetPolicyValue("throttle");
+      value=GetPolicyValue("resource:throttle");
       if (value != (char *) NULL)
-        resource_info.throttle_limit=MagickMin(limit,StringToSizeType(value,
+        resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
           100.0));
-      if (resource_info.throttle_limit > GetOpenMPMaximumThreads())
-        resource_info.throttle_limit=GetOpenMPMaximumThreads();
       break;
     }
     case TimeResource:
     {
       resource_info.time_limit=limit;
-      value=GetPolicyValue("time");
+      value=GetPolicyValue("resource:time");
       if (value != (char *) NULL)
         resource_info.time_limit=MagickMin(limit,StringToSizeType(value,100.0));
+      ResetPixelCacheEpoch();
       break;
     }
     default: