Added option 'icon:auto-resize' to automatically store multiple sizes in an ico image (requires 256x256 input image).
diff --git a/coders/icon.c b/coders/icon.c
index 035fe22..9bb995e 100644
--- a/coders/icon.c
+++ b/coders/icon.c
@@ -58,6 +58,7 @@
 #include "MagickCore/monitor.h"
 #include "MagickCore/monitor-private.h"
 #include "MagickCore/nt-base-private.h"
+#include "MagickCore/option.h"
 #include "MagickCore/pixel-accessor.h"
 #include "MagickCore/quantize.h"
 #include "MagickCore/quantum-private.h"
@@ -785,6 +786,7 @@
     icon_info;
 
   Image
+    *images,
     *next;
   
   MagickBooleanType
@@ -829,15 +831,44 @@
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(status);
-  scene=0;
-  next=image;
-  do
-  {
-    if ((image->columns > 256L) || (image->rows > 256L))
-      ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
-    scene++;
-    next=SyncNextImageInList(next);
-  } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
+  images=(Image *) NULL;
+  if (GetImageOption(image_info,"icon:auto-resize") != (const char *) NULL)
+    {
+      size_t
+        sizes[]={192,128,96,64,48,40,32,24,16};
+
+      if ((image->columns != 256L) && (image->rows != 256L))
+        ThrowWriterException(ImageError,"SizeMustBe256x256");
+      if (image->next != (Image *) NULL)
+        ThrowWriterException(ImageError,"OnlyOneImageAllowed");
+      images=CloneImage(image,0,0,MagickTrue,exception);
+      if (images == (Image *) NULL)
+        return(MagickFalse);
+      scene=sizeof(sizes)/sizeof(sizes[0]);
+      for (i=0; i < scene; i++)
+      {
+        next=ResizeImage(image,sizes[i],sizes[i],image->filter,exception);

+        if (next == (Image *) NULL)

+          {

+            images=DestroyImageList(images);

+            return(MagickFalse);

+          }
+        AppendImageToList(&images,next);
+      }
+      scene++;
+    }
+  else
+    {
+      scene=0;
+      next=image;
+      do
+      {
+        if ((image->columns > 256L) || (image->rows > 256L))
+          ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
+        scene++;
+        next=SyncNextImageInList(next);
+      } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
+    }
   /*
     Dump out a ICON header template to be properly initialized later.
   */
@@ -847,7 +878,7 @@
   (void) ResetMagickMemory(&icon_file,0,sizeof(icon_file));
   (void) ResetMagickMemory(&icon_info,0,sizeof(icon_info));
   scene=0;
-  next=image;
+  next=(images != (Image *) NULL) ? images : image;
   do
   {
     (void) WriteBlobByte(image,icon_file.directory[scene].width);
@@ -864,7 +895,7 @@
     next=SyncNextImageInList(next);
   } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
   scene=0;
-  next=image;
+  next=(images != (Image *) NULL) ? images : image;
   do
   {
     if ((next->columns > 255L) && (next->rows > 255L) &&
@@ -884,8 +915,11 @@
           *png;
 
         write_image=CloneImage(next,0,0,MagickTrue,exception);
-        if (write_image == (Image *) NULL)
-          return(MagickFalse);
+        if (write_image == (Image *) NULL)

+          {

+            images=DestroyImageList(images);

+            return(MagickFalse);

+          }
         write_info=CloneImageInfo(image_info);
         (void) CopyMagickString(write_info->filename,"PNG:",MaxTextExtent);
 
@@ -899,8 +933,11 @@
           exception);
         write_image=DestroyImage(write_image);
         write_info=DestroyImageInfo(write_info);
-        if (png == (unsigned char *) NULL)
-          return(MagickFalse);
+        if (png == (unsigned char *) NULL)

+          {

+            images=DestroyImageList(images);

+            return(MagickFalse);

+          }
         icon_file.directory[scene].width=0;
         icon_file.directory[scene].height=0;
         icon_file.directory[scene].colors=0;
@@ -1005,8 +1042,11 @@
         */
         pixels=(unsigned char *) AcquireQuantumMemory((size_t)
           icon_info.image_size,sizeof(*pixels));
-        if (pixels == (unsigned char *) NULL)
-          ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+        if (pixels == (unsigned char *) NULL)

+          {

+            images=DestroyImageList(images);
+            ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+          }

         (void) ResetMagickMemory(pixels,0,(size_t) icon_info.image_size);
         switch (icon_info.bits_per_pixel)
         {
@@ -1186,8 +1226,12 @@
             */
             icon_colormap=(unsigned char *) AcquireQuantumMemory((size_t)
               (1UL << icon_info.bits_per_pixel),4UL*sizeof(*icon_colormap));
-            if (icon_colormap == (unsigned char *) NULL)
-              ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
+            if (icon_colormap == (unsigned char *) NULL)

+              {

+                images=DestroyImageList(images);

+                ThrowWriterException(ResourceLimitError,

+                  "MemoryAllocationFailed");

+              }
             q=icon_colormap;
             for (i=0; i < (ssize_t) next->colors; i++)
             {
@@ -1256,7 +1300,7 @@
   (void) WriteBlobLSBShort(image,1);
   (void) WriteBlobLSBShort(image,(unsigned short) (scene+1));
   scene=0;
-  next=image;
+  next=(images != (Image *) NULL) ? images : image;
   do
   {
     (void) WriteBlobByte(image,icon_file.directory[scene].width);
@@ -1273,5 +1317,6 @@
     next=SyncNextImageInList(next);
   } while ((next != (Image *) NULL) && (image_info->adjoin != MagickFalse));
   (void) CloseBlob(image);
+  images=DestroyImageList(images);
   return(MagickTrue);
 }