% Methods to Paint on an Image %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1998 %
% %
% %
-% 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/artifact.h"
+#include "MagickCore/channel.h"
#include "MagickCore/color.h"
#include "MagickCore/color-private.h"
#include "MagickCore/colorspace-private.h"
#include "MagickCore/gem-private.h"
#include "MagickCore/monitor.h"
#include "MagickCore/monitor-private.h"
+#include "MagickCore/option.h"
#include "MagickCore/paint.h"
#include "MagickCore/pixel-accessor.h"
#include "MagickCore/resource_.h"
#include "MagickCore/statistic.h"
#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
#include "MagickCore/thread-private.h"
\f
/*
const ssize_t y_offset,const MagickBooleanType invert,
ExceptionInfo *exception)
{
-#define MaxStacksize (1UL << 15)
+#define MaxStacksize 524288UL
#define PushSegmentStack(up,left,right,delta) \
{ \
if (s >= (segment_stack+MaxStacksize)) \
skip,
status;
+ MemoryInfo
+ *segment_info;
+
PixelInfo
fill_color,
pixel;
ssize_t
offset,
start,
- x,
x1,
x2,
y;
Check boundary conditions.
*/
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(draw_info != (DrawInfo *) NULL);
- assert(draw_info->signature == MagickSignature);
+ assert(draw_info->signature == MagickCoreSignature);
if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
return(MagickFalse);
if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
- (void) TransformImageColorspace(image,RGBColorspace,exception);
- if ((image->alpha_trait != BlendPixelTrait) && (draw_info->fill.alpha_trait == BlendPixelTrait))
+ (void) SetImageColorspace(image,sRGBColorspace,exception);
+ if ((image->alpha_trait == UndefinedPixelTrait) &&
+ (draw_info->fill.alpha_trait != UndefinedPixelTrait))
(void) SetImageAlpha(image,OpaqueAlpha,exception);
/*
Set floodfill state.
*/
- floodplane_image=CloneImage(image,image->columns,image->rows,MagickTrue,
+ floodplane_image=CloneImage(image,0,0,MagickTrue,
exception);
if (floodplane_image == (Image *) NULL)
return(MagickFalse);
(void) QueryColorCompliance("#000",AllCompliance,
&floodplane_image->background_color,exception);
(void) SetImageBackgroundColor(floodplane_image,exception);
- segment_stack=(SegmentInfo *) AcquireQuantumMemory(MaxStacksize,
- sizeof(*segment_stack));
- if (segment_stack == (SegmentInfo *) NULL)
+ segment_info=AcquireVirtualMemory(MaxStacksize,sizeof(*segment_stack));
+ if (segment_info == (MemoryInfo *) NULL)
{
floodplane_image=DestroyImage(floodplane_image);
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
}
+ segment_stack=(SegmentInfo *) GetVirtualMemoryBlob(segment_info);
/*
Push initial segment on stack.
*/
status=MagickTrue;
- x=x_offset;
- y=y_offset;
start=0;
s=segment_stack;
- PushSegmentStack(y,x,x,1);
- PushSegmentStack(y+1,x,x,-1);
+ PushSegmentStack(y_offset,x_offset,x_offset,1);
+ PushSegmentStack(y_offset+1,x_offset,x_offset,-1);
GetPixelInfo(image,&pixel);
image_view=AcquireVirtualCacheView(image,exception);
floodplane_view=AcquireAuthenticCacheView(floodplane_image,exception);
while (s > segment_stack)
{
register const Quantum
- *restrict p;
+ *magick_restrict p;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
x;
start=x;
} while (x <= x2);
}
+ status=MagickTrue;
for (y=0; y < (ssize_t) image->rows; y++)
{
register const Quantum
- *restrict p;
+ *magick_restrict p;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
x;
/*
Tile fill color onto floodplane.
*/
+ if (status == MagickFalse)
+ continue;
p=GetCacheViewVirtualPixels(floodplane_view,0,y,image->columns,1,exception);
q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
- break;
+ {
+ status=MagickFalse;
+ continue;
+ }
for (x=0; x < (ssize_t) image->columns; x++)
{
if (GetPixelGray(floodplane_image,p) != 0)
{
- (void) GetFillColor(draw_info,x,y,&fill_color,exception);
- SetPixelInfoPixel(image,&fill_color,q);
+ GetFillColor(draw_info,x,y,&fill_color,exception);
+ SetPixelViaPixelInfo(image,&fill_color,q);
}
p+=GetPixelChannels(floodplane_image);
q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
- break;
+ status=MagickFalse;
}
floodplane_view=DestroyCacheView(floodplane_view);
image_view=DestroyCacheView(image_view);
- segment_stack=(SegmentInfo *) RelinquishMagickMemory(segment_stack);
+ segment_info=RelinquishVirtualMemory(segment_info);
floodplane_image=DestroyImage(floodplane_image);
- return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
+ return(status);
}
\f
/*
% o exception: return any errors or warnings in this structure.
%
*/
-
-static inline double MagickMax(const double x,const double y)
-{
- return(x > y ? x : y);
-}
-
MagickExport MagickBooleanType GradientImage(Image *image,
- const GradientType type,const SpreadMethod method,
- const PixelInfo *start_color,const PixelInfo *stop_color,
- ExceptionInfo *exception)
+ const GradientType type,const SpreadMethod method,const StopInfo *stops,
+ const size_t number_stops,ExceptionInfo *exception)
{
+ const char
+ *artifact;
+
DrawInfo
*draw_info;
MagickBooleanType
status;
- register ssize_t
- i;
-
/*
Set gradient start-stop end points.
*/
assert(image != (const Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- assert(start_color != (const PixelInfo *) NULL);
- assert(stop_color != (const PixelInfo *) NULL);
+ assert(stops != (const StopInfo *) NULL);
+ assert(number_stops > 0);
draw_info=AcquireDrawInfo();
gradient=(&draw_info->gradient);
gradient->type=type;
gradient->bounding_box.width=image->columns;
gradient->bounding_box.height=image->rows;
- gradient->gradient_vector.x2=(double) image->columns-1.0;
- gradient->gradient_vector.y2=(double) image->rows-1.0;
- if ((type == LinearGradient) && (gradient->gradient_vector.y2 != 0.0))
- gradient->gradient_vector.x2=0.0;
+ artifact=GetImageArtifact(image,"gradient:bounding-box");
+ if (artifact != (const char *) NULL)
+ (void) ParseAbsoluteGeometry(artifact,&gradient->bounding_box);
+ gradient->gradient_vector.x2=(double) image->columns-1;
+ gradient->gradient_vector.y2=(double) image->rows-1;
+ artifact=GetImageArtifact(image,"gradient:direction");
+ if (artifact != (const char *) NULL)
+ {
+ GravityType
+ direction;
+
+ direction=(GravityType) ParseCommandOption(MagickGravityOptions,
+ MagickFalse,artifact);
+ switch (direction)
+ {
+ case NorthWestGravity:
+ {
+ gradient->gradient_vector.x1=(double) image->columns-1;
+ gradient->gradient_vector.y1=(double) image->rows-1;
+ gradient->gradient_vector.x2=0.0;
+ gradient->gradient_vector.y2=0.0;
+ break;
+ }
+ case NorthGravity:
+ {
+ gradient->gradient_vector.x1=0.0;
+ gradient->gradient_vector.y1=(double) image->rows-1;
+ gradient->gradient_vector.x2=0.0;
+ gradient->gradient_vector.y2=0.0;
+ break;
+ }
+ case NorthEastGravity:
+ {
+ gradient->gradient_vector.x1=0.0;
+ gradient->gradient_vector.y1=(double) image->rows-1;
+ gradient->gradient_vector.x2=(double) image->columns-1;
+ gradient->gradient_vector.y2=0.0;
+ break;
+ }
+ case WestGravity:
+ {
+ gradient->gradient_vector.x1=(double) image->columns-1;
+ gradient->gradient_vector.y1=0.0;
+ gradient->gradient_vector.x2=0.0;
+ gradient->gradient_vector.y2=0.0;
+ break;
+ }
+ case EastGravity:
+ {
+ gradient->gradient_vector.x1=0.0;
+ gradient->gradient_vector.y1=0.0;
+ gradient->gradient_vector.x2=(double) image->columns-1;
+ gradient->gradient_vector.y2=0.0;
+ break;
+ }
+ case SouthWestGravity:
+ {
+ gradient->gradient_vector.x1=(double) image->columns-1;
+ gradient->gradient_vector.y1=0.0;
+ gradient->gradient_vector.x2=0.0;
+ gradient->gradient_vector.y2=(double) image->rows-1;
+ break;
+ }
+ case SouthGravity:
+ {
+ gradient->gradient_vector.x1=0.0;
+ gradient->gradient_vector.y1=0.0;
+ gradient->gradient_vector.x2=0.0;
+ gradient->gradient_vector.y2=(double) image->columns-1;
+ break;
+ }
+ case SouthEastGravity:
+ {
+ gradient->gradient_vector.x1=0.0;
+ gradient->gradient_vector.y1=0.0;
+ gradient->gradient_vector.x2=(double) image->columns-1;
+ gradient->gradient_vector.y2=(double) image->rows-1;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ artifact=GetImageArtifact(image,"gradient:angle");
+ if (artifact != (const char *) NULL)
+ gradient->angle=StringToDouble(artifact,(char **) NULL);
+ artifact=GetImageArtifact(image,"gradient:vector");
+ if (artifact != (const char *) NULL)
+ (void) sscanf(artifact,"%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf",
+ &gradient->gradient_vector.x1,&gradient->gradient_vector.y1,
+ &gradient->gradient_vector.x2,&gradient->gradient_vector.y2);
+ if ((GetImageArtifact(image,"gradient:angle") == (const char *) NULL) &&
+ (GetImageArtifact(image,"gradient:direction") == (const char *) NULL) &&
+ (GetImageArtifact(image,"gradient:extent") == (const char *) NULL) &&
+ (GetImageArtifact(image,"gradient:vector") == (const char *) NULL))
+ if ((type == LinearGradient) && (gradient->gradient_vector.y2 != 0.0))
+ gradient->gradient_vector.x2=0.0;
gradient->center.x=(double) gradient->gradient_vector.x2/2.0;
gradient->center.y=(double) gradient->gradient_vector.y2/2.0;
- gradient->radius=MagickMax(gradient->center.x,gradient->center.y);
+ artifact=GetImageArtifact(image,"gradient:center");
+ if (artifact != (const char *) NULL)
+ (void) sscanf(artifact,"%lf%*[ ,]%lf",&gradient->center.x,
+ &gradient->center.y);
+ artifact=GetImageArtifact(image,"gradient:angle");
+ if ((type == LinearGradient) && (artifact != (const char *) NULL))
+ {
+ double
+ sine,
+ cosine,
+ distance;
+
+ /*
+ Reference https://drafts.csswg.org/css-images-3/#linear-gradients.
+ */
+ sine=sin((double) DegreesToRadians(gradient->angle-90.0));
+ cosine=cos((double) DegreesToRadians(gradient->angle-90.0));
+ distance=fabs((double) (image->columns-1.0)*cosine)+
+ fabs((double) (image->rows-1.0)*sine);
+ gradient->gradient_vector.x1=0.5*((image->columns-1.0)-distance*cosine);
+ gradient->gradient_vector.y1=0.5*((image->rows-1.0)-distance*sine);
+ gradient->gradient_vector.x2=0.5*((image->columns-1.0)+distance*cosine);
+ gradient->gradient_vector.y2=0.5*((image->rows-1.0)+distance*sine);
+ }
+ gradient->radii.x=(double) MagickMax((image->columns-1.0),(image->rows-1.0))/
+ 2.0;
+ gradient->radii.y=gradient->radii.x;
+ artifact=GetImageArtifact(image,"gradient:extent");
+ if (artifact != (const char *) NULL)
+ {
+ if (LocaleCompare(artifact,"Circle") == 0)
+ {
+ gradient->radii.x=(double) MagickMax((image->columns-1.0),
+ (image->rows-1.0))/2.0;
+ gradient->radii.y=gradient->radii.x;
+ }
+ if (LocaleCompare(artifact,"Diagonal") == 0)
+ {
+ gradient->radii.x=(double) (sqrt((double) (image->columns-1.0)*
+ (image->columns-1.0)+(image->rows-1.0)*(image->rows-1.0)))/2.0;
+ gradient->radii.y=gradient->radii.x;
+ }
+ if (LocaleCompare(artifact,"Ellipse") == 0)
+ {
+ gradient->radii.x=(double) (image->columns-1.0)/2.0;
+ gradient->radii.y=(double) (image->rows-1.0)/2.0;
+ }
+ if (LocaleCompare(artifact,"Maximum") == 0)
+ {
+ gradient->radii.x=(double) MagickMax((image->columns-1.0),
+ (image->rows-1.0))/2.0;
+ gradient->radii.y=gradient->radii.x;
+ }
+ if (LocaleCompare(artifact,"Minimum") == 0)
+ {
+ gradient->radii.x=(double) (MagickMin((image->columns-1.0),
+ (image->rows-1.0)))/2.0;
+ gradient->radii.y=gradient->radii.x;
+ }
+ }
+ artifact=GetImageArtifact(image,"gradient:radii");
+ if (artifact != (const char *) NULL)
+ (void) sscanf(artifact,"%lf%*[ ,]%lf",&gradient->radii.x,
+ &gradient->radii.y);
+ gradient->radius=MagickMax(gradient->radii.x,gradient->radii.y);
gradient->spread=method;
/*
Define the gradient to fill between the stops.
*/
- gradient->number_stops=2;
+ gradient->number_stops=number_stops;
gradient->stops=(StopInfo *) AcquireQuantumMemory(gradient->number_stops,
sizeof(*gradient->stops));
if (gradient->stops == (StopInfo *) NULL)
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
image->filename);
- (void) ResetMagickMemory(gradient->stops,0,gradient->number_stops*
- sizeof(*gradient->stops));
- for (i=0; i < (ssize_t) gradient->number_stops; i++)
- GetPixelInfo(image,&gradient->stops[i].color);
- gradient->stops[0].color=(*start_color);
- gradient->stops[0].offset=0.0;
- gradient->stops[1].color=(*stop_color);
- gradient->stops[1].offset=1.0;
+ (void) memcpy(gradient->stops,stops,(size_t) number_stops*
+ sizeof(*stops));
/*
Draw a gradient on the image.
*/
- (void) SetImageColorspace(image,start_color->colorspace,exception);
status=DrawGradientImage(image,draw_info,exception);
draw_info=DestroyDrawInfo(draw_info);
return(status);
histogram=(size_t **) AcquireQuantumMemory(number_threads,sizeof(*histogram));
if (histogram == (size_t **) NULL)
return((size_t **) NULL);
- (void) ResetMagickMemory(histogram,0,number_threads*sizeof(*histogram));
+ (void) memset(histogram,0,number_threads*sizeof(*histogram));
for (i=0; i < (ssize_t) number_threads; i++)
{
histogram[i]=(size_t *) AcquireQuantumMemory(count,sizeof(**histogram));
*paint_view;
Image
+ *linear_image,
*paint_image;
MagickBooleanType
Initialize painted image attributes.
*/
assert(image != (const Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
+ assert(exception->signature == MagickCoreSignature);
width=GetOptimalKernelWidth2D(radius,sigma);
- paint_image=CloneImage(image,image->columns,image->rows,MagickTrue,exception);
- if (paint_image == (Image *) NULL)
- return((Image *) NULL);
+ linear_image=CloneImage(image,0,0,MagickTrue,exception);
+ paint_image=CloneImage(image,0,0,MagickTrue,exception);
+ if ((linear_image == (Image *) NULL) || (paint_image == (Image *) NULL))
+ {
+ if (linear_image != (Image *) NULL)
+ linear_image=DestroyImage(linear_image);
+ if (paint_image != (Image *) NULL)
+ linear_image=DestroyImage(paint_image);
+ return((Image *) NULL);
+ }
if (SetImageStorageClass(paint_image,DirectClass,exception) == MagickFalse)
{
+ linear_image=DestroyImage(linear_image);
paint_image=DestroyImage(paint_image);
return((Image *) NULL);
}
histograms=AcquireHistogramThreadSet(NumberPaintBins);
if (histograms == (size_t **) NULL)
{
+ linear_image=DestroyImage(linear_image);
paint_image=DestroyImage(paint_image);
ThrowImageException(ResourceLimitError,"MemoryAllocationFailed");
}
*/
status=MagickTrue;
progress=0;
- center=(ssize_t) GetPixelChannels(image)*(image->columns+width)*(width/2L)+
- GetPixelChannels(image)*(width/2L);
- image_view=AcquireVirtualCacheView(image,exception);
+ center=(ssize_t) GetPixelChannels(linear_image)*(linear_image->columns+width)*
+ (width/2L)+GetPixelChannels(linear_image)*(width/2L);
+ image_view=AcquireVirtualCacheView(linear_image,exception);
paint_view=AcquireAuthenticCacheView(paint_image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static) shared(progress,status) \
+ magick_number_threads(linear_image,paint_image,linear_image->rows,1)
#endif
- for (y=0; y < (ssize_t) image->rows; y++)
+ for (y=0; y < (ssize_t) linear_image->rows; y++)
{
register const Quantum
- *restrict p;
+ *magick_restrict p;
register Quantum
- *restrict q;
+ *magick_restrict q;
register size_t
*histogram;
if (status == MagickFalse)
continue;
p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t)
- (width/2L),image->columns+width,width,exception);
+ (width/2L),linear_image->columns+width,width,exception);
q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1,
exception);
if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
continue;
}
histogram=histograms[GetOpenMPThreadId()];
- for (x=0; x < (ssize_t) image->columns; x++)
+ for (x=0; x < (ssize_t) linear_image->columns; x++)
{
register ssize_t
i,
k=0;
j=0;
count=0;
- (void) ResetMagickMemory(histogram,0,NumberPaintBins* sizeof(*histogram));
+ (void) memset(histogram,0,NumberPaintBins* sizeof(*histogram));
for (v=0; v < (ssize_t) width; v++)
{
for (u=0; u < (ssize_t) width; u++)
{
- n=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,
- p+GetPixelChannels(image)*(u+k))));
+ n=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(
+ linear_image,p+GetPixelChannels(linear_image)*(u+k))));
histogram[n]++;
if (histogram[n] > count)
{
count=histogram[n];
}
}
- k+=(ssize_t) (image->columns+width);
+ k+=(ssize_t) (linear_image->columns+width);
}
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ for (i=0; i < (ssize_t) GetPixelChannels(linear_image); i++)
{
- PixelChannel
- channel;
-
- PixelTrait
- paint_traits,
- traits;
-
- channel=GetPixelChannelChannel(image,i);
- traits=GetPixelChannelTraits(image,channel);
- paint_traits=GetPixelChannelTraits(paint_image,channel);
+ PixelChannel channel = GetPixelChannelChannel(linear_image,i);
+ PixelTrait traits = GetPixelChannelTraits(linear_image,channel);
+ PixelTrait paint_traits=GetPixelChannelTraits(paint_image,channel);
if ((traits == UndefinedPixelTrait) ||
(paint_traits == UndefinedPixelTrait))
continue;
- if (((paint_traits & CopyPixelTrait) != 0) ||
- (GetPixelMask(image,p) != 0))
+ if ((paint_traits & CopyPixelTrait) != 0)
{
SetPixelChannel(paint_image,channel,p[center+i],q);
continue;
}
- SetPixelChannel(paint_image,channel,p[j*GetPixelChannels(image)+i],q);
+ SetPixelChannel(paint_image,channel,p[j*GetPixelChannels(linear_image)+
+ i],q);
}
- p+=GetPixelChannels(image);
+ p+=GetPixelChannels(linear_image);
q+=GetPixelChannels(paint_image);
}
if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse)
status=MagickFalse;
- if (image->progress_monitor != (MagickProgressMonitor) NULL)
+ if (linear_image->progress_monitor != (MagickProgressMonitor) NULL)
{
MagickBooleanType
proceed;
#if defined(MAGICKCORE_OPENMP_SUPPORT)
#pragma omp critical (MagickCore_OilPaintImage)
#endif
- proceed=SetImageProgress(image,OilPaintImageTag,progress++,image->rows);
+ proceed=SetImageProgress(linear_image,OilPaintImageTag,progress++,
+ linear_image->rows);
if (proceed == MagickFalse)
status=MagickFalse;
}
paint_view=DestroyCacheView(paint_view);
image_view=DestroyCacheView(image_view);
histograms=DestroyHistogramThreadSet(histograms);
+ linear_image=DestroyImage(linear_image);
if (status == MagickFalse)
paint_image=DestroyImage(paint_image);
return(paint_image);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% OpaquePaintImage() changes any pixel that matches color with the color
-% defined by fill.
+% defined by fill argument.
%
% By default color must match a particular pixel color exactly. However, in
% many cases two colors may differ by a small amount. Fuzz defines how much
%
% The format of the OpaquePaintImage method is:
%
-% MagickBooleanType OpaquePaintImage(Image *image,
-% const PixelInfo *target,const PixelInfo *fill,
-% const MagickBooleanType invert,ExceptionInfo *exception)
+% MagickBooleanType OpaquePaintImage(Image *image,const PixelInfo *target,
+% const PixelInfo *fill,const MagickBooleanType invert,
+% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
progress;
PixelInfo
+ conform_fill,
+ conform_target,
zero;
ssize_t
y;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(target != (PixelInfo *) NULL);
assert(fill != (PixelInfo *) NULL);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
- if ((IsGrayColorspace(image->colorspace) != MagickFalse) &&
- (IsPixelInfoGray(fill) == MagickFalse))
- (void) TransformImageColorspace(image,RGBColorspace,exception);
- if ((fill->alpha_trait == BlendPixelTrait) && (image->alpha_trait != BlendPixelTrait))
- (void) SetImageAlpha(image,OpaqueAlpha,exception);
+ ConformPixelInfo(image,fill,&conform_fill,exception);
+ ConformPixelInfo(image,target,&conform_target,exception);
/*
Make image color opaque.
*/
GetPixelInfo(image,&zero);
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static) shared(progress,status) \
+ magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
pixel;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
x;
for (x=0; x < (ssize_t) image->columns; x++)
{
GetPixelInfoPixel(image,q,&pixel);
- if (IsFuzzyEquivalencePixelInfo(&pixel,target) != invert)
- SetPixelInfoPixel(image,fill,q);
+ if (IsFuzzyEquivalencePixelInfo(&pixel,&conform_target) != invert)
+ {
+ PixelTrait
+ traits;
+
+ traits=GetPixelChannelTraits(image,RedPixelChannel);
+ if ((traits & UpdatePixelTrait) != 0)
+ SetPixelRed(image,(Quantum) conform_fill.red,q);
+ traits=GetPixelChannelTraits(image,GreenPixelChannel);
+ if ((traits & UpdatePixelTrait) != 0)
+ SetPixelGreen(image,(Quantum) conform_fill.green,q);
+ traits=GetPixelChannelTraits(image,BluePixelChannel);
+ if ((traits & UpdatePixelTrait) != 0)
+ SetPixelBlue(image,(Quantum) conform_fill.blue,q);
+ traits=GetPixelChannelTraits(image,BlackPixelChannel);
+ if ((traits & UpdatePixelTrait) != 0)
+ SetPixelBlack(image,(Quantum) conform_fill.black,q);
+ traits=GetPixelChannelTraits(image,AlphaPixelChannel);
+ if ((traits & UpdatePixelTrait) != 0)
+ SetPixelAlpha(image,(Quantum) conform_fill.alpha,q);
+ }
q+=GetPixelChannels(image);
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
y;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(target != (PixelInfo *) NULL);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
- if (image->alpha_trait != BlendPixelTrait)
+ if (image->alpha_trait == UndefinedPixelTrait)
(void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
/*
Make image color transparent.
GetPixelInfo(image,&zero);
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static) shared(progress,status) \
+ magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
x;
register Quantum
- *restrict q;
+ *magick_restrict q;
if (status == MagickFalse)
continue;
y;
assert(image != (Image *) NULL);
- assert(image->signature == MagickSignature);
+ assert(image->signature == MagickCoreSignature);
assert(high != (PixelInfo *) NULL);
assert(low != (PixelInfo *) NULL);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
return(MagickFalse);
- if (image->alpha_trait != BlendPixelTrait)
+ if (image->alpha_trait == UndefinedPixelTrait)
(void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
/*
Make image color transparent.
progress=0;
image_view=AcquireAuthenticCacheView(image,exception);
#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(progress,status) \
- dynamic_number_threads(image,image->columns,image->rows,1)
+ #pragma omp parallel for schedule(static) shared(progress,status) \
+ magick_number_threads(image,image,image->rows,1)
#endif
for (y=0; y < (ssize_t) image->rows; y++)
{
pixel;
register Quantum
- *restrict q;
+ *magick_restrict q;
register ssize_t
x;