]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/image.c
(no commit message)
[imagemagick] / MagickCore / image.c
index 54c849470cd533132b32525b53903b3673b4a1ee..b583397372a42c5f7db2c3a1a4db7382ec9e8cdd 100644 (file)
 %                           MagickCore Image Methods                          %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 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  %
@@ -205,9 +205,10 @@ MagickExport Image *AcquireImage(const ImageInfo *image_info,
   image->channel_mask=DefaultChannels;
   image->channel_map=AcquirePixelChannelMap();
   image->blob=CloneBlobInfo((BlobInfo *) NULL);
+  image->timestamp=time((time_t *) NULL);
   image->debug=IsEventLogging();
   image->reference_count=1;
-  image->semaphore=AllocateSemaphoreInfo();
+  image->semaphore=AcquireSemaphoreInfo();
   image->signature=MagickSignature;
   if (image_info == (ImageInfo *) NULL)
     return(image);
@@ -280,11 +281,14 @@ MagickExport Image *AcquireImage(const ImageInfo *image_info,
   image->client_data=image_info->client_data;
   if (image_info->cache != (void *) NULL)
     ClonePixelCacheMethods(image->cache,image_info->cache);
-
-  /* Set all global options that map to per-image settings */
+  /*
+    Set all global options that map to per-image settings.
+  */
   (void) SyncImageSettings(image_info,image,exception);
-
-  /* global options that are only set for new images */
+  /*
+    Global options that are only set for new images.
+  */
+  image->image_info=(ImageInfo *) NULL;
   option=GetImageOption(image_info,"delay");
   if (option != (const char *) NULL)
     {
@@ -445,7 +449,6 @@ MagickExport Image *AppendImages(const Image *images,
     *append_image;
 
   MagickBooleanType
-    proceed,
     status;
 
   MagickOffsetType
@@ -526,6 +529,9 @@ MagickExport Image *AppendImages(const Image *images,
     Image
       *image;
 
+    MagickBooleanType
+      proceed;
+
     image=CloneImage(next,0,0,MagickTrue,exception);
     if (image == (Image *) NULL)
       break;
@@ -539,7 +545,7 @@ MagickExport Image *AppendImages(const Image *images,
     image_view=AcquireVirtualCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
     #pragma omp parallel for schedule(static,4) shared(status) \
-      dynamic_number_threads(image,image->columns,image->rows,1)
+      magick_threads(image,image,image->rows,1)
 #endif
     for (y=0; y < (ssize_t) image->rows; y++)
     {
@@ -571,8 +577,9 @@ MagickExport Image *AppendImages(const Image *images,
       GetPixelInfo(image,&pixel);
       for (x=0; x < (ssize_t) image->columns; x++)
       {
-        if (GetPixelMask(image,p) != 0)
+        if (GetPixelReadMask(image,p) == 0)
           {
+            SetPixelBackgoundColor(append_image,q);
             p+=GetPixelChannels(image);
             q+=GetPixelChannels(append_image);
             continue;
@@ -815,7 +822,8 @@ MagickExport Image *CloneImage(const Image *image,const size_t columns,
   clone_image->number_meta_channels=image->number_meta_channels;
   clone_image->metacontent_extent=image->metacontent_extent;
   clone_image->colorspace=image->colorspace;
-  clone_image->mask=image->mask;
+  clone_image->read_mask=image->read_mask;
+  clone_image->write_mask=image->write_mask;
   clone_image->alpha_trait=image->alpha_trait;
   clone_image->columns=image->columns;
   clone_image->rows=image->rows;
@@ -865,7 +873,7 @@ MagickExport Image *CloneImage(const Image *image,const size_t columns,
     }
   clone_image->ping=image->ping;
   clone_image->debug=IsEventLogging();
-  clone_image->semaphore=AllocateSemaphoreInfo();
+  clone_image->semaphore=AcquireSemaphoreInfo();
   if ((columns == 0) && (rows == 0))
     {
       if (image->montage != (char *) NULL)
@@ -886,6 +894,7 @@ MagickExport Image *CloneImage(const Image *image,const size_t columns,
   clone_image->columns=columns;
   clone_image->rows=rows;
   clone_image->cache=ClonePixelCache(image->cache);
+
   return(clone_image);
 }
 \f
@@ -1043,7 +1052,7 @@ MagickExport Image *DestroyImage(Image *image)
     image->ascii85=(Ascii85Info *) RelinquishMagickMemory(image->ascii85);
   DestroyBlob(image);
   if (image->semaphore != (SemaphoreInfo *) NULL)
-    DestroySemaphoreInfo(&image->semaphore);
+    RelinquishSemaphoreInfo(&image->semaphore);
   image->signature=(~MagickSignature);
   image=(Image *) RelinquishMagickMemory(image);
   return(image);
@@ -1148,39 +1157,6 @@ MagickExport void DisassociateImageStream(Image *image)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   G e t I m a g e A l p h a C h a n n e l                                   %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  GetImageAlphaChannel() returns MagickFalse if the image alpha channel is
-%  not activated.  That is, the image is RGB rather than RGBA or CMYK rather
-%  than CMYKA.
-%
-%  The format of the GetImageAlphaChannel method is:
-%
-%      MagickBooleanType GetImageAlphaChannel(const Image *image)
-%
-%  A description of each parameter follows:
-%
-%    o image: the image.
-%
-*/
-MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
-{
-  assert(image != (const Image *) NULL);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
-  assert(image->signature == MagickSignature);
-  return(image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 %   G e t I m a g e I n f o                                                   %
 %                                                                             %
 %                                                                             %
@@ -1200,6 +1176,9 @@ MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
 */
 MagickExport void GetImageInfo(ImageInfo *image_info)
 {
+  char
+    *synchronize;
+
   ExceptionInfo
     *exception;
 
@@ -1215,8 +1194,12 @@ MagickExport void GetImageInfo(ImageInfo *image_info)
   image_info->quality=UndefinedCompressionQuality;
   image_info->antialias=MagickTrue;
   image_info->dither=MagickTrue;
-  image_info->synchronize=IsStringTrue(GetEnvironmentValue(
-         "MAGICK_SYNCHRONIZE"));
+  synchronize=GetEnvironmentValue("MAGICK_SYNCHRONIZE");
+  if (synchronize != (const char *) NULL)
+    {
+      image_info->synchronize=IsStringTrue(synchronize);
+      synchronize=DestroyString(synchronize);
+    }
   exception=AcquireExceptionInfo();
   (void) QueryColorCompliance(BackgroundColor,AllCompliance,
     &image_info->background_color,exception);
@@ -1307,7 +1290,7 @@ MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
     return((Image *) NULL);
   status=MagickTrue;
   (void) SetImageColorspace(mask_image,GRAYColorspace,exception);
-  mask_image->mask=MagickFalse;
+  mask_image->read_mask=MagickFalse;
   image_view=AcquireVirtualCacheView(image,exception);
   mask_view=AcquireAuthenticCacheView(mask_image,exception);
   for (y=0; y < (ssize_t) image->rows; y++)
@@ -1333,7 +1316,7 @@ MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
       }
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      SetPixelGray(mask_image,GetPixelMask(image,p),q);
+      SetPixelGray(mask_image,GetPixelReadMask(image,p),q);
       p+=GetPixelChannels(image);
       q+=GetPixelChannels(mask_image);
     }
@@ -1342,6 +1325,8 @@ MagickExport Image *GetImageMask(const Image *image,ExceptionInfo *exception)
   }
   mask_view=DestroyCacheView(mask_view);
   image_view=DestroyCacheView(image_view);
+  if (status == MagickFalse)
+    mask_image=DestroyImage(mask_image);
   return(mask_image);
 }
 \f
@@ -1560,8 +1545,7 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
 #endif
         if (image != (Image *) NULL)
           value=GetImageProperty(image,pattern,exception);
-        if ((value == (const char *) NULL) &&
-            (image != (Image *) NULL))
+        if ((value == (const char *) NULL) && (image != (Image *) NULL))
           value=GetImageArtifact(image,pattern);
         if ((value == (const char *) NULL) &&
             (image_info != (ImageInfo *) NULL))
@@ -1649,7 +1633,7 @@ MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
   image_view=AcquireVirtualCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -1672,7 +1656,7 @@ MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
       register ssize_t
         i;
 
-      if (GetPixelMask(image,p) != 0)
+      if (GetPixelReadMask(image,p) == 0)
         {
           p+=GetPixelChannels(image);
           continue;
@@ -1690,7 +1674,7 @@ MagickExport MagickBooleanType IsHighDynamicRangeImage(const Image *image,
           continue;
         pixel=(double) p[i];
         if ((pixel < 0.0) || (pixel > QuantumRange) ||
-            (pixel != (QuantumAny) pixel))
+            (pixel != (double) ((QuantumAny) pixel)))
           break;
       }
       p+=GetPixelChannels(image);
@@ -1904,7 +1888,7 @@ MagickExport Image *NewMagickImage(const ImageInfo *image_info,
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -2045,273 +2029,6 @@ MagickExport MagickBooleanType ResetImagePage(Image *image,const char *page)
 %                                                                             %
 %                                                                             %
 %                                                                             %
-%   S e t I m a g e A l p h a C h a n n e l                                   %
-%                                                                             %
-%                                                                             %
-%                                                                             %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-%  SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
-%  channel.
-%
-%  The format of the SetImageAlphaChannel method is:
-%
-%      MagickBooleanType SetImageAlphaChannel(Image *image,
-%        const AlphaChannelOption alpha_type,ExceptionInfo *exception)
-%
-%  A description of each parameter follows:
-%
-%    o image: the image.
-%
-%    o alpha_type:  The alpha channel type: ActivateAlphaChannel,
-%      CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
-%      OpaqueAlphaChannel, SetAlphaChannel, ShapeAlphaChannel, and
-%      TransparentAlphaChannel.
-%
-%    o exception: return any errors or warnings in this structure.
-%
-*/
-
-static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p,
-  const double alpha,const Quantum *q,const double beta,
-  Quantum *composite)
-{
-  double
-    Da,
-    gamma,
-    Sa;
-
-  register ssize_t
-    i;
-
-  /*
-    Compose pixel p over pixel q with the given alpha.
-  */
-  Sa=QuantumScale*alpha;
-  Da=QuantumScale*beta,
-  gamma=Sa*(-Da)+Sa+Da;
-  gamma=MagickEpsilonReciprocal(gamma);
-  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
-  {
-    PixelChannel
-      channel;
-
-    PixelTrait
-      traits;
-
-    channel=GetPixelChannelChannel(image,i);
-    traits=GetPixelChannelTraits(image,channel);
-    if (traits == UndefinedPixelTrait)
-      continue;
-    switch (channel)
-    {
-      case RedPixelChannel:
-      {
-        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
-          (double) p->red,alpha));
-        break;
-      }
-      case GreenPixelChannel:
-      {
-        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
-          (double) p->green,alpha));
-        break;
-      }
-      case BluePixelChannel:
-      {
-        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
-          (double) p->blue,alpha));
-        break;
-      }
-      case BlackPixelChannel:
-      {
-        composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
-          (double) p->black,alpha));
-        break;
-      }
-      case AlphaPixelChannel:
-      {
-        composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
-        break;
-      }
-      default:
-        break;
-    }
-  }
-}
-
-MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
-  const AlphaChannelOption alpha_type,ExceptionInfo *exception)
-{
-  MagickBooleanType
-    status;
-
-  assert(image != (Image *) NULL);
-  if (image->debug != MagickFalse)
-    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
-  assert(image->signature == MagickSignature);
-  status=MagickTrue;
-  switch (alpha_type)
-  {
-    case ActivateAlphaChannel:
-    {
-      image->alpha_trait=BlendPixelTrait;
-      break;
-    }
-    case BackgroundAlphaChannel:
-    {
-      CacheView
-        *image_view;
-
-      ssize_t
-        y;
-
-      /*
-        Set transparent pixels to background color.
-      */
-      if (image->alpha_trait != BlendPixelTrait)
-        break;
-      if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
-        break;
-      image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status) \
-        dynamic_number_threads(image,image->columns,image->rows,1)
-#endif
-      for (y=0; y < (ssize_t) image->rows; y++)
-      {
-        register Quantum
-          *restrict q;
-
-        register ssize_t
-          x;
-
-        if (status == MagickFalse)
-          continue;
-        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
-          exception);
-        if (q == (Quantum *) NULL)
-          {
-            status=MagickFalse;
-            continue;
-          }
-        for (x=0; x < (ssize_t) image->columns; x++)
-        {
-          if (GetPixelAlpha(image,q) == TransparentAlpha)
-            SetPixelInfoPixel(image,&image->background_color,q);
-          q+=GetPixelChannels(image);
-        }
-        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
-          status=MagickFalse;
-      }
-      image_view=DestroyCacheView(image_view);
-      return(status);
-    }
-    case CopyAlphaChannel:
-    case ShapeAlphaChannel:
-    {
-      /*
-        Copy pixel intensity to the alpha channel.
-      */
-      status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
-        exception);
-      if (alpha_type == ShapeAlphaChannel)
-        (void) LevelImageColors(image,&image->background_color,
-          &image->background_color,MagickTrue,exception);
-      break;
-    }
-    case DeactivateAlphaChannel:
-    {
-      image->alpha_trait=CopyPixelTrait;
-      break;
-    }
-    case ExtractAlphaChannel:
-    {
-      status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
-        exception);
-      image->alpha_trait=UndefinedPixelTrait;
-      break;
-    }
-    case OpaqueAlphaChannel:
-    {
-      status=SetImageAlpha(image,OpaqueAlpha,exception);
-      break;
-    }
-    case RemoveAlphaChannel:
-    {
-      CacheView
-        *image_view;
-
-      ssize_t
-        y;
-
-      /*
-        Remove transparency.
-      */
-      if (image->alpha_trait != BlendPixelTrait)
-        break;
-      if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
-        break;
-      image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
-      #pragma omp parallel for schedule(static,4) shared(status) \
-        dynamic_number_threads(image,image->columns,image->rows,1)
-#endif
-      for (y=0; y < (ssize_t) image->rows; y++)
-      {
-        register Quantum
-          *restrict q;
-
-        register ssize_t
-          x;
-
-        if (status == MagickFalse)
-          continue;
-        q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
-          exception);
-        if (q == (Quantum *) NULL)
-          {
-            status=MagickFalse;
-            continue;
-          }
-        for (x=0; x < (ssize_t) image->columns; x++)
-        {
-          FlattenPixelInfo(image,&image->background_color,
-            image->background_color.alpha,q,(double)
-            GetPixelAlpha(image,q),q);
-          q+=GetPixelChannels(image);
-        }
-        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
-          status=MagickFalse;
-      }
-      image_view=DestroyCacheView(image_view);
-      image->alpha_trait=image->background_color.alpha_trait;
-      return(status);
-    }
-    case SetAlphaChannel:
-    {
-      if (image->alpha_trait != BlendPixelTrait)
-        status=SetImageAlpha(image,OpaqueAlpha,exception);
-      break;
-    }
-    case TransparentAlphaChannel:
-    {
-      status=SetImageAlpha(image,TransparentAlpha,exception);
-      break;
-    }
-    case UndefinedAlphaChannel:
-      break;
-  }
-  if (status == MagickFalse)
-    return(status);
-  return(SyncImagePixelCache(image,exception));
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%                                                                             %
-%                                                                             %
-%                                                                             %
 %   S e t I m a g e B a c k g r o u n d C o l o r                             %
 %                                                                             %
 %                                                                             %
@@ -2354,7 +2071,7 @@ MagickExport MagickBooleanType SetImageBackgroundColor(Image *image,
     return(MagickFalse);
   if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
       (IsGrayColorspace(image->colorspace) != MagickFalse))
-    (void) TransformImageColorspace(image,RGBColorspace,exception);
+    (void) TransformImageColorspace(image,sRGBColorspace,exception);
   if ((image->background_color.alpha_trait == BlendPixelTrait) &&
       (image->alpha_trait != BlendPixelTrait))
     (void) SetImageAlpha(image,OpaqueAlpha,exception);
@@ -2481,7 +2198,7 @@ MagickExport MagickBooleanType SetImageColor(Image *image,
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -2662,50 +2379,46 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info,
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
       image_info->filename);
   *subimage='\0';
-  if (frames == 0)
+  GetPathComponent(image_info->filename,SubimagePath,subimage);
+  if (*subimage != '\0')
     {
-      GetPathComponent(image_info->filename,SubimagePath,subimage);
-      if (*subimage != '\0')
+      /*
+        Look for scene specification (e.g. img0001.pcd[4]).
+      */
+      if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse)
         {
-          /*
-            Look for scene specification (e.g. img0001.pcd[4]).
-          */
-          if (IsSceneGeometry(subimage,MagickFalse) == MagickFalse)
-            {
-              if (IsGeometry(subimage) != MagickFalse)
-                (void) CloneString(&image_info->extract,subimage);
-            }
-          else
-            {
-              size_t
-                first,
-                last;
-
-              (void) CloneString(&image_info->scenes,subimage);
-              image_info->scene=StringToUnsignedLong(image_info->scenes);
-              image_info->number_scenes=image_info->scene;
-              p=image_info->scenes;
-              for (q=(char *) image_info->scenes; *q != '\0'; p++)
-              {
-                while ((isspace((int) ((unsigned char) *p)) != 0) ||
-                       (*p == ','))
-                  p++;
-                first=(size_t) strtol(p,&q,10);
-                last=first;
-                while (isspace((int) ((unsigned char) *q)) != 0)
-                  q++;
-                if (*q == '-')
-                  last=(size_t) strtol(q+1,&q,10);
-                if (first > last)
-                  Swap(first,last);
-                if (first < image_info->scene)
-                  image_info->scene=first;
-                if (last > image_info->number_scenes)
-                  image_info->number_scenes=last;
-                p=q;
-              }
-              image_info->number_scenes-=image_info->scene-1;
-            }
+          if (IsGeometry(subimage) != MagickFalse)
+            (void) CloneString(&image_info->extract,subimage);
+        }
+      else
+        {
+          size_t
+            first,
+            last;
+
+          (void) CloneString(&image_info->scenes,subimage);
+          image_info->scene=StringToUnsignedLong(image_info->scenes);
+          image_info->number_scenes=image_info->scene;
+          p=image_info->scenes;
+          for (q=(char *) image_info->scenes; *q != '\0'; p++)
+          {
+            while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
+              p++;
+            first=(size_t) strtol(p,&q,10);
+            last=first;
+            while (isspace((int) ((unsigned char) *q)) != 0)
+              q++;
+            if (*q == '-')
+              last=(size_t) strtol(q+1,&q,10);
+            if (first > last)
+              Swap(first,last);
+            if (first < image_info->scene)
+              image_info->scene=first;
+            if (last > image_info->number_scenes)
+              image_info->number_scenes=last;
+            p=q;
+          }
+          image_info->number_scenes-=image_info->scene-1;
         }
     }
   *extension='\0';
@@ -2896,6 +2609,7 @@ MagickExport MagickBooleanType SetImageInfo(ImageInfo *image_info,
         }
       (void) ResetMagickMemory(magick,0,sizeof(magick));
       count=ReadBlob(image,2*MaxTextExtent,magick);
+      (void) SeekBlob(image,-((MagickOffsetType) count),SEEK_CUR);
       (void) CloseBlob(image);
       image=DestroyImage(image);
       /*
@@ -3047,13 +2761,19 @@ MagickExport MagickBooleanType SetImageMask(Image *image,const Image *mask,
   assert(image->signature == MagickSignature);
   if (mask == (const Image *) NULL)
     {
-      image->mask=MagickFalse;
-      return(MagickTrue);
+      image->read_mask=MagickFalse;
+      return(SyncImagePixelCache(image,exception));
     }
+  image->read_mask=MagickTrue;
+  if (SyncImagePixelCache(image,exception) == MagickFalse)
+    return(MagickFalse);
   status=MagickTrue;
-  image->mask=MagickTrue;
   mask_view=AcquireVirtualCacheView(mask,exception);
   image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+  #pragma omp parallel for schedule(static,4) shared(status) \
+    magick_threads(mask,image,1,1)
+#endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
     register const Quantum
@@ -3076,7 +2796,7 @@ MagickExport MagickBooleanType SetImageMask(Image *image,const Image *mask,
       }
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      SetPixelMask(image,GetPixelGray(mask,p),q);
+      SetPixelReadMask(image,ClampToQuantum(GetPixelIntensity(mask,p)),q);
       p+=GetPixelChannels(mask);
       q+=GetPixelChannels(image);
     }
@@ -3135,7 +2855,7 @@ MagickExport MagickBooleanType SetImageAlpha(Image *image,const Quantum alpha,
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -3607,7 +3327,7 @@ MagickExport MagickBooleanType SyncImage(Image *image,ExceptionInfo *exception)
   image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static,4) shared(range_exception,status) \
-    dynamic_number_threads(image,image->columns,image->rows,1)
+    magick_threads(image,image,image->rows,1)
 #endif
   for (y=0; y < (ssize_t) image->rows; y++)
   {
@@ -3640,7 +3360,7 @@ MagickExport MagickBooleanType SyncImage(Image *image,ExceptionInfo *exception)
   image_view=DestroyCacheView(image_view);
   if ((image->ping == MagickFalse) && (range_exception != MagickFalse))
     (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
-      "InvalidColormapIndex","'%s'",image->filename);
+      "InvalidColormapIndex","`%s'",image->filename);
   return(status);
 }
 \f
@@ -3658,10 +3378,11 @@ MagickExport MagickBooleanType SyncImage(Image *image,ExceptionInfo *exception)
 %  SyncImageSettings() syncs any image_info global options into per-image
 %  attributes.
 %
-%  Note: in IMv6 free form 'options' were always maped into 'artifacts', so
+%  Note: in IMv6 free form 'options' were always mapped into 'artifacts', so
 %  that operations and coders can find such settings.  In IMv7 if a desired
 %  per-image artifact is not set, then it will directly look for a global
-%  option as a fallback.
+%  option as a fallback, as such this copy is no longer needed, only the
+%  link set up.
 %
 %  The format of the SyncImageSettings method is:
 %
@@ -3805,6 +3526,10 @@ MagickExport MagickBooleanType SyncImageSettings(const ImageInfo *image_info,
   if (option != (const char *) NULL)
     image->rendering_intent=(RenderingIntent) ParseCommandOption(
       MagickIntentOptions,MagickFalse,option);
+  option=GetImageOption(image_info,"intensity");
+  if (option != (const char *) NULL)
+    image->intensity=(PixelIntensityMethod) ParseCommandOption(
+      MagickPixelIntensityOptions,MagickFalse,option);
   option=GetImageOption(image_info,"interlace");
   if (option != (const char *) NULL)
     image->interlace=(InterlaceType) ParseCommandOption(MagickInterlaceOptions,
@@ -3925,17 +3650,18 @@ MagickExport MagickBooleanType SyncImageSettings(const ImageInfo *image_info,
   ResetImageOptionIterator(image_info);
 #if 0
   {
+    /* IMv6: Copy freeform global options into per-image artifacts, so
+     * various operations and coders can access them.
+     *
+     * This has a problem, as per-image artefacts may have been set in
+     * parenthesis, but may not be unset when parenthesis ends.
+     */
     char
       property[MaxTextExtent];
 
     const char
       *value;
 
-    /* IMv6: Copy freeform global options into per-image artifacts, so
-     * various operations and coders can access them.
-     * This has a problem, as artifacts may be set in parenthesis, but may
-     * not be unset when parenthesis ends.
-     */
     for (option=GetNextImageOption(image_info); option != (const char *) NULL; )
     {
       value=GetImageOption(image_info,option);
@@ -3948,15 +3674,17 @@ MagickExport MagickBooleanType SyncImageSettings(const ImageInfo *image_info,
     }
   }
 #else
-  /* IMv7: pointer for lookup of artifact fallback, back to global option.
-     This saves a lot of duplication of global options into per-image
-     artifacts, while ensuring only specificly set per-image artifacts
-     are preverved when parenthesis ends.
-
-     WARNING: When a global option is set, any associated per-image artifact
-     should also be unset, as no longer valid.
-   */
-  image->image_info = CloneImageInfo(image_info);
+  /* IMv7: pointer to allow the lookup of pre-image artefact will fallback to
+     a global option setting/define.  This saves a lot of duplication of
+     global options into per-image artifacts, while ensuring only specifically
+     set per-image artifacts are preverved when parenthesis ends.
+
+     This pointer is never explictally freed, as it is only used as a back
+     reference, not as the main pointer to the image_info structure.  Images
+     being removed from a image_info image list (or yet to be added to such),
+     should have this pointer reset to NULL.
+  */
+  image->image_info=image_info;
 #endif
   return(MagickTrue);
 }