]> granicus.if.org Git - imagemagick/commitdiff
Compose DarkenIntensity and LightenIntensity
authoranthony <anthony@git.imagemagick.org>
Thu, 7 Apr 2011 11:15:54 +0000 (11:15 +0000)
committeranthony <anthony@git.imagemagick.org>
Thu, 7 Apr 2011 11:15:54 +0000 (11:15 +0000)
ChangeLog
magick/composite.c
magick/composite.h
magick/option.c

index ed0f372db8f3282b15ff69733cbf0da9225984fb..b8bf4836b8c6e369f699dc87b586f9428e9949d6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
     transparency will use 'Over' while images with transparency will
     preverse transparency using 'Copy'. Before this only 'Over' was used
     due to the testing of the wrong image.
+  * Added Compose methods  DarkenIntensity and LightenIntensity
 
 2011-04-06  6.6.9-4 Cristy  <quetzlzacatenango@image...>
   * New version 6.6.9-4.
index 7122bfe4141e5a337d8b85203f58921b17436c08..0dd25af862e484e5011ffb55a0245b46de8eca6f 100644 (file)
@@ -403,6 +403,40 @@ static inline void CompositeDarken(const MagickPixelPacket *p,
   }
 }
 
+static inline void CompositeDarkenIntensity(const MagickPixelPacket *p,
+  const MagickPixelPacket *q,const ChannelType channel,
+  MagickPixelPacket *composite)
+{
+  /*
+    Select the pixel based on the intensity level.
+    If 'Sync' flag select whole pixel based on alpha weighted intensity.
+    Otherwise use Intenisty only, but restrict copy according to channel.
+  */
+  if ( (channel & SyncChannels) != 0 ) {
+    MagickRealType
+      Da,
+      Sa;
+
+    Sa=1.0-QuantumScale*p->opacity;
+    Da=1.0-QuantumScale*q->opacity;
+    *composite = (Sa*MagickPixelIntensity(p) < Da*MagickPixelIntensity(q))
+              ? *p : *q;
+  }
+  else {
+    int from_p = (MagickPixelIntensity(p) < MagickPixelIntensity(q));
+    if ( (channel & AlphaChannel) != 0 )
+      composite->opacity = from_p ? p->opacity : q->opacity;
+    if ( (channel & RedChannel) != 0 )
+      composite->red = from_p ? p->red : q->red;
+    if ( (channel & GreenChannel) != 0 )
+      composite->green = from_p ? p->green : q->green;
+    if ( (channel & BlueChannel) != 0 )
+      composite->blue = from_p ? p->blue : q->blue;
+    if ( (channel & IndexChannel) != 0 && q->colorspace == CMYKColorspace)
+      composite->index = from_p ? p->index : q->index;
+  }
+}
+
 static inline MagickRealType Difference(const MagickRealType p,
   const MagickRealType Sa,const MagickRealType q,const MagickRealType Da)
 {
@@ -703,6 +737,40 @@ static inline void CompositeLighten(const MagickPixelPacket *p,
   }
 }
 
+static inline void CompositeLightenIntensity(const MagickPixelPacket *p,
+  const MagickPixelPacket *q,const ChannelType channel,
+  MagickPixelPacket *composite)
+{
+  /*
+    Select the pixel based on the intensity level.
+    If 'Sync' flag select whole pixel based on alpha weighted intensity.
+    Otherwise use Intenisty only, but restrict copy according to channel.
+  */
+  if ( (channel & SyncChannels) != 0 ) {
+    MagickRealType
+      Da,
+      Sa;
+
+    Sa=1.0-QuantumScale*p->opacity;
+    Da=1.0-QuantumScale*q->opacity;
+    *composite = (Sa*MagickPixelIntensity(p) > Da*MagickPixelIntensity(q))
+               ? *p : *q;
+  }
+  else {
+    int from_p = (MagickPixelIntensity(p) > MagickPixelIntensity(q));
+    if ( (channel & AlphaChannel) != 0 )
+      composite->opacity = from_p ? p->opacity : q->opacity;
+    if ( (channel & RedChannel) != 0 )
+      composite->red = from_p ? p->red : q->red;
+    if ( (channel & GreenChannel) != 0 )
+      composite->green = from_p ? p->green : q->green;
+    if ( (channel & BlueChannel) != 0 )
+      composite->blue = from_p ? p->blue : q->blue;
+    if ( (channel & IndexChannel) != 0 && q->colorspace == CMYKColorspace)
+      composite->index = from_p ? p->index : q->index;
+  }
+}
+
 #if 0
 static inline MagickRealType LinearDodge(const MagickRealType Sca,
   const MagickRealType Sa,const MagickRealType Dca,const MagickRealType Da)
@@ -2430,6 +2498,16 @@ MagickExport MagickBooleanType CompositeImageChannel(Image *image,
           CompositeLighten(&source,&destination,channel,&composite);
           break;
         }
+        case DarkenIntensityCompositeOp:
+        {
+          CompositeDarkenIntensity(&source,&destination,channel,&composite);
+          break;
+        }
+        case LightenIntensityCompositeOp:
+        {
+          CompositeLightenIntensity(&source,&destination,channel,&composite);
+          break;
+        }
         case MathematicsCompositeOp:
         {
           CompositeMathematics(&source,&destination,channel,&geometry_info,
index 9c4d524759c5f0b9daac3d3a290caa2a1c8d3434..4373c2557fd4493ee03eaf11874580ca7dd931d6 100644 (file)
@@ -93,7 +93,9 @@ typedef enum
   LinearBurnCompositeOp,
   MathematicsCompositeOp,
   DivideSrcCompositeOp,
-  MinusSrcCompositeOp
+  MinusSrcCompositeOp,
+  DarkenIntensityCompositeOp,
+  LightenIntensityCompositeOp
 } CompositeOperator;
 
 /* Depreciated (renamed) Method Names for backward compatibility
index 928fdae2491d83a46f02367b779934bf11f59566..415a37b6820acde3895f4fd9221a07a337c2175f 100644 (file)
@@ -723,6 +723,7 @@ static const OptionInfo
     { "CopyRed", (ssize_t) CopyRedCompositeOp, MagickFalse },
     { "CopyYellow", (ssize_t) CopyYellowCompositeOp, MagickFalse },
     { "Darken", (ssize_t) DarkenCompositeOp, MagickFalse },
+    { "DarkenIntensity", (ssize_t) DarkenIntensityCompositeOp, MagickFalse },
     { "DivideDst", (ssize_t) DivideDstCompositeOp, MagickFalse },
     { "DivideSrc", (ssize_t) DivideSrcCompositeOp, MagickFalse },
     { "Dst", (ssize_t) DstCompositeOp, MagickFalse },
@@ -740,6 +741,7 @@ static const OptionInfo
     { "Hue", (ssize_t) HueCompositeOp, MagickFalse },
     { "In", (ssize_t) InCompositeOp, MagickFalse },
     { "Lighten", (ssize_t) LightenCompositeOp, MagickFalse },
+    { "LightenIntensity", (ssize_t) LightenIntensityCompositeOp, MagickFalse },
     { "LinearBurn", (ssize_t) LinearBurnCompositeOp, MagickFalse },
     { "LinearDodge", (ssize_t) LinearDodgeCompositeOp, MagickFalse },
     { "LinearLight", (ssize_t) LinearLightCompositeOp, MagickFalse },