]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Mon, 29 Sep 2014 12:43:59 +0000 (12:43 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Mon, 29 Sep 2014 12:43:59 +0000 (12:43 +0000)
MagickCore/channel.c
MagickCore/colorspace.c
MagickCore/colorspace.h
MagickCore/image.h
MagickCore/option.c

index 58cb1578ec0ddada2f29088fec5f407eeb6b6214..abd2a13b427da80630e49d92611a59940a35fd50 100644 (file)
@@ -857,9 +857,9 @@ MagickExport Image *SeparateImages(const Image *image,ExceptionInfo *exception)
 %    o image: the image.
 %
 %    o alpha_type:  The alpha channel type: ActivateAlphaChannel,
-%      CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
-%      OpaqueAlphaChannel, SetAlphaChannel, ShapeAlphaChannel, and
-%      TransparentAlphaChannel.
+%      AssociateAlphaChannel, CopyAlphaChannel, DeactivateAlphaChannel,
+%      DisassociateAlphaChannel,  ExtractAlphaChannel, OpaqueAlphaChannel,
+%      SetAlphaChannel, ShapeAlphaChannel, and TransparentAlphaChannel.
 %
 %    o exception: return any errors or warnings in this structure.
 %
@@ -930,9 +930,15 @@ static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p,
 MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
   const AlphaChannelOption alpha_type,ExceptionInfo *exception)
 {
+  CacheView
+    *image_view;
+
   MagickBooleanType
     status;
 
+  ssize_t
+    y;
+
   assert(image != (Image *) NULL);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
@@ -945,20 +951,76 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
       image->alpha_trait=BlendPixelTrait;
       break;
     }
-    case BackgroundAlphaChannel:
+    case AssociateAlphaChannel:
     {
-      CacheView
-        *image_view;
+      /*
+        Associate alpha.
+      */
+      status=SetImageStorageClass(image,DirectClass,exception);
+      if (status == MagickFalse)
+        break;
+      image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        magick_threads(image,image,image->rows,1)
+#endif
+      for (y=0; y < (ssize_t) image->rows; y++)
+      {
+        register Quantum
+          *restrict q;
 
-      ssize_t
-        y;
+        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++)
+        {
+          double
+            Sa;
+  
+          register ssize_t
+            i;
+  
+          if (GetPixelReadMask(image,q) == 0)
+            {
+              q+=GetPixelChannels(image);
+              continue;
+            }
+          Sa=QuantumScale*GetPixelAlpha(image,q);
+          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+          {
+            PixelChannel channel=GetPixelChannelChannel(image,i);
+            PixelTrait traits=GetPixelChannelTraits(image,channel);
+            if ((traits & UpdatePixelTrait) == 0)
+              continue;
+            q[i]=ClampToQuantum(Sa*q[i]);
+          }
+          q+=GetPixelChannels(image);
+        }
+        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+          status=MagickFalse;
+      }
+      image_view=DestroyCacheView(image_view);
+      image->alpha_trait=CopyPixelTrait;
+      return(status);
+    }
+    case BackgroundAlphaChannel:
+    {
       /*
         Set transparent pixels to background color.
       */
       if (image->alpha_trait != BlendPixelTrait)
         break;
-      if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+      status=SetImageStorageClass(image,DirectClass,exception);
+      if (status == MagickFalse)
         break;
       image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
@@ -1015,6 +1077,69 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
       image->alpha_trait=CopyPixelTrait;
       break;
     }
+    case DisassociateAlphaChannel:
+    {
+      /*
+        Disassociate alpha.
+      */
+      status=SetImageStorageClass(image,DirectClass,exception);
+      if (status == MagickFalse)
+        break;
+      image->alpha_trait=BlendPixelTrait;
+      image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+      #pragma omp parallel for schedule(static,4) shared(status) \
+        magick_threads(image,image,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++)
+        {
+          double
+            gamma, 
+            Sa;
+
+          register ssize_t
+            i;
+
+          if (GetPixelReadMask(image,q) == 0)
+            {
+              q+=GetPixelChannels(image);
+              continue;
+            }
+          Sa=QuantumScale*GetPixelAlpha(image,q);
+          gamma=PerceptibleReciprocal(Sa);
+          for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+          {
+            PixelChannel channel=GetPixelChannelChannel(image,i);
+            PixelTrait traits=GetPixelChannelTraits(image,channel);
+            if ((traits & UpdatePixelTrait) == 0)
+              continue;
+            q[i]=ClampToQuantum(gamma*q[i]);
+          }
+          q+=GetPixelChannels(image);
+        }
+        if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+          status=MagickFalse;
+      }
+      image_view=DestroyCacheView(image_view);
+      return(status);
+    }
     case ExtractAlphaChannel:
     {
       status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
@@ -1029,18 +1154,13 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
     }
     case RemoveAlphaChannel:
     {
-      CacheView
-        *image_view;
-
-      ssize_t
-        y;
-
       /*
         Remove transparency.
       */
       if (image->alpha_trait != BlendPixelTrait)
         break;
-      if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+      status=SetImageStorageClass(image,DirectClass,exception);
+      if (status == MagickFalse)
         break;
       image_view=AcquireAuthenticCacheView(image,exception);
 #if defined(MAGICKCORE_OPENMP_SUPPORT)
index ef586b9c2195eee6407fc3553f9c5d206ef485e4..3eb3941cda7a447d5cecd16a94fdfc5c17e188e1 100644 (file)
@@ -167,6 +167,20 @@ static void ConvertRGBToLuv(const double red,const double green,
   ConvertXYZToLuv(X,Y,Z,L,u,v);
 }
 
+static void ConvertRGBToxyY(const double red,const double green,
+  const double blue,double *low_x,double *low_y,double *cap_Y)
+{
+  double
+    X,
+    Y,
+    Z;
+
+  ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
+  *low_x=X/(X+Y+Z);
+  *low_y=Y/(X+Y+Z);
+  *cap_Y=Y;
+}
+
 static void ConvertRGBToYDbDr(const double red,const double green,
   const double blue,double *Y,double *Db,double *Dr)
 {
@@ -375,6 +389,7 @@ static MagickBooleanType sRGBTransformImage(Image *image,
     case LCHuvColorspace:
     case LMSColorspace:
     case LuvColorspace:
+    case xyYColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
     case YDbDrColorspace:
@@ -498,6 +513,11 @@ static MagickBooleanType sRGBTransformImage(Image *image,
               ConvertRGBToLuv(red,green,blue,&X,&Y,&Z);
               break;
             }
+            case xyYColorspace:
+            {
+              ConvertRGBToxyY(red,green,blue,&X,&Y,&Z);
+              break;
+            }
             case XYZColorspace:
             {
               ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
@@ -1076,7 +1096,7 @@ MagickExport MagickBooleanType SetImageColorspace(Image *image,
     }
   else
     if ((IsRGBColorspace(colorspace) != MagickFalse) ||
-        (colorspace == XYZColorspace))
+        (colorspace == XYZColorspace) || (colorspace == xyYColorspace))
       image->gamma=1.000;
     else
       {
@@ -1261,6 +1281,20 @@ static inline void ConvertLabToRGB(const double L,const double a,
   ConvertXYZToRGB(X,Y,Z,red,green,blue);
 }
 
+static inline void ConvertxyYToRGB(const double low_x,const double low_y,
+  const double cap_Y,double *red,double *green,double *blue)
+{
+  double
+    X,
+    Y,
+    Z;
+
+  X=cap_Y/low_y*low_x;
+  Y=cap_Y;
+  Z=cap_Y/low_y*(1.0-low_x-low_y);
+  ConvertXYZToRGB(X,Y,Z,red,green,blue);
+}
+
 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
   double *red,double *green,double *blue)
 {
@@ -1718,6 +1752,7 @@ static MagickBooleanType TransformsRGBImage(Image *image,
     case LCHuvColorspace:
     case LMSColorspace:
     case LuvColorspace:
+    case xyYColorspace:
     case XYZColorspace:
     case YCbCrColorspace:
     case YDbDrColorspace:
@@ -1841,6 +1876,11 @@ static MagickBooleanType TransformsRGBImage(Image *image,
               ConvertLuvToRGB(X,Y,Z,&red,&green,&blue);
               break;
             }
+            case xyYColorspace:
+            {
+              ConvertxyYToRGB(X,Y,Z,&red,&green,&blue);
+              break;
+            }
             case XYZColorspace:
             {
               ConvertXYZToRGB(X,Y,Z,&red,&green,&blue);
index 82498b37274e6fa3edf9576492e674954cd59c20..7687e0c3dd7187d629d72d503c06853ce06ffc0d 100644 (file)
@@ -49,6 +49,7 @@ typedef enum
   scRGBColorspace,         /* ??? */
   sRGBColorspace,          /* Default: non-linear sRGB colorspace */
   TransparentColorspace,
+  xyYColorspace,
   XYZColorspace,           /* IEEE Color Reference colorspace */
   YCbCrColorspace,
   YCCColorspace,
index a1d1a584fe1d03c40fa600133f02612edc0c5fd1..f2d4dd303471720bcb193f004389458e3e93ec7c 100644 (file)
@@ -32,9 +32,11 @@ typedef enum
 {
   UndefinedAlphaChannel,
   ActivateAlphaChannel,
+  AssociateAlphaChannel,
   BackgroundAlphaChannel,
   CopyAlphaChannel,
   DeactivateAlphaChannel,
+  DisassociateAlphaChannel,
   ExtractAlphaChannel,
   OpaqueAlphaChannel,
   RemoveAlphaChannel,
index 53b82d04ce91fe0d4736b950ac1e2c0a3305af93..6502972af2fd63afc66be34febf4f79294d9006a 100644 (file)
@@ -97,9 +97,11 @@ static const OptionInfo
   {
     { "Undefined", UndefinedAlphaChannel, UndefinedOptionFlag, MagickTrue },
     { "Activate", ActivateAlphaChannel, UndefinedOptionFlag, MagickFalse },
+    { "Associate", AssociateAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "Background", BackgroundAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "Copy", CopyAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "Deactivate", DeactivateAlphaChannel, UndefinedOptionFlag, MagickFalse },
+    { "Disassociate", DisassociateAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "Extract", ExtractAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "Off", DeactivateAlphaChannel, UndefinedOptionFlag, MagickFalse },
     { "On", ActivateAlphaChannel, UndefinedOptionFlag, MagickFalse },
@@ -916,6 +918,7 @@ static const OptionInfo
     { "scRGB", scRGBColorspace, UndefinedOptionFlag, MagickFalse },
     { "sRGB", sRGBColorspace, UndefinedOptionFlag, MagickFalse },
     { "Transparent", TransparentColorspace, UndefinedOptionFlag, MagickFalse },
+    { "xyY", xyYColorspace, UndefinedOptionFlag, MagickFalse },
     { "XYZ", XYZColorspace, UndefinedOptionFlag, MagickFalse },
     { "YCbCr", YCbCrColorspace, UndefinedOptionFlag, MagickFalse },
     { "YDbDr", YDbDrColorspace, UndefinedOptionFlag, MagickFalse },