]> granicus.if.org Git - imagemagick/blobdiff - coders/gradient.c
...
[imagemagick] / coders / gradient.c
index 03c927b41011fb79d197c587cb7fe4c41aaae013..faa4a660cd1273397745c398a20ddbf96736410f 100644 (file)
 %                   Read An Image Filled Using Gradient.                      %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2018 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  %
 %  obtain a copy of the License at                                            %
 %                                                                             %
-%    http://www.imagemagick.org/script/license.php                            %
+%    https://imagemagick.org/script/license.php                               %
 %                                                                             %
 %  Unless required by applicable law or agreed to in writing, software        %
 %  distributed under the License is distributed on an "AS IS" BASIS,          %
   Include declarations.
 */
 #include "MagickCore/studio.h"
+#include "MagickCore/attribute.h"
 #include "MagickCore/blob.h"
 #include "MagickCore/blob-private.h"
+#include "MagickCore/channel.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
 #include "MagickCore/colorspace-private.h"
+#include "MagickCore/constitute.h"
 #include "MagickCore/draw.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/exception-private.h"
 %    o exception: return any errors or warnings in this structure.
 %
 */
+
+static Image *ReadXCImage(const ImageInfo *image_info,ExceptionInfo *exception)
+{
+  Image
+    *image;
+
+  MagickBooleanType
+    status;
+
+  PixelInfo
+    pixel;
+
+  register ssize_t
+    x;
+
+  register Quantum
+    *q;
+
+  ssize_t
+    y;
+
+  /*
+    Initialize Image structure.
+  */
+  assert(image_info != (const ImageInfo *) NULL);
+  assert(image_info->signature == MagickCoreSignature);
+  if (image_info->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+      image_info->filename);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickCoreSignature);
+  image=AcquireImage(image_info,exception);
+  if (image->columns == 0)
+    image->columns=1;
+  if (image->rows == 0)
+    image->rows=1;
+  status=SetImageExtent(image,image->columns,image->rows,exception);
+  if (status == MagickFalse)
+    return(DestroyImageList(image));
+  (void) CopyMagickString(image->filename,image_info->filename,
+    MagickPathExtent);
+  if (*image_info->filename == '\0')
+    pixel=image->background_color;
+  else
+    {
+      status=QueryColorCompliance((char *) image_info->filename,AllCompliance,
+        &pixel,exception);
+      if (status == MagickFalse)
+        {
+          image=DestroyImage(image);
+          return((Image *) NULL);
+        }
+    }
+  (void) SetImageColorspace(image,pixel.colorspace,exception);
+  image->alpha_trait=pixel.alpha_trait;
+  for (y=0; y < (ssize_t) image->rows; y++)
+  {
+    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
+    if (q == (Quantum *) NULL)
+      break;
+    for (x=0; x < (ssize_t) image->columns; x++)
+    {
+      SetPixelViaPixelInfo(image,&pixel,q);
+      q+=GetPixelChannels(image);
+    }
+    if (SyncAuthenticPixels(image,exception) == MagickFalse)
+      break;
+  }
+  return(GetFirstImageInList(image));
+}
+
 static Image *ReadGRADIENTImage(const ImageInfo *image_info,
   ExceptionInfo *exception)
 {
   char
-    colorname[MaxTextExtent];
+    colorname[MagickPathExtent+4];
 
   Image
     *image;
 
+  ImageInfo
+    *read_info;
+
   MagickBooleanType
+    icc_color,
     status;
 
-  PixelInfo
-    start_color,
-    stop_color;
+  StopInfo
+    *stops;
 
   /*
     Initialize Image structure.
   */
   assert(image_info != (const ImageInfo *) NULL);
-  assert(image_info->signature == MagickSignature);
+  assert(image_info->signature == MagickCoreSignature);
   if (image_info->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
       image_info->filename);
   assert(exception != (ExceptionInfo *) NULL);
-  assert(exception->signature == MagickSignature);
-  image=AcquireImage(image_info,exception);
-  if ((image->columns == 0) || (image->rows == 0))
-    ThrowReaderException(OptionError,"MustSpecifyImageSize");
-  (void) SetImageAlpha(image,(Quantum) TransparentAlpha,exception);
-  (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
-  (void) CopyMagickString(colorname,image_info->filename,MaxTextExtent);
+  assert(exception->signature == MagickCoreSignature);
+  read_info=CloneImageInfo(image_info);
+  SetImageInfoBlob(read_info,(void *) NULL,0);
+  (void) CopyMagickString(colorname,image_info->filename,MagickPathExtent);
   (void) sscanf(image_info->filename,"%[^-]",colorname);
-  status=QueryColorCompliance(colorname,AllCompliance,&start_color,exception);
+  (void) CopyMagickString(read_info->filename,colorname,MagickPathExtent);
+  image=ReadXCImage(read_info,exception);
+  read_info=DestroyImageInfo(read_info);
+  if (image == (Image *) NULL)
+    return((Image *) NULL);
+  (void) SetImageAlpha(image,(Quantum) TransparentAlpha,exception);
+  (void) CopyMagickString(image->filename,image_info->filename,
+    MagickPathExtent);
+  icc_color=MagickFalse;
+  if (LocaleCompare(colorname,"icc") == 0)
+    {
+      (void) ConcatenateMagickString(colorname,"-",MagickPathExtent);
+      (void) sscanf(image_info->filename,"%*[^-]-%[^-]",colorname+4);
+      icc_color=MagickTrue;
+    }
+  stops=(StopInfo *) AcquireQuantumMemory(2,sizeof(*stops));
+  if (stops == (StopInfo *) NULL)
+    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+  stops[0].offset=0.0;
+  stops[1].offset=1.0;
+  status=QueryColorCompliance(colorname,AllCompliance,&stops[0].color,
+    exception);
   if (status == MagickFalse)
     {
+      stops=(StopInfo *) RelinquishMagickMemory(stops);
       image=DestroyImage(image);
       return((Image *) NULL);
     }
-  (void) CopyMagickString(colorname,"white",MaxTextExtent);
-  if (GetPixelInfoIntensity(&start_color) > (Quantum) (QuantumRange/2))
-    (void) CopyMagickString(colorname,"black",MaxTextExtent);
-  (void) sscanf(image_info->filename,"%*[^-]-%s",colorname);
-  status=QueryColorCompliance(colorname,AllCompliance,&stop_color,exception);
+  (void) SetImageColorspace(image,stops[0].color.colorspace,exception);
+  (void) CopyMagickString(colorname,"white",MagickPathExtent);
+  if (GetPixelInfoIntensity(image,&stops[0].color) > (QuantumRange/2.0))
+    (void) CopyMagickString(colorname,"black",MagickPathExtent);
+  if (icc_color == MagickFalse)
+    (void) sscanf(image_info->filename,"%*[^-]-%[^-]",colorname);
+  else
+    (void) sscanf(image_info->filename,"%*[^-]-%*[^-]-%[^-]",colorname);
+  status=QueryColorCompliance(colorname,AllCompliance,&stops[1].color,
+    exception);
   if (status == MagickFalse)
     {
+      stops=(StopInfo *) RelinquishMagickMemory(stops);
       image=DestroyImage(image);
       return((Image *) NULL);
     }
-  if (IssRGBColorspace(start_color.colorspace) != MagickFalse)
-    {
-      start_color.red=QuantumRange*DecompandsRGB(QuantumScale*
-        start_color.red);
-      start_color.green=QuantumRange*DecompandsRGB(QuantumScale*
-        start_color.green);
-      start_color.blue=QuantumRange*DecompandsRGB(QuantumScale*
-        start_color.blue);
-    }
-  if (IssRGBColorspace(stop_color.colorspace) != MagickFalse)
-    {
-      stop_color.red=QuantumRange*DecompandsRGB(QuantumScale*
-        stop_color.red);
-      stop_color.green=QuantumRange*DecompandsRGB(QuantumScale*
-        stop_color.green);
-      stop_color.blue=QuantumRange*DecompandsRGB(QuantumScale*
-        stop_color.blue);
-    }
+  image->alpha_trait=stops[0].color.alpha_trait;
+  if (stops[1].color.alpha_trait != UndefinedPixelTrait)
+    image->alpha_trait=stops[1].color.alpha_trait;
   status=GradientImage(image,LocaleCompare(image_info->magick,"GRADIENT") == 0 ?
-    LinearGradient : RadialGradient,PadSpread,&start_color,&stop_color,
-    exception);
+    LinearGradient : RadialGradient,PadSpread,stops,2,exception);
+  stops=(StopInfo *) RelinquishMagickMemory(stops);
   if (status == MagickFalse)
     {
       image=DestroyImageList(image);
       return((Image *) NULL);
     }
-  (void) SetImageColorspace(image,start_color.colorspace,exception);
-  if ((start_color.matte == MagickFalse) && (stop_color.matte == MagickFalse))
-    (void) SetImageAlphaChannel(image,DeactivateAlphaChannel,exception);
-  if (IssRGBColorspace(start_color.colorspace) != MagickFalse)
-    {
-      (void) SetImageColorspace(image,RGBColorspace,exception);
-      (void) TransformImageColorspace(image,sRGBColorspace,exception);
-    }
   return(GetFirstImageInList(image));
 }
 \f
@@ -203,23 +282,19 @@ ModuleExport size_t RegisterGRADIENTImage(void)
   MagickInfo
     *entry;
 
-  entry=SetMagickInfo("GRADIENT");
+  entry=AcquireMagickInfo("GRADIENT","GRADIENT",
+    "Gradual linear passing from one shade to another");
   entry->decoder=(DecodeImageHandler *) ReadGRADIENTImage;
-  entry->adjoin=MagickFalse;
-  entry->raw=MagickTrue;
+  entry->flags^=CoderAdjoinFlag;
+  entry->flags|=CoderRawSupportFlag;
   entry->format_type=ImplicitFormatType;
-  entry->description=ConstantString("Gradual linear passing from one shade to "
-    "another");
-  entry->module=ConstantString("GRADIENT");
   (void) RegisterMagickInfo(entry);
-  entry=SetMagickInfo("RADIAL-GRADIENT");
+  entry=AcquireMagickInfo("GRADIENT","RADIAL-GRADIENT",
+    "Gradual radial passing from one shade to another");
   entry->decoder=(DecodeImageHandler *) ReadGRADIENTImage;
-  entry->adjoin=MagickFalse;
-  entry->raw=MagickTrue;
+  entry->flags^=CoderAdjoinFlag;
+  entry->flags|=CoderRawSupportFlag;
   entry->format_type=ImplicitFormatType;
-  entry->description=ConstantString("Gradual radial passing from one shade to "
-    "another");
-  entry->module=ConstantString("GRADIENT");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
 }