42#include "MagickCore/studio.h"
43#include "MagickCore/artifact.h"
44#include "MagickCore/channel.h"
45#include "MagickCore/color.h"
46#include "MagickCore/color-private.h"
47#include "MagickCore/colorspace-private.h"
48#include "MagickCore/composite.h"
49#include "MagickCore/composite-private.h"
50#include "MagickCore/draw.h"
51#include "MagickCore/draw-private.h"
52#include "MagickCore/exception.h"
53#include "MagickCore/exception-private.h"
54#include "MagickCore/gem.h"
55#include "MagickCore/gem-private.h"
56#include "MagickCore/monitor.h"
57#include "MagickCore/monitor-private.h"
58#include "MagickCore/option.h"
59#include "MagickCore/paint.h"
60#include "MagickCore/pixel-accessor.h"
61#include "MagickCore/resource_.h"
62#include "MagickCore/statistic.h"
63#include "MagickCore/string_.h"
64#include "MagickCore/string-private.h"
65#include "MagickCore/thread-private.h"
112MagickExport MagickBooleanType FloodfillPaintImage(
Image *image,
114 const ssize_t y_offset,
const MagickBooleanType invert,
117#define MaxStacksize 524288UL
118#define PushSegmentStack(up,left,right,delta) \
120 if (s >= (segment_stack+MaxStacksize)) \
122 segment_info=RelinquishVirtualMemory(segment_info); \
123 image_view=DestroyCacheView(image_view); \
124 floodplane_view=DestroyCacheView(floodplane_view); \
125 floodplane_image=DestroyImage(floodplane_image); \
126 ThrowBinaryException(DrawError,"SegmentStackOverflow",image->filename) \
130 if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (ssize_t) image->rows)) \
132 s->x1=(double) (left); \
133 s->y1=(double) (up); \
134 s->x2=(double) (right); \
135 s->y2=(double) (delta); \
174 assert(image != (
Image *) NULL);
175 assert(image->signature == MagickCoreSignature);
176 assert(draw_info != (
DrawInfo *) NULL);
177 assert(draw_info->signature == MagickCoreSignature);
178 if (IsEventLogging() != MagickFalse)
179 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
180 if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns))
182 if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows))
184 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
186 if (IsGrayColorspace(image->colorspace) != MagickFalse)
187 (void) SetImageColorspace(image,sRGBColorspace,exception);
188 if (((image->alpha_trait & BlendPixelTrait) == 0) &&
189 (draw_info->fill.alpha_trait != UndefinedPixelTrait))
190 (void) SetImageAlpha(image,OpaqueAlpha,exception);
194 floodplane_image=CloneImage(image,0,0,MagickTrue,exception);
195 if (floodplane_image == (
Image *) NULL)
197 floodplane_image->alpha_trait=UndefinedPixelTrait;
198 floodplane_image->colorspace=GRAYColorspace;
199 (void) QueryColorCompliance(
"#000",AllCompliance,
200 &floodplane_image->background_color,exception);
201 (void) SetImageBackgroundColor(floodplane_image,exception);
202 segment_info=AcquireVirtualMemory(MaxStacksize,
sizeof(*segment_stack));
205 floodplane_image=DestroyImage(floodplane_image);
206 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
209 segment_stack=(
SegmentInfo *) GetVirtualMemoryBlob(segment_info);
216 GetPixelInfo(image,&pixel);
217 image_view=AcquireVirtualCacheView(image,exception);
218 floodplane_view=AcquireAuthenticCacheView(floodplane_image,exception);
219 PushSegmentStack(y_offset,x_offset,x_offset,1);
220 PushSegmentStack(y_offset+1,x_offset,x_offset,-1);
221 while (s > segment_stack)
238 offset=(ssize_t) s->y2;
239 y=(ssize_t) s->y1+offset;
243 p=GetCacheViewVirtualPixels(image_view,0,y,(
size_t) (x1+1),1,exception);
244 q=GetCacheViewAuthenticPixels(floodplane_view,0,y,(
size_t) (x1+1),1,
246 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
248 p+=(ptrdiff_t) x1*(ssize_t) GetPixelChannels(image);
249 q+=(ptrdiff_t) x1*(ssize_t) GetPixelChannels(floodplane_image);
250 for (x=x1; x >= 0; x--)
252 if (GetPixelGray(floodplane_image,q) != 0)
254 GetPixelInfoPixel(image,p,&pixel);
255 if (IsFuzzyEquivalencePixelInfo(&pixel,target) == invert)
257 SetPixelGray(floodplane_image,QuantumRange,q);
258 p-=(ptrdiff_t)GetPixelChannels(image);
259 q-=GetPixelChannels(floodplane_image);
261 if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse)
263 skip=x >= x1 ? MagickTrue : MagickFalse;
264 if (skip == MagickFalse)
268 PushSegmentStack(y,start,x1-1,-offset);
273 if (skip == MagickFalse)
275 if (x < (ssize_t) image->columns)
277 p=GetCacheViewVirtualPixels(image_view,x,y,(
size_t)
278 ((ssize_t) image->columns-x),1,exception);
279 q=GetCacheViewAuthenticPixels(floodplane_view,x,y,(
size_t)
280 ((ssize_t) image->columns-x),1,exception);
281 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
283 for ( ; x < (ssize_t) image->columns; x++)
285 if (GetPixelGray(floodplane_image,q) != 0)
287 GetPixelInfoPixel(image,p,&pixel);
288 if (IsFuzzyEquivalencePixelInfo(&pixel,target) == invert)
290 SetPixelGray(floodplane_image,QuantumRange,q);
291 p+=(ptrdiff_t) GetPixelChannels(image);
292 q+=(ptrdiff_t) GetPixelChannels(floodplane_image);
294 status=SyncCacheViewAuthenticPixels(floodplane_view,exception);
295 if (status == MagickFalse)
298 PushSegmentStack(y,start,x-1,offset);
300 PushSegmentStack(y,x2+1,x-1,-offset);
306 p=GetCacheViewVirtualPixels(image_view,x,y,(
size_t) (x2-x+1),1,
308 q=GetCacheViewAuthenticPixels(floodplane_view,x,y,(
size_t) (x2-x+1),1,
310 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
312 for ( ; x <= x2; x++)
314 if (GetPixelGray(floodplane_image,q) != 0)
316 GetPixelInfoPixel(image,p,&pixel);
317 if (IsFuzzyEquivalencePixelInfo(&pixel,target) != invert)
319 p+=(ptrdiff_t) GetPixelChannels(image);
320 q+=(ptrdiff_t) GetPixelChannels(floodplane_image);
327#if defined(MAGICKCORE_OPENMP_SUPPORT)
328 #pragma omp parallel for schedule(static) shared(status) \
329 magick_number_threads(floodplane_image,image,image->rows,2)
331 for (y=0; y < (ssize_t) image->rows; y++)
345 if (status == MagickFalse)
347 p=GetCacheViewVirtualPixels(floodplane_view,0,y,image->columns,1,exception);
348 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
349 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
354 for (x=0; x < (ssize_t) image->columns; x++)
356 if (GetPixelGray(floodplane_image,p) != 0)
361 GetFillColor(draw_info,x,y,&fill_color,exception);
362 if ((image->channel_mask & RedChannel) != 0)
363 SetPixelRed(image,(Quantum) fill_color.red,q);
364 if ((image->channel_mask & GreenChannel) != 0)
365 SetPixelGreen(image,(Quantum) fill_color.green,q);
366 if ((image->channel_mask & BlueChannel) != 0)
367 SetPixelBlue(image,(Quantum) fill_color.blue,q);
368 if ((image->channel_mask & BlackChannel) != 0)
369 SetPixelBlack(image,(Quantum) fill_color.black,q);
370 if (((image->channel_mask & AlphaChannel) != 0) &&
371 ((image->alpha_trait & BlendPixelTrait) != 0))
372 SetPixelAlpha(image,(Quantum) fill_color.alpha,q);
374 p+=(ptrdiff_t) GetPixelChannels(floodplane_image);
375 q+=(ptrdiff_t) GetPixelChannels(image);
377 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
380 floodplane_view=DestroyCacheView(floodplane_view);
381 image_view=DestroyCacheView(image_view);
382 segment_info=RelinquishVirtualMemory(segment_info);
383 floodplane_image=DestroyImage(floodplane_image);
425MagickExport MagickBooleanType GradientImage(
Image *image,
426 const GradientType type,
const SpreadMethod method,
const StopInfo *stops,
444 assert(image != (
const Image *) NULL);
445 assert(image->signature == MagickCoreSignature);
446 assert(stops != (
const StopInfo *) NULL);
447 assert(number_stops > 0);
448 if (IsEventLogging() != MagickFalse)
449 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
450 draw_info=AcquireDrawInfo();
451 gradient=(&draw_info->gradient);
453 gradient->bounding_box.width=image->columns;
454 gradient->bounding_box.height=image->rows;
455 artifact=GetImageArtifact(image,
"gradient:bounding-box");
456 if (artifact != (
const char *) NULL)
457 (void) ParseAbsoluteGeometry(artifact,&gradient->bounding_box);
458 gradient->gradient_vector.x2=(double) image->columns-1;
459 gradient->gradient_vector.y2=(double) image->rows-1;
460 artifact=GetImageArtifact(image,
"gradient:direction");
461 if (artifact != (
const char *) NULL)
466 direction=(GravityType) ParseCommandOption(MagickGravityOptions,
467 MagickFalse,artifact);
470 case NorthWestGravity:
472 gradient->gradient_vector.x1=(double) image->columns-1;
473 gradient->gradient_vector.y1=(double) image->rows-1;
474 gradient->gradient_vector.x2=0.0;
475 gradient->gradient_vector.y2=0.0;
480 gradient->gradient_vector.x1=0.0;
481 gradient->gradient_vector.y1=(double) image->rows-1;
482 gradient->gradient_vector.x2=0.0;
483 gradient->gradient_vector.y2=0.0;
486 case NorthEastGravity:
488 gradient->gradient_vector.x1=0.0;
489 gradient->gradient_vector.y1=(double) image->rows-1;
490 gradient->gradient_vector.x2=(double) image->columns-1;
491 gradient->gradient_vector.y2=0.0;
496 gradient->gradient_vector.x1=(double) image->columns-1;
497 gradient->gradient_vector.y1=0.0;
498 gradient->gradient_vector.x2=0.0;
499 gradient->gradient_vector.y2=0.0;
504 gradient->gradient_vector.x1=0.0;
505 gradient->gradient_vector.y1=0.0;
506 gradient->gradient_vector.x2=(double) image->columns-1;
507 gradient->gradient_vector.y2=0.0;
510 case SouthWestGravity:
512 gradient->gradient_vector.x1=(double) image->columns-1;
513 gradient->gradient_vector.y1=0.0;
514 gradient->gradient_vector.x2=0.0;
515 gradient->gradient_vector.y2=(double) image->rows-1;
520 gradient->gradient_vector.x1=0.0;
521 gradient->gradient_vector.y1=0.0;
522 gradient->gradient_vector.x2=0.0;
523 gradient->gradient_vector.y2=(double) image->rows-1;
526 case SouthEastGravity:
528 gradient->gradient_vector.x1=0.0;
529 gradient->gradient_vector.y1=0.0;
530 gradient->gradient_vector.x2=(double) image->columns-1;
531 gradient->gradient_vector.y2=(double) image->rows-1;
538 artifact=GetImageArtifact(image,
"gradient:angle");
539 if (artifact != (
const char *) NULL)
540 gradient->angle=StringToDouble(artifact,(
char **) NULL);
541 artifact=GetImageArtifact(image,
"gradient:vector");
542 if (artifact != (
const char *) NULL)
543 (void) sscanf(artifact,
"%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf",
544 &gradient->gradient_vector.x1,&gradient->gradient_vector.y1,
545 &gradient->gradient_vector.x2,&gradient->gradient_vector.y2);
546 if ((GetImageArtifact(image,
"gradient:angle") == (
const char *) NULL) &&
547 (GetImageArtifact(image,
"gradient:direction") == (
const char *) NULL) &&
548 (GetImageArtifact(image,
"gradient:extent") == (
const char *) NULL) &&
549 (GetImageArtifact(image,
"gradient:vector") == (
const char *) NULL))
550 if ((type == LinearGradient) && (gradient->gradient_vector.y2 != 0.0))
551 gradient->gradient_vector.x2=0.0;
552 gradient->center.x=(double) gradient->gradient_vector.x2/2.0;
553 gradient->center.y=(double) gradient->gradient_vector.y2/2.0;
554 artifact=GetImageArtifact(image,
"gradient:center");
555 if (artifact != (
const char *) NULL)
556 (void) sscanf(artifact,
"%lf%*[ ,]%lf",&gradient->center.x,
557 &gradient->center.y);
558 artifact=GetImageArtifact(image,
"gradient:angle");
559 if ((type == LinearGradient) && (artifact != (
const char *) NULL))
569 sine=sin((
double) DegreesToRadians(gradient->angle-90.0));
570 cosine=cos((
double) DegreesToRadians(gradient->angle-90.0));
571 distance=fabs((
double) (image->columns-1.0)*cosine)+
572 fabs((
double) (image->rows-1.0)*sine);
573 gradient->gradient_vector.x1=0.5*((image->columns-1.0)-distance*cosine);
574 gradient->gradient_vector.y1=0.5*((image->rows-1.0)-distance*sine);
575 gradient->gradient_vector.x2=0.5*((image->columns-1.0)+distance*cosine);
576 gradient->gradient_vector.y2=0.5*((image->rows-1.0)+distance*sine);
578 gradient->radii.x=(double) MagickMax((image->columns-1.0),(image->rows-1.0))/
580 gradient->radii.y=gradient->radii.x;
581 artifact=GetImageArtifact(image,
"gradient:extent");
582 if (artifact != (
const char *) NULL)
584 if (LocaleCompare(artifact,
"Circle") == 0)
586 gradient->radii.x=(double) MagickMax((image->columns-1.0),
587 (image->rows-1.0))/2.0;
588 gradient->radii.y=gradient->radii.x;
590 if (LocaleCompare(artifact,
"Diagonal") == 0)
592 gradient->radii.x=(double) (sqrt((
double) (image->columns-1.0)*
593 (image->columns-1.0)+(image->rows-1.0)*(image->rows-1.0)))/2.0;
594 gradient->radii.y=gradient->radii.x;
596 if (LocaleCompare(artifact,
"Ellipse") == 0)
598 gradient->radii.x=(double) (image->columns-1.0)/2.0;
599 gradient->radii.y=(double) (image->rows-1.0)/2.0;
601 if (LocaleCompare(artifact,
"Maximum") == 0)
603 gradient->radii.x=(double) MagickMax((image->columns-1.0),
604 (image->rows-1.0))/2.0;
605 gradient->radii.y=gradient->radii.x;
607 if (LocaleCompare(artifact,
"Minimum") == 0)
609 gradient->radii.x=(double) (MagickMin((image->columns-1.0),
610 (image->rows-1.0)))/2.0;
611 gradient->radii.y=gradient->radii.x;
614 artifact=GetImageArtifact(image,
"gradient:radii");
615 if (artifact != (
const char *) NULL)
616 (void) sscanf(artifact,
"%lf%*[ ,]%lf",&gradient->radii.x,
618 gradient->radius=MagickMax(gradient->radii.x,gradient->radii.y);
619 gradient->spread=method;
623 gradient->number_stops=number_stops;
624 gradient->stops=(
StopInfo *) AcquireQuantumMemory(gradient->number_stops,
625 sizeof(*gradient->stops));
626 if (gradient->stops == (
StopInfo *) NULL)
627 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
629 (void) memcpy(gradient->stops,stops,(
size_t) number_stops*
sizeof(*stops));
633 status=DrawGradientImage(image,draw_info,exception);
634 draw_info=DestroyDrawInfo(draw_info);
670static size_t **DestroyHistogramTLS(
size_t **histogram)
675 assert(histogram != (
size_t **) NULL);
676 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
677 if (histogram[i] != (
size_t *) NULL)
678 histogram[i]=(
size_t *) RelinquishMagickMemory(histogram[i]);
679 histogram=(
size_t **) RelinquishMagickMemory(histogram);
683static size_t **AcquireHistogramTLS(
const size_t count)
692 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
693 histogram=(
size_t **) AcquireQuantumMemory(number_threads,
sizeof(*histogram));
694 if (histogram == (
size_t **) NULL)
695 return((
size_t **) NULL);
696 (void) memset(histogram,0,number_threads*
sizeof(*histogram));
697 for (i=0; i < (ssize_t) number_threads; i++)
699 histogram[i]=(
size_t *) AcquireQuantumMemory(count,
sizeof(**histogram));
700 if (histogram[i] == (
size_t *) NULL)
701 return(DestroyHistogramTLS(histogram));
706MagickExport
Image *OilPaintImage(
const Image *image,
const double radius,
709#define NumberPaintBins 256
710#define OilPaintImageTag "OilPaint/Image"
737 assert(image != (
const Image *) NULL);
738 assert(image->signature == MagickCoreSignature);
740 assert(exception->signature == MagickCoreSignature);
741 if (IsEventLogging() != MagickFalse)
742 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
743 width=GetOptimalKernelWidth2D(radius,sigma);
744 linear_image=CloneImage(image,0,0,MagickTrue,exception);
745 paint_image=CloneImage(image,0,0,MagickTrue,exception);
746 if ((linear_image == (
Image *) NULL) || (paint_image == (
Image *) NULL))
748 if (linear_image != (
Image *) NULL)
749 linear_image=DestroyImage(linear_image);
750 if (paint_image != (
Image *) NULL)
751 linear_image=DestroyImage(paint_image);
752 return((
Image *) NULL);
754 if (SetImageStorageClass(paint_image,DirectClass,exception) == MagickFalse)
756 linear_image=DestroyImage(linear_image);
757 paint_image=DestroyImage(paint_image);
758 return((
Image *) NULL);
760 histograms=AcquireHistogramTLS(NumberPaintBins);
761 if (histograms == (
size_t **) NULL)
763 linear_image=DestroyImage(linear_image);
764 paint_image=DestroyImage(paint_image);
765 ThrowImageException(ResourceLimitError,
"MemoryAllocationFailed");
772 center=(ssize_t) (GetPixelChannels(linear_image)*(linear_image->columns+
773 width)*(width/2L)+GetPixelChannels(linear_image)*(width/2L));
774 image_view=AcquireVirtualCacheView(linear_image,exception);
775 paint_view=AcquireAuthenticCacheView(paint_image,exception);
776#if defined(MAGICKCORE_OPENMP_SUPPORT)
777 #pragma omp parallel for schedule(static) shared(progress,status) \
778 magick_number_threads(linear_image,paint_image,linear_image->rows,1)
780 for (y=0; y < (ssize_t) linear_image->rows; y++)
794 if (status == MagickFalse)
796 p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t)
797 (width/2L),linear_image->columns+width,width,exception);
798 q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1,
800 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
805 histogram=histograms[GetOpenMPThreadId()];
806 for (x=0; x < (ssize_t) linear_image->columns; x++)
827 (void) memset(histogram,0,NumberPaintBins*
sizeof(*histogram));
828 for (v=0; v < (ssize_t) width; v++)
830 for (u=0; u < (ssize_t) width; u++)
832 n=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(
833 linear_image,p+(ssize_t) GetPixelChannels(linear_image)*(u+k))));
835 if (histogram[n] > count)
841 k+=(ssize_t) (linear_image->columns+width);
843 for (i=0; i < (ssize_t) GetPixelChannels(linear_image); i++)
845 PixelChannel channel = GetPixelChannelChannel(linear_image,i);
846 PixelTrait traits = GetPixelChannelTraits(linear_image,channel);
847 PixelTrait paint_traits=GetPixelChannelTraits(paint_image,channel);
848 if ((traits == UndefinedPixelTrait) ||
849 (paint_traits == UndefinedPixelTrait))
851 if ((paint_traits & CopyPixelTrait) != 0)
853 SetPixelChannel(paint_image,channel,p[center+i],q);
856 SetPixelChannel(paint_image,channel,p[j*(ssize_t)
857 GetPixelChannels(linear_image)+i],q);
859 p+=(ptrdiff_t) GetPixelChannels(linear_image);
860 q+=(ptrdiff_t) GetPixelChannels(paint_image);
862 if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse)
864 if (linear_image->progress_monitor != (MagickProgressMonitor) NULL)
869#if defined(MAGICKCORE_OPENMP_SUPPORT)
873 proceed=SetImageProgress(linear_image,OilPaintImageTag,progress,
875 if (proceed == MagickFalse)
879 paint_view=DestroyCacheView(paint_view);
880 image_view=DestroyCacheView(image_view);
881 histograms=DestroyHistogramTLS(histograms);
882 linear_image=DestroyImage(linear_image);
883 if (status == MagickFalse)
884 paint_image=DestroyImage(paint_image);
927MagickExport MagickBooleanType OpaquePaintImage(
Image *image,
931#define OpaquePaintImageTag "Opaque/Image"
950 assert(image != (
Image *) NULL);
951 assert(image->signature == MagickCoreSignature);
954 if (IsEventLogging() != MagickFalse)
955 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
956 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
958 ConformPixelInfo(image,fill,&conform_fill,exception);
959 ConformPixelInfo(image,target,&conform_target,exception);
965 GetPixelInfo(image,&zero);
966 image_view=AcquireAuthenticCacheView(image,exception);
967#if defined(MAGICKCORE_OPENMP_SUPPORT)
968 #pragma omp parallel for schedule(static) shared(progress,status) \
969 magick_number_threads(image,image,image->rows,1)
971 for (y=0; y < (ssize_t) image->rows; y++)
982 if (status == MagickFalse)
984 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
985 if (q == (Quantum *) NULL)
991 for (x=0; x < (ssize_t) image->columns; x++)
993 GetPixelInfoPixel(image,q,&pixel);
994 if (IsFuzzyEquivalencePixelInfo(&pixel,&conform_target) != invert)
999 traits=GetPixelChannelTraits(image,RedPixelChannel);
1000 if ((traits & UpdatePixelTrait) != 0)
1001 SetPixelRed(image,(Quantum) conform_fill.red,q);
1002 traits=GetPixelChannelTraits(image,GreenPixelChannel);
1003 if ((traits & UpdatePixelTrait) != 0)
1004 SetPixelGreen(image,(Quantum) conform_fill.green,q);
1005 traits=GetPixelChannelTraits(image,BluePixelChannel);
1006 if ((traits & UpdatePixelTrait) != 0)
1007 SetPixelBlue(image,(Quantum) conform_fill.blue,q);
1008 traits=GetPixelChannelTraits(image,BlackPixelChannel);
1009 if ((traits & UpdatePixelTrait) != 0)
1010 SetPixelBlack(image,(Quantum) conform_fill.black,q);
1011 traits=GetPixelChannelTraits(image,AlphaPixelChannel);
1012 if ((traits & UpdatePixelTrait) != 0)
1013 SetPixelAlpha(image,(Quantum) conform_fill.alpha,q);
1015 q+=(ptrdiff_t) GetPixelChannels(image);
1017 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1019 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1024#if defined(MAGICKCORE_OPENMP_SUPPORT)
1028 proceed=SetImageProgress(image,OpaquePaintImageTag,progress,
1030 if (proceed == MagickFalse)
1034 image_view=DestroyCacheView(image_view);
1077MagickExport MagickBooleanType TransparentPaintImage(
Image *image,
1078 const PixelInfo *target,
const Quantum opacity,
const MagickBooleanType invert,
1081#define TransparentPaintImageTag "Transparent/Image"
1098 assert(image != (
Image *) NULL);
1099 assert(image->signature == MagickCoreSignature);
1101 if (IsEventLogging() != MagickFalse)
1102 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1103 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1104 return(MagickFalse);
1105 if ((image->alpha_trait & BlendPixelTrait) == 0)
1106 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1112 GetPixelInfo(image,&zero);
1113 image_view=AcquireAuthenticCacheView(image,exception);
1114#if defined(MAGICKCORE_OPENMP_SUPPORT)
1115 #pragma omp parallel for schedule(static) shared(progress,status) \
1116 magick_number_threads(image,image,image->rows,1)
1118 for (y=0; y < (ssize_t) image->rows; y++)
1129 if (status == MagickFalse)
1131 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1132 if (q == (Quantum *) NULL)
1138 for (x=0; x < (ssize_t) image->columns; x++)
1140 GetPixelInfoPixel(image,q,&pixel);
1141 if (IsFuzzyEquivalencePixelInfo(&pixel,target) != invert)
1142 SetPixelAlpha(image,opacity,q);
1143 q+=(ptrdiff_t) GetPixelChannels(image);
1145 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1147 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1152#if defined(MAGICKCORE_OPENMP_SUPPORT)
1156 proceed=SetImageProgress(image,TransparentPaintImageTag,progress,
1158 if (proceed == MagickFalse)
1162 image_view=DestroyCacheView(image_view);
1208MagickExport MagickBooleanType TransparentPaintImageChroma(
Image *image,
1212#define TransparentPaintImageTag "Transparent/Image"
1226 assert(image != (
Image *) NULL);
1227 assert(image->signature == MagickCoreSignature);
1230 if (IsEventLogging() != MagickFalse)
1231 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1232 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
1233 return(MagickFalse);
1234 if ((image->alpha_trait & BlendPixelTrait) == 0)
1235 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1241 image_view=AcquireAuthenticCacheView(image,exception);
1242#if defined(MAGICKCORE_OPENMP_SUPPORT)
1243 #pragma omp parallel for schedule(static) shared(progress,status) \
1244 magick_number_threads(image,image,image->rows,1)
1246 for (y=0; y < (ssize_t) image->rows; y++)
1260 if (status == MagickFalse)
1262 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1263 if (q == (Quantum *) NULL)
1268 GetPixelInfo(image,&pixel);
1269 for (x=0; x < (ssize_t) image->columns; x++)
1271 GetPixelInfoPixel(image,q,&pixel);
1272 match=((pixel.red >= low->red) && (pixel.red <= high->red) &&
1273 (pixel.green >= low->green) && (pixel.green <= high->green) &&
1274 (pixel.blue >= low->blue) && (pixel.blue <= high->blue)) ? MagickTrue :
1276 if (match != invert)
1277 SetPixelAlpha(image,opacity,q);
1278 q+=(ptrdiff_t) GetPixelChannels(image);
1280 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1282 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1287#if defined(MAGICKCORE_OPENMP_SUPPORT)
1291 proceed=SetImageProgress(image,TransparentPaintImageTag,progress,
1293 if (proceed == MagickFalse)
1297 image_view=DestroyCacheView(image_view);