]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/channel.c
Add RobidouxSharp filter depreciate Bessel Filter and Static Gravity
[imagemagick] / MagickCore / channel.c
index 71acfa58d81bf5417564e2265e2b6e4c3a02de43..149df0b1442f4477496d3cd5dfacbc18b138fedb 100644 (file)
@@ -41,6 +41,7 @@
   Include declarations.
 */
 #include "MagickCore/studio.h"
+#include "MagickCore/colorspace-private.h"
 #include "MagickCore/image.h"
 #include "MagickCore/list.h"
 #include "MagickCore/log.h"
 %    =>      copy one channel to another channel (e.g. red=>green)
 %    =       assign a constant value to a channel (e.g. red=50%)
 %    ,       write new image channels in the specified order (e.g. red, green)
-%    |       extract channels from next image in the sequence (e.g.
-%              green=>red|red=>green).
-%    ;       separate each specified channel to its own image (e.g.
-%              red; green; blue)
+%    |       add a new output image for the next set of channel operations
+%    ;       move to the next input image for the source of channel data
 %
 %  For example, to create 3 grayscale images from the red, green, and blue
 %  channels of an image, use:
 %
-%  -channel-fx "red; green; blue"
+%    -channel-fx "red; green; blue"
 %
 %  A channel without an operation symbol implies separate (i.e, semicolon).
 %
@@ -133,8 +132,8 @@ static MagickBooleanType ChannelImage(Image *destination_image,
     y;
 
   status=MagickTrue;
-  source_view=AcquireCacheView(source_image);
-  destination_view=AcquireCacheView(destination_image);
+  source_view=AcquireVirtualCacheView(source_image,exception);
+  destination_view=AcquireAuthenticCacheView(destination_image,exception);
   height=MagickMin(source_image->rows,destination_image->rows);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(status)
@@ -201,6 +200,9 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
   ChannelFx
     channel_op;
 
+  ChannelType
+    channel_mask;
+
   char
     token[MaxTextExtent];
 
@@ -237,10 +239,11 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
   if (destination_image == (Image *) NULL)
     return((Image *) NULL);
   if (destination_image->colorspace == GRAYColorspace)
-    destination_image->colorspace=RGBColorspace;
+    destination_image->colorspace=sRGBColorspace;
   if (expression == (const char *) NULL)
     return(destination_image);
   destination_channel=RedPixelChannel;
+  channel_mask=UndefinedChannel;
   pixel=0.0;
   p=(char *) expression;
   GetMagickToken(p,&p,token);
@@ -271,11 +274,9 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
         Image
           *canvas;
 
-        if ((channel_op == ExtractChannelOp) && (channels == 1))
-          {
-            destination_image->colorspace=GRAYColorspace;
-            InitializePixelChannelMap(destination_image);
-          }
+        SetPixelChannelMapMask(destination_image,channel_mask);
+        if ((channel_op == ExtractChannelOp) && (destination_channel == 1))
+          (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
         status=SetImageStorageClass(destination_image,DirectClass,exception);
         if (status == MagickFalse)
           {
@@ -289,18 +290,19 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
             return(destination_image);
           }
         if (canvas->colorspace == GRAYColorspace)
-          canvas->colorspace=RGBColorspace;
+          canvas->colorspace=sRGBColorspace;
         AppendImageToList(&destination_image,canvas);
         destination_image=GetLastImageInList(destination_image);
         GetMagickToken(p,&p,token);
         channels=0;
         destination_channel=RedPixelChannel;
+        channel_mask=UndefinedChannel;
       }
     i=ParsePixelChannelOption(token);
     if (i < 0)
       {
         (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-          "UnrecognizedChannelType","`%s'",token);
+          "UnrecognizedChannelType","'%s'",token);
         destination_image=DestroyImageList(destination_image);
         return(destination_image);
       }
@@ -339,19 +341,37 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
         if (i < 0)
           {
             (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
-              "UnrecognizedChannelType","`%s'",token);
+              "UnrecognizedChannelType","'%s'",token);
             destination_image=DestroyImageList(destination_image);
             return(destination_image);
           }
         destination_channel=(PixelChannel) i;
+        channel_mask=(ChannelType) (channel_mask | ParseChannelOption(token));
+        if (LocaleCompare(token,"gray") == 0)
+          (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
+        if ((LocaleCompare(token,"black") == 0) ||
+            (LocaleCompare(token,"c") == 0) ||
+            (LocaleCompare(token,"cyan") == 0) ||
+            (LocaleCompare(token,"k") == 0) ||
+            (LocaleCompare(token,"m") == 0) ||
+            (LocaleCompare(token,"magenta") == 0) ||
+            (LocaleCompare(token,"y") == 0) ||
+            (LocaleCompare(token,"yellow") == 0))
+          (void) SetImageColorspace(destination_image,CMYKColorspace,exception);
+        if ((LocaleCompare(token,"Cb") == 0) ||
+            (LocaleCompare(token,"Cr") == 0))
+          (void) SetImageColorspace(destination_image,YCbCrColorspace,
+            exception);
+        if (LocaleCompare(token,"alpha") == 0)
+          (void) SetImageAlpha(destination_image,OpaqueAlpha,exception);
+        if (i >= (ssize_t) GetPixelChannels(destination_image))
+          (void) SetPixelMetaChannels(destination_image,(size_t) (i-
+            GetPixelChannels(destination_image)+1),exception);
         GetMagickToken(p,&p,token);
         break;
       }
-      case ExtractChannelOp:
-      {
+      default:
         break;
-        destination_channel++;
-      }
     }
     status=ChannelImage(destination_image,destination_channel,channel_op,
       source_image,source_channel,ClampToQuantum(pixel),exception);
@@ -372,16 +392,25 @@ MagickExport Image *ChannelFxImage(const Image *image,const char *expression,
           }
         channels++;
       }
+    switch (channel_op)
+    {
+      case ExtractChannelOp:
+      {
+        channel_mask=(ChannelType) (channel_mask | (1 << destination_channel));
+        destination_channel=(PixelChannel) (destination_channel+1);
+        break;
+      }
+      default:
+        break;
+    }
     status=SetImageProgress(source_image,ChannelFxImageTag,p-expression,
       strlen(expression));
     if (status == MagickFalse)
       break;
   }
-  if ((channel_op == ExtractChannelOp) && (channels == 1))
-    {
-      destination_image->colorspace=GRAYColorspace;
-      InitializePixelChannelMap(destination_image);
-    }
+  SetPixelChannelMapMask(destination_image,channel_mask);
+  if ((channel_op == ExtractChannelOp) && (destination_channel == 1))
+    (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
   status=SetImageStorageClass(destination_image,DirectClass,exception);
   if (status == MagickFalse)
     {
@@ -454,6 +483,8 @@ MagickExport Image *CombineImages(const Image *image,ExceptionInfo *exception)
       combine_image=DestroyImage(combine_image);
       return((Image *) NULL);
     }
+  if (IsGrayColorspace(image->colorspace) != MagickFalse)
+    (void) SetImageColorspace(combine_image,sRGBColorspace,exception);
   if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
     combine_image->matte=MagickTrue;
   /*
@@ -461,7 +492,7 @@ MagickExport Image *CombineImages(const Image *image,ExceptionInfo *exception)
   */
   status=MagickTrue;
   progress=0;
-  combine_view=AcquireCacheView(combine_image);
+  combine_view=AcquireAuthenticCacheView(combine_image,exception);
   for (y=0; y < (ssize_t) combine_image->rows; y++)
   {
     CacheView
@@ -492,13 +523,12 @@ MagickExport Image *CombineImages(const Image *image,ExceptionInfo *exception)
         continue;
       }
     next=image;
-    for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+    for (i=0; i < (ssize_t) GetPixelChannels(combine_image); i++)
     {
       PixelChannel
         channel;
 
       PixelTrait
-        combine_traits,
         traits;
 
       register ssize_t
@@ -506,13 +536,11 @@ MagickExport Image *CombineImages(const Image *image,ExceptionInfo *exception)
 
       if (next == (Image *) NULL)
         continue;
-      channel=GetPixelChannelMapChannel(image,i);
-      traits=GetPixelChannelMapTraits(image,channel);
-      combine_traits=GetPixelChannelMapTraits(combine_image,channel);
-      if ((traits == UndefinedPixelTrait) ||
-          (combine_traits == UndefinedPixelTrait))
+      channel=GetPixelChannelMapChannel(combine_image,i);
+      traits=GetPixelChannelMapTraits(combine_image,channel);
+      if (traits == UndefinedPixelTrait)
         continue;
-      image_view=AcquireCacheView(next);
+      image_view=AcquireVirtualCacheView(next,exception);
       p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
       if (p == (const Quantum *) NULL)
         continue;
@@ -622,8 +650,8 @@ MagickExport Image *SeparateImage(const Image *image,
   */
   status=MagickTrue;
   progress=0;
-  image_view=AcquireCacheView(image);
-  separate_view=AcquireCacheView(separate_image);
+  image_view=AcquireVirtualCacheView(image,exception);
+  separate_view=AcquireAuthenticCacheView(separate_image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
   #pragma omp parallel for schedule(static) shared(progress,status)
 #endif
@@ -714,8 +742,7 @@ MagickExport Image *SeparateImage(const Image *image,
 %
 %  The format of the SeparateImages method is:
 %
-%      MagickBooleanType SeparateImages(const Image *image,
-%        ExceptionInfo *exception)
+%      Image *SeparateImages(const Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %