42#include "magick/studio.h"
43#include "magick/artifact.h"
44#include "magick/cache.h"
45#include "magick/channel.h"
46#include "magick/color-private.h"
47#include "magick/colorspace-private.h"
48#include "magick/composite.h"
49#include "magick/composite-private.h"
50#include "magick/draw.h"
51#include "magick/draw-private.h"
52#include "magick/exception.h"
53#include "magick/exception-private.h"
54#include "magick/gem.h"
55#include "magick/monitor.h"
56#include "magick/monitor-private.h"
57#include "magick/option.h"
58#include "magick/paint.h"
59#include "magick/pixel-private.h"
60#include "magick/resource_.h"
61#include "magick/string_.h"
62#include "magick/string-private.h"
63#include "magick/thread-private.h"
110MagickExport MagickBooleanType FloodfillPaintImage(
Image *image,
111 const ChannelType channel,
const DrawInfo *draw_info,
113 const MagickBooleanType invert)
115#define MaxStacksize 524288UL
116#define PushSegmentStack(up,left,right,delta) \
118 if (s >= (segment_stack+MaxStacksize)) \
120 segment_info=RelinquishVirtualMemory(segment_info); \
121 image_view=DestroyCacheView(image_view); \
122 floodplane_view=DestroyCacheView(floodplane_view); \
123 floodplane_image=DestroyImage(floodplane_image); \
124 ThrowBinaryException(DrawError,"SegmentStackOverflow",image->filename) \
128 if ((((up)+(delta)) >= 0) && (((up)+(delta)) < (ssize_t) image->rows)) \
130 s->x1=(double) (left); \
131 s->y1=(double) (up); \
132 s->x2=(double) (right); \
133 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) == MagickFalse)
186 exception=(&image->exception);
187 if (IsGrayColorspace(image->colorspace) != MagickFalse)
188 (void) SetImageColorspace(image,sRGBColorspace);
189 if ((image->matte == MagickFalse) &&
190 (draw_info->fill.opacity != OpaqueOpacity))
191 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
195 floodplane_image=CloneImage(image,0,0,MagickTrue,&image->exception);
196 if (floodplane_image == (
Image *) NULL)
198 floodplane_image->matte=MagickFalse;
199 floodplane_image->colorspace=GRAYColorspace;
200 (void) QueryColorCompliance(
"#000",AllCompliance,
201 &floodplane_image->background_color,exception);
202 (void) SetImageBackgroundColor(floodplane_image);
203 segment_info=AcquireVirtualMemory(MaxStacksize,
sizeof(*segment_stack));
206 floodplane_image=DestroyImage(floodplane_image);
207 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
210 segment_stack=(
SegmentInfo *) GetVirtualMemoryBlob(segment_info);
218 GetMagickPixelPacket(image,&pixel);
219 image_view=AcquireVirtualCacheView(image,exception);
220 floodplane_view=AcquireAuthenticCacheView(floodplane_image,exception);
221 PushSegmentStack(y,x,x,1);
222 PushSegmentStack(y+1,x,x,-1);
223 while (s > segment_stack)
226 *magick_restrict indexes;
243 offset=(ssize_t) s->y2;
244 y=(ssize_t) s->y1+offset;
248 p=GetCacheViewVirtualPixels(image_view,0,y,(
size_t) (x1+1),1,exception);
249 q=GetCacheViewAuthenticPixels(floodplane_view,0,y,(
size_t) (x1+1),1,
253 indexes=GetCacheViewVirtualIndexQueue(image_view);
256 for (x=x1; x >= 0; x--)
258 if (GetPixelGray(q) != 0)
260 SetMagickPixelPacket(image,p,indexes+x,&pixel);
261 if (IsMagickColorSimilar(&pixel,target) == invert)
263 SetPixelGray(q,QuantumRange);
267 if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse)
269 skip=x >= x1 ? MagickTrue : MagickFalse;
270 if (skip == MagickFalse)
274 PushSegmentStack(y,start,x1-1,-offset);
279 if (skip == MagickFalse)
281 if (x < (ssize_t) image->columns)
283 p=GetCacheViewVirtualPixels(image_view,x,y,image->columns-x,1,
285 q=GetCacheViewAuthenticPixels(floodplane_view,x,y,
286 image->columns-x,1,exception);
290 indexes=GetCacheViewVirtualIndexQueue(image_view);
291 for ( ; x < (ssize_t) image->columns; x++)
293 if (GetPixelGray(q) != 0)
295 SetMagickPixelPacket(image,p,indexes+x,&pixel);
296 if (IsMagickColorSimilar(&pixel,target) == invert)
298 SetPixelGray(q,QuantumRange);
302 if (SyncCacheViewAuthenticPixels(floodplane_view,exception) == MagickFalse)
305 PushSegmentStack(y,start,x-1,offset);
307 PushSegmentStack(y,x2+1,x-1,-offset);
313 p=GetCacheViewVirtualPixels(image_view,x,y,(
size_t) (x2-x+1),1,
315 q=GetCacheViewAuthenticPixels(floodplane_view,x,y,(
size_t) (x2-x+1),1,
319 indexes=GetCacheViewVirtualIndexQueue(image_view);
320 for ( ; x <= x2; x++)
322 if (GetPixelGray(q) != 0)
324 SetMagickPixelPacket(image,p,indexes+x,&pixel);
325 if (IsMagickColorSimilar(&pixel,target) != invert)
335#if defined(MMAGICKCORE_OPENMP_SUPPORT)
336 #pragma omp parallel for schedule(static) shared(status) \
337 magick_number_threads(floodplane_image,image,image->rows,2)
339 for (y=0; y < (ssize_t) image->rows; y++)
345 *magick_restrict indexes;
356 if (status == MagickFalse)
358 p=GetCacheViewVirtualPixels(floodplane_view,0,y,image->columns,1,exception);
359 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
365 indexes=GetCacheViewAuthenticIndexQueue(image_view);
366 for (x=0; x < (ssize_t) image->columns; x++)
368 if (GetPixelGray(p) != 0)
376 (void) GetFillColor(draw_info,x,y,&fill_color);
377 GetMagickPixelPacket(image,&fill);
378 SetMagickPixelPacket(image,&fill_color,(IndexPacket *) NULL,&fill);
379 if (image->colorspace == CMYKColorspace)
380 ConvertRGBToCMYK(&fill);
381 if ((channel & RedChannel) != 0)
382 SetPixelRed(q,ClampToQuantum(fill.red));
383 if ((channel & GreenChannel) != 0)
384 SetPixelGreen(q,ClampToQuantum(fill.green));
385 if ((channel & BlueChannel) != 0)
386 SetPixelBlue(q,ClampToQuantum(fill.blue));
387 if (((channel & OpacityChannel) != 0) ||
388 (draw_info->fill.opacity != OpaqueOpacity))
389 SetPixelOpacity(q,ClampToQuantum(fill.opacity));
390 if (((channel & IndexChannel) != 0) &&
391 (image->colorspace == CMYKColorspace))
392 SetPixelIndex(indexes+x,ClampToQuantum(fill.index));
397 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
400 floodplane_view=DestroyCacheView(floodplane_view);
401 image_view=DestroyCacheView(image_view);
402 segment_info=RelinquishVirtualMemory(segment_info);
403 floodplane_image=DestroyImage(floodplane_image);
404 return(y == (ssize_t) image->rows ? MagickTrue : MagickFalse);
446MagickExport MagickBooleanType GradientImage(
Image *image,
447 const GradientType type,
const SpreadMethod method,
468 assert(image != (
const Image *) NULL);
469 assert(image->signature == MagickCoreSignature);
472 if (IsEventLogging() != MagickFalse)
473 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
474 draw_info=AcquireDrawInfo();
475 gradient=(&draw_info->gradient);
477 gradient->bounding_box.width=image->columns;
478 gradient->bounding_box.height=image->rows;
479 artifact=GetImageArtifact(image,
"gradient:bounding-box");
480 if (artifact != (
const char *) NULL)
481 (void) ParseAbsoluteGeometry(artifact,&gradient->bounding_box);
482 gradient->gradient_vector.x2=(double) image->columns-1;
483 gradient->gradient_vector.y2=(double) image->rows-1;
484 artifact=GetImageArtifact(image,
"gradient:direction");
485 if (artifact != (
const char *) NULL)
490 direction=(GravityType) ParseCommandOption(MagickGravityOptions,
491 MagickFalse,artifact);
494 case NorthWestGravity:
496 gradient->gradient_vector.x1=(double) image->columns-1;
497 gradient->gradient_vector.y1=(double) image->rows-1;
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=(double) image->rows-1;
506 gradient->gradient_vector.x2=0.0;
507 gradient->gradient_vector.y2=0.0;
510 case NorthEastGravity:
512 gradient->gradient_vector.x1=0.0;
513 gradient->gradient_vector.y1=(double) image->rows-1;
514 gradient->gradient_vector.x2=(double) image->columns-1;
515 gradient->gradient_vector.y2=0.0;
520 gradient->gradient_vector.x1=(double) image->columns-1;
521 gradient->gradient_vector.y1=0.0;
522 gradient->gradient_vector.x2=0.0;
523 gradient->gradient_vector.y2=0.0;
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=0.0;
534 case SouthWestGravity:
536 gradient->gradient_vector.x1=(double) image->columns-1;
537 gradient->gradient_vector.y1=0.0;
538 gradient->gradient_vector.x2=0.0;
539 gradient->gradient_vector.y2=(double) image->rows-1;
544 gradient->gradient_vector.x1=0.0;
545 gradient->gradient_vector.y1=0.0;
546 gradient->gradient_vector.x2=0.0;
547 gradient->gradient_vector.y2=(double) image->columns-1;
550 case SouthEastGravity:
552 gradient->gradient_vector.x1=0.0;
553 gradient->gradient_vector.y1=0.0;
554 gradient->gradient_vector.x2=(double) image->columns-1;
555 gradient->gradient_vector.y2=(double) image->rows-1;
562 artifact=GetImageArtifact(image,
"gradient:angle");
563 if (artifact != (
const char *) NULL)
564 gradient->angle=(MagickRealType) StringToDouble(artifact,(
char **) NULL);
565 artifact=GetImageArtifact(image,
"gradient:vector");
566 if (artifact != (
const char *) NULL)
567 (void) sscanf(artifact,
"%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf",
568 &gradient->gradient_vector.x1,&gradient->gradient_vector.y1,
569 &gradient->gradient_vector.x2,&gradient->gradient_vector.y2);
570 if ((GetImageArtifact(image,
"gradient:angle") == (
const char *) NULL) &&
571 (GetImageArtifact(image,
"gradient:direction") == (
const char *) NULL) &&
572 (GetImageArtifact(image,
"gradient:extent") == (
const char *) NULL) &&
573 (GetImageArtifact(image,
"gradient:vector") == (
const char *) NULL))
574 if ((type == LinearGradient) && (gradient->gradient_vector.y2 != 0.0))
575 gradient->gradient_vector.x2=0.0;
576 gradient->center.x=(double) gradient->gradient_vector.x2/2.0;
577 gradient->center.y=(double) gradient->gradient_vector.y2/2.0;
578 artifact=GetImageArtifact(image,
"gradient:center");
579 if (artifact != (
const char *) NULL)
580 (void) sscanf(artifact,
"%lf%*[ ,]%lf",&gradient->center.x,
581 &gradient->center.y);
582 artifact=GetImageArtifact(image,
"gradient:angle");
583 if ((type == LinearGradient) && (artifact != (
const char *) NULL))
593 sine=sin((
double) DegreesToRadians(gradient->angle-90.0));
594 cosine=cos((
double) DegreesToRadians(gradient->angle-90.0));
595 distance=fabs((
double) (image->columns-1)*cosine)+
596 fabs((
double) (image->rows-1)*sine);
597 gradient->gradient_vector.x1=0.5*((image->columns-1)-distance*cosine);
598 gradient->gradient_vector.y1=0.5*((image->rows-1)-distance*sine);
599 gradient->gradient_vector.x2=0.5*((image->columns-1)+distance*cosine);
600 gradient->gradient_vector.y2=0.5*((image->rows-1)+distance*sine);
602 gradient->radii.x=(double) MagickMax((image->columns-1),(image->rows-1))/2.0;
603 gradient->radii.y=gradient->radii.x;
604 artifact=GetImageArtifact(image,
"gradient:extent");
605 if (artifact != (
const char *) NULL)
607 if (LocaleCompare(artifact,
"Circle") == 0)
609 gradient->radii.x=(double) (MagickMax((image->columns-1),
610 (image->rows-1)))/2.0;
611 gradient->radii.y=gradient->radii.x;
613 if (LocaleCompare(artifact,
"Diagonal") == 0)
615 gradient->radii.x=(double) (sqrt((
double) (image->columns-1)*
616 (image->columns-1)+(image->rows-1)*(image->rows-1)))/2.0;
617 gradient->radii.y=gradient->radii.x;
619 if (LocaleCompare(artifact,
"Ellipse") == 0)
621 gradient->radii.x=(double) (image->columns-1)/2.0;
622 gradient->radii.y=(double) (image->rows-1)/2.0;
624 if (LocaleCompare(artifact,
"Maximum") == 0)
626 gradient->radii.x=(double) MagickMax((image->columns-1),
627 (image->rows-1))/2.0;
628 gradient->radii.y=gradient->radii.x;
630 if (LocaleCompare(artifact,
"Minimum") == 0)
632 gradient->radii.x=(double) MagickMin((image->columns-1),
633 (image->rows-1))/2.0;
634 gradient->radii.y=gradient->radii.x;
637 artifact=GetImageArtifact(image,
"gradient:radii");
638 if (artifact != (
const char *) NULL)
639 (void) sscanf(artifact,
"%lf%*[ ,]%lf",&gradient->radii.x,
641 gradient->radius=MagickMax(gradient->radii.x,gradient->radii.y);
642 gradient->spread=method;
646 gradient->number_stops=2;
647 gradient->stops=(
StopInfo *) AcquireQuantumMemory(gradient->number_stops,
648 sizeof(*gradient->stops));
649 if (gradient->stops == (
StopInfo *) NULL)
650 ThrowBinaryImageException(ResourceLimitError,
"MemoryAllocationFailed",
652 (void) memset(gradient->stops,0,gradient->number_stops*
653 sizeof(*gradient->stops));
654 for (i=0; i < (ssize_t) gradient->number_stops; i++)
655 GetMagickPixelPacket(image,&gradient->stops[i].color);
656 SetMagickPixelPacket(image,start_color,(IndexPacket *) NULL,
657 &gradient->stops[0].color);
658 gradient->stops[0].offset=0.0;
659 SetMagickPixelPacket(image,stop_color,(IndexPacket *) NULL,
660 &gradient->stops[1].color);
661 gradient->stops[1].offset=1.0;
665 status=DrawGradientImage(image,draw_info);
666 draw_info=DestroyDrawInfo(draw_info);
700static size_t **DestroyHistogramTLS(
size_t **histogram)
705 assert(histogram != (
size_t **) NULL);
706 for (i=0; i < (ssize_t) GetMagickResourceLimit(ThreadResource); i++)
707 if (histogram[i] != (
size_t *) NULL)
708 histogram[i]=(
size_t *) RelinquishMagickMemory(histogram[i]);
709 histogram=(
size_t **) RelinquishMagickMemory(histogram);
713static size_t **AcquireHistogramTLS(
const size_t count)
722 number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
723 histogram=(
size_t **) AcquireQuantumMemory(number_threads,
725 if (histogram == (
size_t **) NULL)
726 return((
size_t **) NULL);
727 (void) memset(histogram,0,number_threads*
sizeof(*histogram));
728 for (i=0; i < (ssize_t) number_threads; i++)
730 histogram[i]=(
size_t *) AcquireQuantumMemory(count,
731 sizeof(**histogram));
732 if (histogram[i] == (
size_t *) NULL)
733 return(DestroyHistogramTLS(histogram));
738MagickExport
Image *OilPaintImage(
const Image *image,
const double radius,
741#define NumberPaintBins 256
742#define OilPaintImageTag "OilPaint/Image"
759 **magick_restrict histograms,
768 assert(image != (
const Image *) NULL);
769 assert(image->signature == MagickCoreSignature);
771 assert(exception->signature == MagickCoreSignature);
772 if (IsEventLogging() != MagickFalse)
773 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
774 width=GetOptimalKernelWidth2D(radius,0.5);
775 linear_image=CloneImage(image,0,0,MagickTrue,exception);
776 paint_image=CloneImage(image,0,0,MagickTrue,exception);
777 if ((linear_image == (
Image *) NULL) || (paint_image == (
Image *) NULL))
779 if (linear_image != (
Image *) NULL)
780 linear_image=DestroyImage(linear_image);
781 if (paint_image != (
Image *) NULL)
782 linear_image=DestroyImage(paint_image);
783 return((
Image *) NULL);
785 if (SetImageStorageClass(paint_image,DirectClass) == MagickFalse)
787 InheritException(exception,&paint_image->exception);
788 linear_image=DestroyImage(linear_image);
789 paint_image=DestroyImage(paint_image);
790 return((
Image *) NULL);
792 histograms=AcquireHistogramTLS(NumberPaintBins);
793 if (histograms == (
size_t **) NULL)
795 linear_image=DestroyImage(linear_image);
796 paint_image=DestroyImage(paint_image);
797 ThrowImageException(ResourceLimitError,
"MemoryAllocationFailed");
804 image_view=AcquireVirtualCacheView(linear_image,exception);
805 paint_view=AcquireAuthenticCacheView(paint_image,exception);
806#if defined(MAGICKCORE_OPENMP_SUPPORT)
807 #pragma omp parallel for schedule(static) shared(progress,status) \
808 magick_number_threads(linear_image,paint_image,linear_image->rows,1)
810 for (y=0; y < (ssize_t) linear_image->rows; y++)
813 *magick_restrict indexes;
819 *magick_restrict paint_indexes;
830 if (status == MagickFalse)
832 p=GetCacheViewVirtualPixels(image_view,-((ssize_t) width/2L),y-(ssize_t)
833 (width/2L),linear_image->columns+width,width,exception);
834 q=QueueCacheViewAuthenticPixels(paint_view,0,y,paint_image->columns,1,
841 indexes=GetCacheViewVirtualIndexQueue(image_view);
842 paint_indexes=GetCacheViewAuthenticIndexQueue(paint_view);
843 histogram=histograms[GetOpenMPThreadId()];
844 for (x=0; x < (ssize_t) linear_image->columns; x++)
864 (void) memset(histogram,0,NumberPaintBins*
sizeof(*histogram));
865 for (v=0; v < (ssize_t) width; v++)
867 for (u=0; u < (ssize_t) width; u++)
869 k=(ssize_t) ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(
870 linear_image,p+u+i)));
872 if (histogram[k] > count)
878 i+=(ssize_t) (linear_image->columns+width);
881 if (linear_image->colorspace == CMYKColorspace)
882 SetPixelIndex(paint_indexes+x,GetPixelIndex(indexes+x+j));
886 if (SyncCacheViewAuthenticPixels(paint_view,exception) == MagickFalse)
888 if (image->progress_monitor != (MagickProgressMonitor) NULL)
893#if defined(MAGICKCORE_OPENMP_SUPPORT)
897 proceed=SetImageProgress(image,OilPaintImageTag,progress,image->rows);
898 if (proceed == MagickFalse)
902 paint_view=DestroyCacheView(paint_view);
903 image_view=DestroyCacheView(image_view);
904 histograms=DestroyHistogramTLS(histograms);
905 linear_image=DestroyImage(linear_image);
906 if (status == MagickFalse)
907 paint_image=DestroyImage(paint_image);
954MagickExport MagickBooleanType OpaquePaintImage(
Image *image,
956 const MagickBooleanType invert)
958 return(OpaquePaintImageChannel(image,CompositeChannels,target,fill,invert));
961MagickExport MagickBooleanType OpaquePaintImageChannel(
Image *image,
965#define OpaquePaintImageTag "Opaque/Image"
987 assert(image != (
Image *) NULL);
988 assert(image->signature == MagickCoreSignature);
991 if (IsEventLogging() != MagickFalse)
992 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
993 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
995 exception=(&image->exception);
996 ConformMagickPixelPacket(image,fill,&conform_fill,exception);
997 ConformMagickPixelPacket(image,target,&conform_target,exception);
1003 GetMagickPixelPacket(image,&zero);
1004 image_view=AcquireAuthenticCacheView(image,exception);
1005#if defined(MAGICKCORE_OPENMP_SUPPORT)
1006 #pragma omp parallel for schedule(static) shared(progress,status) \
1007 magick_number_threads(image,image,image->rows,1)
1009 for (y=0; y < (ssize_t) image->rows; y++)
1015 *magick_restrict indexes;
1023 if (status == MagickFalse)
1025 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1031 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1033 for (x=0; x < (ssize_t) image->columns; x++)
1035 SetMagickPixelPacket(image,q,indexes+x,&pixel);
1036 if (IsMagickColorSimilar(&pixel,&conform_target) != invert)
1038 if ((channel & RedChannel) != 0)
1039 SetPixelRed(q,ClampToQuantum(conform_fill.red));
1040 if ((channel & GreenChannel) != 0)
1041 SetPixelGreen(q,ClampToQuantum(conform_fill.green));
1042 if ((channel & BlueChannel) != 0)
1043 SetPixelBlue(q,ClampToQuantum(conform_fill.blue));
1044 if ((channel & OpacityChannel) != 0)
1045 SetPixelOpacity(q,ClampToQuantum(conform_fill.opacity));
1046 if (((channel & IndexChannel) != 0) &&
1047 (image->colorspace == CMYKColorspace))
1048 SetPixelIndex(indexes+x,ClampToQuantum(conform_fill.index));
1052 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1054 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1059#if defined(MAGICKCORE_OPENMP_SUPPORT)
1063 proceed=SetImageProgress(image,OpaquePaintImageTag,progress,
1065 if (proceed == MagickFalse)
1069 image_view=DestroyCacheView(image_view);
1110MagickExport MagickBooleanType TransparentPaintImage(
Image *image,
1112 const MagickBooleanType invert)
1114#define TransparentPaintImageTag "Transparent/Image"
1134 assert(image != (
Image *) NULL);
1135 assert(image->signature == MagickCoreSignature);
1137 if (IsEventLogging() != MagickFalse)
1138 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1139 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1140 return(MagickFalse);
1141 if (image->matte == MagickFalse)
1142 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
1148 exception=(&image->exception);
1149 GetMagickPixelPacket(image,&zero);
1150 image_view=AcquireAuthenticCacheView(image,exception);
1151#if defined(MAGICKCORE_OPENMP_SUPPORT)
1152 #pragma omp parallel for schedule(static) shared(progress,status) \
1153 magick_number_threads(image,image,image->rows,1)
1155 for (y=0; y < (ssize_t) image->rows; y++)
1161 *magick_restrict indexes;
1169 if (status == MagickFalse)
1171 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1177 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1179 for (x=0; x < (ssize_t) image->columns; x++)
1181 SetMagickPixelPacket(image,q,indexes+x,&pixel);
1182 if (IsMagickColorSimilar(&pixel,target) != invert)
1186 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1188 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1193#if defined(MAGICKCORE_OPENMP_SUPPORT)
1197 proceed=SetImageProgress(image,TransparentPaintImageTag,progress,
1199 if (proceed == MagickFalse)
1203 image_view=DestroyCacheView(image_view);
1247MagickExport MagickBooleanType TransparentPaintImageChroma(
Image *image,
1249 const Quantum opacity,
const MagickBooleanType invert)
1251#define TransparentPaintImageTag "Transparent/Image"
1268 assert(image != (
Image *) NULL);
1269 assert(image->signature == MagickCoreSignature);
1272 if (IsEventLogging() != MagickFalse)
1273 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1274 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
1275 return(MagickFalse);
1276 if (image->matte == MagickFalse)
1277 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
1283 exception=(&image->exception);
1284 image_view=AcquireAuthenticCacheView(image,exception);
1285#if defined(MAGICKCORE_OPENMP_SUPPORT)
1286 #pragma omp parallel for schedule(static) shared(progress,status) \
1287 magick_number_threads(image,image,image->rows,1)
1289 for (y=0; y < (ssize_t) image->rows; y++)
1298 *magick_restrict indexes;
1306 if (status == MagickFalse)
1308 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
1314 indexes=GetCacheViewAuthenticIndexQueue(image_view);
1315 GetMagickPixelPacket(image,&pixel);
1316 for (x=0; x < (ssize_t) image->columns; x++)
1318 SetMagickPixelPacket(image,q,indexes+x,&pixel);
1319 match=((pixel.red >= low->red) && (pixel.red <= high->red) &&
1320 (pixel.green >= low->green) && (pixel.green <= high->green) &&
1321 (pixel.blue >= low->blue) && (pixel.blue <= high->blue)) ? MagickTrue : MagickFalse;
1322 if (match != invert)
1326 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1328 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1333#if defined(MAGICKCORE_OPENMP_SUPPORT)
1337 proceed=SetImageProgress(image,TransparentPaintImageTag,progress,
1339 if (proceed == MagickFalse)
1343 image_view=DestroyCacheView(image_view);