44#include "MagickCore/studio.h"
45#include "MagickCore/accelerate-private.h"
46#include "MagickCore/artifact.h"
47#include "MagickCore/cache.h"
48#include "MagickCore/cache-private.h"
49#include "MagickCore/cache-view.h"
50#include "MagickCore/color-private.h"
51#include "MagickCore/delegate-private.h"
52#include "MagickCore/enhance.h"
53#include "MagickCore/exception.h"
54#include "MagickCore/exception-private.h"
55#include "MagickCore/gem.h"
56#include "MagickCore/image.h"
57#include "MagickCore/image-private.h"
58#include "MagickCore/linked-list.h"
59#include "MagickCore/list.h"
60#include "MagickCore/memory_.h"
61#include "MagickCore/monitor-private.h"
62#include "MagickCore/opencl.h"
63#include "MagickCore/opencl-private.h"
64#include "MagickCore/option.h"
65#include "MagickCore/pixel-accessor.h"
66#include "MagickCore/prepress.h"
67#include "MagickCore/quantize.h"
68#include "MagickCore/quantum-private.h"
69#include "MagickCore/random_.h"
70#include "MagickCore/random-private.h"
71#include "MagickCore/registry.h"
72#include "MagickCore/resize.h"
73#include "MagickCore/resize-private.h"
74#include "MagickCore/semaphore.h"
75#include "MagickCore/splay-tree.h"
76#include "MagickCore/statistic.h"
77#include "MagickCore/string_.h"
78#include "MagickCore/string-private.h"
79#include "MagickCore/token.h"
81#define MAGICK_MAX(x,y) (((x) >= (y))?(x):(y))
82#define MAGICK_MIN(x,y) (((x) <= (y))?(x):(y))
84#if defined(MAGICKCORE_OPENCL_SUPPORT)
89#define ALIGNED(pointer,type) ((((size_t)(pointer)) & (sizeof(type)-1)) == 0)
94static const ResizeWeightingFunctionType supportedResizeWeighting[] =
97 TriangleWeightingFunction,
98 HannWeightingFunction,
99 HammingWeightingFunction,
100 BlackmanWeightingFunction,
101 CubicBCWeightingFunction,
102 SincWeightingFunction,
103 SincFastWeightingFunction,
104 LastWeightingFunction
110static MagickBooleanType checkAccelerateCondition(
const Image* image)
113 if (image->storage_class != DirectClass)
117 if (image->colorspace != RGBColorspace &&
118 image->colorspace != sRGBColorspace &&
119 image->colorspace != LinearGRAYColorspace &&
120 image->colorspace != GRAYColorspace)
124 if ((GetImageVirtualPixelMethod(image) != UndefinedVirtualPixelMethod) &&
125 (GetImageVirtualPixelMethod(image) != EdgeVirtualPixelMethod))
129 if (((image->channels & ReadMaskChannel) != 0) ||
130 ((image->channels & WriteMaskChannel) != 0) ||
131 ((image->channels & CompositeMaskChannel) != 0))
134 if (image->number_channels > 4)
138 if ((image->channel_mask != AllChannels) &&
139 (image->channel_mask > 0x7ffffff))
143 if (GetPixelChannelOffset(image,RedPixelChannel) != 0)
146 if (image->number_channels == 1)
150 if ((image->number_channels == 2) &&
151 (GetPixelChannelOffset(image,AlphaPixelChannel) == 1))
154 if (image->number_channels == 2)
158 if ((GetPixelChannelOffset(image,GreenPixelChannel) != 1) ||
159 (GetPixelChannelOffset(image,BluePixelChannel) != 2))
162 if (image->number_channels == 3)
166 if (GetPixelChannelOffset(image,AlphaPixelChannel) != 3)
172static MagickBooleanType checkAccelerateConditionRGBA(
const Image* image)
174 if (checkAccelerateCondition(image) == MagickFalse)
178 if (image->number_channels != 4)
181 if ((GetPixelRedTraits(image) == UndefinedPixelTrait) ||
182 (GetPixelGreenTraits(image) == UndefinedPixelTrait) ||
183 (GetPixelBlueTraits(image) == UndefinedPixelTrait) ||
184 (GetPixelAlphaTraits(image) == UndefinedPixelTrait))
190static MagickBooleanType checkPixelIntensity(
const Image *image,
191 const PixelIntensityMethod method)
194 if ((method == Rec601LumaPixelIntensityMethod) ||
195 (method == Rec709LumaPixelIntensityMethod))
197 if (image->colorspace == RGBColorspace)
201 if ((method == Rec601LuminancePixelIntensityMethod) ||
202 (method == Rec709LuminancePixelIntensityMethod))
204 if (image->colorspace == sRGBColorspace)
211static MagickBooleanType checkHistogramCondition(
const Image *image,
212 const PixelIntensityMethod method)
215 if ((image->channel_mask & SyncChannels) == 0)
218 return(checkPixelIntensity(image,method));
221static MagickCLEnv getOpenCLEnvironment(
ExceptionInfo* exception)
226 clEnv=GetCurrentOpenCLEnv();
227 if (clEnv == (MagickCLEnv) NULL)
228 return((MagickCLEnv) NULL);
230 if (clEnv->enabled == MagickFalse)
231 return((MagickCLEnv) NULL);
233 if (InitializeOpenCL(clEnv,exception) == MagickFalse)
234 return((MagickCLEnv) NULL);
244 if (((image->channel_mask & RedChannel) != 0) &&
245 ((image->channel_mask & GreenChannel) != 0) &&
246 ((image->channel_mask & BlueChannel) != 0) &&
247 ((image->channel_mask & AlphaChannel) != 0))
248 clone=CloneImage(image,0,0,MagickTrue,exception);
251 clone=CloneImage(image,0,0,MagickTrue,exception);
252 if (clone != (
Image *) NULL)
253 SyncImagePixelCache(clone,exception);
260inline static unsigned int padGlobalWorkgroupSizeToLocalWorkgroupSize(
261 const unsigned int orgGlobalSize,
const unsigned int localGroupSize)
263 return ((orgGlobalSize+(localGroupSize-1))/localGroupSize*localGroupSize);
266static cl_mem createKernelInfo(MagickCLDevice device,
const double radius,
270 geometry[MagickPathExtent];
284 (void) FormatLocaleString(geometry,MagickPathExtent,
285 "blur:%.20gx%.20g;blur:%.20gx%.20g+90",radius,sigma,radius,sigma);
286 kernel=AcquireKernelInfo(geometry,exception);
289 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
290 ResourceLimitWarning,
"AcquireKernelInfo failed.",
".");
291 return((cl_mem) NULL);
293 kernelBufferPtr=(
float *) AcquireMagickMemory(kernel->width*
294 sizeof(*kernelBufferPtr));
295 if (kernelBufferPtr == (
float *) NULL)
297 kernel=DestroyKernelInfo(kernel);
298 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
299 ResourceLimitWarning,
"MemoryAllocationFailed.",
".");
300 return((cl_mem) NULL);
302 for (i = 0; i < (ssize_t) kernel->width; i++)
303 kernelBufferPtr[i]=(
float) kernel->values[i];
304 imageKernelBuffer=CreateOpenCLBuffer(device,CL_MEM_COPY_HOST_PTR |
305 CL_MEM_READ_ONLY,kernel->width*
sizeof(*kernelBufferPtr),kernelBufferPtr);
306 *width=(cl_uint) kernel->width;
307 kernelBufferPtr=(
float *) RelinquishMagickMemory(kernelBufferPtr);
308 kernel=DestroyKernelInfo(kernel);
309 if (imageKernelBuffer == (cl_mem) NULL)
310 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
311 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
312 return(imageKernelBuffer);
315static cl_int get32BitChannelValue(
const ChannelType channel)
317#if defined(MAGICKCORE_64BIT_CHANNEL_MASK_SUPPORT)
318 if (channel == AllChannels)
321 return((cl_int) channel);
324static MagickBooleanType LaunchHistogramKernel(MagickCLEnv clEnv,
325 MagickCLDevice device,cl_command_queue queue,cl_mem imageBuffer,
326 cl_mem histogramBuffer,
Image *image,
const ChannelType channel,
333 channel_mask=get32BitChannelValue(channel),
352 histogramKernel=NULL;
353 outputReady=MagickFalse;
355 colorspace = image->colorspace;
356 method = image->intensity;
359 histogramKernel = AcquireOpenCLKernel(device,
"Histogram");
360 if (histogramKernel == NULL)
362 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
368 clStatus=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
369 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_int),&channel_mask);
370 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_uint),&colorspace);
371 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_uint),&method);
372 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_mem),(
void *)&histogramBuffer);
373 if (clStatus != CL_SUCCESS)
375 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
380 global_work_size[0] = image->columns;
381 global_work_size[1] = image->rows;
383 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, histogramKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
385 if (clStatus != CL_SUCCESS)
387 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
390 RecordProfileData(device,histogramKernel,event);
392 outputReady = MagickTrue;
396 if (histogramKernel!=NULL)
397 ReleaseOpenCLKernel(histogramKernel);
414static Image *ComputeBlurImage(
const Image* image,MagickCLEnv clEnv,
415 const double radius,
const double sigma,
ExceptionInfo *exception)
421 channel_mask=get32BitChannelValue(image->channel_mask),
461 filteredImageBuffer=NULL;
462 tempImageBuffer=NULL;
463 imageKernelBuffer=NULL;
465 blurColumnKernel=NULL;
466 outputReady=MagickFalse;
468 assert(image != (
Image *) NULL);
469 assert(image->signature == MagickCoreSignature);
470 if (IsEventLogging() != MagickFalse)
471 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
473 device=RequestOpenCLDevice(clEnv);
474 if (device == (MagickCLDevice) NULL)
476 queue=AcquireOpenCLCommandQueue(device);
477 if (queue == (cl_command_queue) NULL)
479 filteredImage=cloneImage(image,exception);
480 if (filteredImage == (
Image *) NULL)
482 if (filteredImage->number_channels != image->number_channels)
484 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
485 if (imageBuffer == (cl_mem) NULL)
487 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
488 if (filteredImageBuffer == (cl_mem) NULL)
491 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
493 if (imageKernelBuffer == (cl_mem) NULL)
496 length=image->columns*image->rows;
497 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
498 sizeof(cl_float4),(
void *) NULL);
499 if (tempImageBuffer == (cl_mem) NULL)
502 blurRowKernel=AcquireOpenCLKernel(device,
"BlurRow");
503 if (blurRowKernel == (cl_kernel) NULL)
505 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
506 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
510 number_channels=(cl_uint) image->number_channels;
511 imageColumns=(cl_uint) image->columns;
512 imageRows=(cl_uint) image->rows;
515 status =SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
516 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),&number_channels);
517 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_int),&channel_mask);
518 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
519 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
520 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
521 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
522 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
523 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
524 if (status != CL_SUCCESS)
526 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
527 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
531 gsize[0]=chunkSize*((image->columns+chunkSize-1)/chunkSize);
532 gsize[1]=image->rows;
536 outputReady=EnqueueOpenCLKernel(queue,blurRowKernel,2,(
size_t *) NULL,gsize,
537 lsize,image,filteredImage,MagickFalse,exception);
538 if (outputReady == MagickFalse)
541 blurColumnKernel=AcquireOpenCLKernel(device,
"BlurColumn");
542 if (blurColumnKernel == (cl_kernel) NULL)
544 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
545 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
550 status =SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
551 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),&number_channels);
552 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_int),&channel_mask);
553 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
554 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
555 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
556 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
557 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
558 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
559 if (status != CL_SUCCESS)
561 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
562 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
566 gsize[0]=image->columns;
567 gsize[1]=chunkSize*((image->rows+chunkSize-1)/chunkSize);
571 outputReady=EnqueueOpenCLKernel(queue,blurColumnKernel,2,(
size_t *) NULL,gsize,
572 lsize,image,filteredImage,MagickFalse,exception);
576 if (imageBuffer != (cl_mem) NULL)
577 ReleaseOpenCLMemObject(imageBuffer);
578 if (filteredImageBuffer != (cl_mem) NULL)
579 ReleaseOpenCLMemObject(filteredImageBuffer);
580 if (tempImageBuffer != (cl_mem) NULL)
581 ReleaseOpenCLMemObject(tempImageBuffer);
582 if (imageKernelBuffer != (cl_mem) NULL)
583 ReleaseOpenCLMemObject(imageKernelBuffer);
584 if (blurRowKernel != (cl_kernel) NULL)
585 ReleaseOpenCLKernel(blurRowKernel);
586 if (blurColumnKernel != (cl_kernel) NULL)
587 ReleaseOpenCLKernel(blurColumnKernel);
588 if (queue != (cl_command_queue) NULL)
589 ReleaseOpenCLCommandQueue(device,queue);
590 if (device != (MagickCLDevice) NULL)
591 ReleaseOpenCLDevice(device);
592 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
593 filteredImage=DestroyImage(filteredImage);
595 return(filteredImage);
598MagickPrivate
Image* AccelerateBlurImage(
const Image *image,
599 const double radius,
const double sigma,
ExceptionInfo *exception)
607 assert(image != NULL);
609 if (IsEventLogging() != MagickFalse)
610 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
612 if (checkAccelerateCondition(image) == MagickFalse)
613 return((
Image *) NULL);
615 clEnv=getOpenCLEnvironment(exception);
616 if (clEnv == (MagickCLEnv) NULL)
617 return((
Image *) NULL);
619 filteredImage=ComputeBlurImage(image,clEnv,radius,sigma,exception);
620 return(filteredImage);
635static MagickBooleanType ComputeContrastImage(
Image *image,MagickCLEnv clEnv,
664 assert(image != (
Image *) NULL);
665 assert(image->signature == MagickCoreSignature);
666 if (IsEventLogging() != MagickFalse)
667 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
672 outputReady=MagickFalse;
674 device=RequestOpenCLDevice(clEnv);
675 if (device == (MagickCLDevice) NULL)
677 queue=AcquireOpenCLCommandQueue(device);
678 if (queue == (cl_command_queue) NULL)
680 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
681 if (imageBuffer == (cl_mem) NULL)
684 contrastKernel=AcquireOpenCLKernel(device,
"Contrast");
685 if (contrastKernel == (cl_kernel) NULL)
687 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
688 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
692 number_channels=(cl_uint) image->number_channels;
693 sign=sharpen != MagickFalse ? 1 : -1;
696 status =SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
697 status|=SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_uint),&number_channels);
698 status|=SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_int),&sign);
699 if (status != CL_SUCCESS)
701 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
702 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
706 gsize[0]=image->columns;
707 gsize[1]=image->rows;
709 outputReady=EnqueueOpenCLKernel(queue,contrastKernel,2,(
const size_t *) NULL,
710 gsize,(
const size_t *) NULL,image,(
Image *) NULL,MagickFalse,exception);
714 if (imageBuffer != (cl_mem) NULL)
715 ReleaseOpenCLMemObject(imageBuffer);
716 if (contrastKernel != (cl_kernel) NULL)
717 ReleaseOpenCLKernel(contrastKernel);
718 if (queue != (cl_command_queue) NULL)
719 ReleaseOpenCLCommandQueue(device,queue);
720 if (device != (MagickCLDevice) NULL)
721 ReleaseOpenCLDevice(device);
726MagickPrivate MagickBooleanType AccelerateContrastImage(
Image *image,
735 assert(image != NULL);
737 if (IsEventLogging() != MagickFalse)
738 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
740 if (checkAccelerateCondition(image) == MagickFalse)
743 clEnv=getOpenCLEnvironment(exception);
744 if (clEnv == (MagickCLEnv) NULL)
747 status=ComputeContrastImage(image,clEnv,sharpen,exception);
763static MagickBooleanType ComputeContrastStretchImage(
Image *image,
764 MagickCLEnv clEnv,
const double black_point,
const double white_point,
767#define ContrastStretchImageTag "ContrastStretch/Image"
768#define MaxRange(color) ((cl_float) ScaleQuantumToMap((Quantum) (color)))
777 channel_mask=get32BitChannelValue(image->channel_mask),
828 assert(image != (
Image *) NULL);
829 assert(image->signature == MagickCoreSignature);
830 if (IsEventLogging() != MagickFalse)
831 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
839 histogramBuffer=NULL;
840 stretchMapBuffer=NULL;
841 histogramKernel=NULL;
843 outputReady=MagickFalse;
848 device=RequestOpenCLDevice(clEnv);
849 if (device == (MagickCLDevice) NULL)
851 queue=AcquireOpenCLCommandQueue(device);
852 if (queue == (cl_command_queue) NULL)
858 histogram=(cl_uint4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*histogram));
860 if (histogram == (cl_uint4 *) NULL)
861 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed", image->filename);
864 (void) memset(histogram,0,(MaxMap+1)*
sizeof(*histogram));
880 image_view=AcquireAuthenticCacheView(image,exception);
881 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
883 if (inputPixels == (
void *) NULL)
885 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
891 if (ALIGNED(inputPixels,CLPixelPacket))
893 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
897 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
900 length = image->columns * image->rows;
901 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
902 if (clStatus != CL_SUCCESS)
904 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
911 if (ALIGNED(histogram,cl_uint4))
913 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
918 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
923 histogramBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(cl_uint4), hostPtr, &clStatus);
924 if (clStatus != CL_SUCCESS)
926 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
930 status = LaunchHistogramKernel(clEnv, device, queue, imageBuffer, histogramBuffer, image, image->channel_mask,exception);
931 if (status == MagickFalse)
935 if (ALIGNED(histogram,cl_uint4))
938 clEnv->library->clEnqueueMapBuffer(queue, histogramBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(cl_uint4), 0, NULL, NULL, &clStatus);
943 clStatus = clEnv->library->clEnqueueReadBuffer(queue, histogramBuffer, CL_TRUE, 0, length *
sizeof(cl_uint4), histogram, 0, NULL, NULL);
945 if (clStatus != CL_SUCCESS)
947 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
952 if (ALIGNED(histogram,cl_uint4))
954 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, histogramBuffer, histogram, 0, NULL, NULL);
955 if (clStatus != CL_SUCCESS)
957 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueUnmapMemObject failed.",
".");
964 if (imageBuffer!=NULL)
965 clEnv->library->clReleaseMemObject(imageBuffer);
973 white.x=MaxRange(QuantumRange);
974 if ((image->channel_mask & RedChannel) != 0)
977 for (i=0; i <= (ssize_t) MaxMap; i++)
979 intensity+=histogram[i].s[2];
980 if (intensity > black_point)
983 black.x=(cl_float) i;
985 for (i=(ssize_t) MaxMap; i != 0; i--)
987 intensity+=histogram[i].s[2];
988 if (intensity > ((
double) image->columns*image->rows-white_point))
991 white.x=(cl_float) i;
994 white.y=MaxRange(QuantumRange);
995 if ((image->channel_mask & GreenChannel) != 0)
998 for (i=0; i <= (ssize_t) MaxMap; i++)
1000 intensity+=histogram[i].s[2];
1001 if (intensity > black_point)
1004 black.y=(cl_float) i;
1006 for (i=(ssize_t) MaxMap; i != 0; i--)
1008 intensity+=histogram[i].s[2];
1009 if (intensity > ((
double) image->columns*image->rows-white_point))
1012 white.y=(cl_float) i;
1015 white.z=MaxRange(QuantumRange);
1016 if ((image->channel_mask & BlueChannel) != 0)
1019 for (i=0; i <= (ssize_t) MaxMap; i++)
1021 intensity+=histogram[i].s[2];
1022 if (intensity > black_point)
1025 black.z=(cl_float) i;
1027 for (i=(ssize_t) MaxMap; i != 0; i--)
1029 intensity+=histogram[i].s[2];
1030 if (intensity > ((
double) image->columns*image->rows-white_point))
1033 white.z=(cl_float) i;
1036 white.w=MaxRange(QuantumRange);
1037 if ((image->channel_mask & AlphaChannel) != 0)
1040 for (i=0; i <= (ssize_t) MaxMap; i++)
1042 intensity+=histogram[i].s[2];
1043 if (intensity > black_point)
1046 black.w=(cl_float) i;
1048 for (i=(ssize_t) MaxMap; i != 0; i--)
1050 intensity+=histogram[i].s[2];
1051 if (intensity > ((
double) image->columns*image->rows-white_point))
1054 white.w=(cl_float) i;
1057 stretch_map=(
PixelPacket *) AcquireQuantumMemory(MaxMap+1UL,
1058 sizeof(*stretch_map));
1061 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
1067 (void) memset(stretch_map,0,(MaxMap+1)*
sizeof(*stretch_map));
1068 for (i=0; i <= (ssize_t) MaxMap; i++)
1070 if ((image->channel_mask & RedChannel) != 0)
1072 if (i < (ssize_t) black.x)
1073 stretch_map[i].red=(Quantum) 0;
1075 if (i > (ssize_t) white.x)
1076 stretch_map[i].red=QuantumRange;
1078 if (black.x != white.x)
1079 stretch_map[i].red=ScaleMapToQuantum((MagickRealType) (MaxMap*
1080 (i-black.x)/(white.x-black.x)));
1082 if ((image->channel_mask & GreenChannel) != 0)
1084 if (i < (ssize_t) black.y)
1085 stretch_map[i].green=0;
1087 if (i > (ssize_t) white.y)
1088 stretch_map[i].green=QuantumRange;
1090 if (black.y != white.y)
1091 stretch_map[i].green=ScaleMapToQuantum((MagickRealType) (MaxMap*
1092 (i-black.y)/(white.y-black.y)));
1094 if ((image->channel_mask & BlueChannel) != 0)
1096 if (i < (ssize_t) black.z)
1097 stretch_map[i].blue=0;
1099 if (i > (ssize_t) white.z)
1100 stretch_map[i].blue= QuantumRange;
1102 if (black.z != white.z)
1103 stretch_map[i].blue=ScaleMapToQuantum((MagickRealType) (MaxMap*
1104 (i-black.z)/(white.z-black.z)));
1106 if ((image->channel_mask & AlphaChannel) != 0)
1108 if (i < (ssize_t) black.w)
1109 stretch_map[i].alpha=0;
1111 if (i > (ssize_t) white.w)
1112 stretch_map[i].alpha=QuantumRange;
1114 if (black.w != white.w)
1115 stretch_map[i].alpha=ScaleMapToQuantum((MagickRealType) (MaxMap*
1116 (i-black.w)/(white.w-black.w)));
1123 if (((image->channel_mask & AlphaChannel) != 0) || (((image->channel_mask & IndexChannel) != 0) &&
1124 (image->colorspace == CMYKColorspace)))
1125 image->storage_class=DirectClass;
1126 if (image->storage_class == PseudoClass)
1131 for (i=0; i < (ssize_t) image->colors; i++)
1133 if ((image->channel_mask & RedChannel) != 0)
1135 if (black.x != white.x)
1136 image->colormap[i].red=stretch_map[
1137 ScaleQuantumToMap(image->colormap[i].red)].red;
1139 if ((image->channel_mask & GreenChannel) != 0)
1141 if (black.y != white.y)
1142 image->colormap[i].green=stretch_map[
1143 ScaleQuantumToMap(image->colormap[i].green)].green;
1145 if ((image->channel_mask & BlueChannel) != 0)
1147 if (black.z != white.z)
1148 image->colormap[i].blue=stretch_map[
1149 ScaleQuantumToMap(image->colormap[i].blue)].blue;
1151 if ((image->channel_mask & AlphaChannel) != 0)
1153 if (black.w != white.w)
1154 image->colormap[i].alpha=stretch_map[
1155 ScaleQuantumToMap(image->colormap[i].alpha)].alpha;
1170#ifdef RECREATEBUFFER
1174 if (ALIGNED(inputPixels,CLPixelPacket))
1176 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
1180 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1183 length = image->columns * image->rows;
1184 imageBuffer = clEnv->library->clCreateBuffer(context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1185 if (clStatus != CL_SUCCESS)
1187 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1195 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1196 hostPtr = stretch_map;
1200 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1201 hostPtr = stretch_map;
1204 length = (MaxMap+1);
1205 stretchMapBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(
PixelPacket), hostPtr, &clStatus);
1206 if (clStatus != CL_SUCCESS)
1208 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1213 stretchKernel = AcquireOpenCLKernel(device,
"ContrastStretch");
1214 if (stretchKernel == NULL)
1216 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
1222 clStatus=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
1223 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_int),&channel_mask);
1224 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_mem),(
void *)&stretchMapBuffer);
1225 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_float4),&white);
1226 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_float4),&black);
1227 if (clStatus != CL_SUCCESS)
1229 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1234 global_work_size[0] = image->columns;
1235 global_work_size[1] = image->rows;
1237 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, stretchKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1239 if (clStatus != CL_SUCCESS)
1241 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1244 RecordProfileData(device,stretchKernel,event);
1247 if (ALIGNED(inputPixels,CLPixelPacket))
1249 length = image->columns * image->rows;
1250 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
1254 length = image->columns * image->rows;
1255 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
1257 if (clStatus != CL_SUCCESS)
1259 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1263 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
1267 image_view=DestroyCacheView(image_view);
1269 if (imageBuffer!=NULL)
1270 clEnv->library->clReleaseMemObject(imageBuffer);
1272 if (stretchMapBuffer!=NULL)
1273 clEnv->library->clReleaseMemObject(stretchMapBuffer);
1274 if (stretch_map!=NULL)
1275 stretch_map=(
PixelPacket *) RelinquishMagickMemory(stretch_map);
1276 if (histogramBuffer!=NULL)
1277 clEnv->library->clReleaseMemObject(histogramBuffer);
1278 if (histogram!=NULL)
1279 histogram=(cl_uint4 *) RelinquishMagickMemory(histogram);
1280 if (histogramKernel!=NULL)
1281 ReleaseOpenCLKernel(histogramKernel);
1282 if (stretchKernel!=NULL)
1283 ReleaseOpenCLKernel(stretchKernel);
1285 ReleaseOpenCLCommandQueue(device,queue);
1287 ReleaseOpenCLDevice(device);
1289 return(outputReady);
1292MagickPrivate MagickBooleanType AccelerateContrastStretchImage(
1293 Image *image,
const double black_point,
const double white_point,
1302 assert(image != NULL);
1304 if (IsEventLogging() != MagickFalse)
1305 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1307 if ((checkAccelerateConditionRGBA(image) == MagickFalse) ||
1308 (checkHistogramCondition(image,image->intensity) == MagickFalse))
1309 return(MagickFalse);
1311 clEnv=getOpenCLEnvironment(exception);
1312 if (clEnv == (MagickCLEnv) NULL)
1313 return(MagickFalse);
1315 status=ComputeContrastStretchImage(image,clEnv,black_point,white_point,
1332static Image *ComputeDespeckleImage(
const Image *image,MagickCLEnv clEnv,
1336 X[4] = {0, 1, 1,-1},
1337 Y[4] = {1, 0, 1, 1};
1340 *filteredImage_view,
1360 filteredImageBuffer,
1384 global_work_size[2];
1398 filteredImage_view=NULL;
1399 filteredPixels=NULL;
1401 filteredImageBuffer=NULL;
1404 tempImageBuffer[0]=NULL;
1405 tempImageBuffer[1]=NULL;
1406 outputReady=MagickFalse;
1408 device=RequestOpenCLDevice(clEnv);
1409 if (device == (MagickCLDevice) NULL)
1411 queue=AcquireOpenCLCommandQueue(device);
1412 if (queue == (cl_command_queue) NULL)
1415 image_view=AcquireAuthenticCacheView(image,exception);
1416 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
1417 if (inputPixels == (
void *) NULL)
1419 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
1423 if (ALIGNED(inputPixels,CLPixelPacket))
1425 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1429 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
1432 length = image->columns * image->rows;
1433 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1434 if (clStatus != CL_SUCCESS)
1436 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1440 mem_flags = CL_MEM_READ_WRITE;
1441 length = image->columns * image->rows;
1442 for (k = 0; k < 2; k++)
1444 tempImageBuffer[k] = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), NULL, &clStatus);
1445 if (clStatus != CL_SUCCESS)
1447 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1452 filteredImage = CloneImage(image,0,0,MagickTrue,exception);
1453 assert(filteredImage != NULL);
1454 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
1456 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"CloneImage failed.",
".");
1459 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
1460 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
1461 if (filteredPixels == (
void *) NULL)
1463 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
1467 if (ALIGNED(filteredPixels,CLPixelPacket))
1469 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
1470 hostPtr = filteredPixels;
1474 mem_flags = CL_MEM_WRITE_ONLY;
1478 length = image->columns * image->rows;
1479 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
1480 if (clStatus != CL_SUCCESS)
1482 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1486 hullPass1 = AcquireOpenCLKernel(device,
"HullPass1");
1487 hullPass2 = AcquireOpenCLKernel(device,
"HullPass2");
1489 clStatus =clEnv->library->clSetKernelArg(hullPass1,0,
sizeof(cl_mem),(
void *)&imageBuffer);
1490 clStatus |=clEnv->library->clSetKernelArg(hullPass1,1,
sizeof(cl_mem),(
void *)(tempImageBuffer+1));
1491 imageWidth = (
unsigned int) image->columns;
1492 clStatus |=clEnv->library->clSetKernelArg(hullPass1,2,
sizeof(
unsigned int),(
void *)&imageWidth);
1493 imageHeight = (
unsigned int) image->rows;
1494 clStatus |=clEnv->library->clSetKernelArg(hullPass1,3,
sizeof(
unsigned int),(
void *)&imageHeight);
1495 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
1496 clStatus |=clEnv->library->clSetKernelArg(hullPass1,6,
sizeof(
int),(
void *)&matte);
1497 if (clStatus != CL_SUCCESS)
1499 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1503 clStatus = clEnv->library->clSetKernelArg(hullPass2,0,
sizeof(cl_mem),(
void *)(tempImageBuffer+1));
1504 clStatus |=clEnv->library->clSetKernelArg(hullPass2,1,
sizeof(cl_mem),(
void *)tempImageBuffer);
1505 imageWidth = (
unsigned int) image->columns;
1506 clStatus |=clEnv->library->clSetKernelArg(hullPass2,2,
sizeof(
unsigned int),(
void *)&imageWidth);
1507 imageHeight = (
unsigned int) image->rows;
1508 clStatus |=clEnv->library->clSetKernelArg(hullPass2,3,
sizeof(
unsigned int),(
void *)&imageHeight);
1509 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
1510 clStatus |=clEnv->library->clSetKernelArg(hullPass2,6,
sizeof(
int),(
void *)&matte);
1511 if (clStatus != CL_SUCCESS)
1513 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1518 global_work_size[0] = image->columns;
1519 global_work_size[1] = image->rows;
1522 for (k = 0; k < 4; k++)
1531 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1532 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1533 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1534 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1535 if (clStatus != CL_SUCCESS)
1537 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1541 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1542 if (clStatus != CL_SUCCESS)
1544 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1547 RecordProfileData(device,hullPass1,event);
1550 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1551 if (clStatus != CL_SUCCESS)
1553 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1556 RecordProfileData(device,hullPass2,event);
1559 clStatus =clEnv->library->clSetKernelArg(hullPass1,0,
sizeof(cl_mem),(
void *)(tempImageBuffer));
1560 offset.s[0] = -X[k];
1561 offset.s[1] = -Y[k];
1563 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1564 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1565 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1566 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1567 if (clStatus != CL_SUCCESS)
1569 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1573 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1574 if (clStatus != CL_SUCCESS)
1576 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1579 RecordProfileData(device,hullPass1,event);
1582 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1583 if (clStatus != CL_SUCCESS)
1585 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1588 RecordProfileData(device,hullPass2,event);
1590 offset.s[0] = -X[k];
1591 offset.s[1] = -Y[k];
1593 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1594 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1595 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1596 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1597 if (clStatus != CL_SUCCESS)
1599 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1603 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1604 if (clStatus != CL_SUCCESS)
1606 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1609 RecordProfileData(device,hullPass1,event);
1612 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1613 if (clStatus != CL_SUCCESS)
1615 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1618 RecordProfileData(device,hullPass2,event);
1623 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1624 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1625 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1626 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1629 clStatus |=clEnv->library->clSetKernelArg(hullPass2,1,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
1631 if (clStatus != CL_SUCCESS)
1633 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1637 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1638 if (clStatus != CL_SUCCESS)
1640 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1643 RecordProfileData(device,hullPass1,event);
1646 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1647 if (clStatus != CL_SUCCESS)
1649 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1652 RecordProfileData(device,hullPass2,event);
1655 if (ALIGNED(filteredPixels,CLPixelPacket))
1657 length = image->columns * image->rows;
1658 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
1662 length = image->columns * image->rows;
1663 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
1665 if (clStatus != CL_SUCCESS)
1667 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1671 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
1675 image_view=DestroyCacheView(image_view);
1676 if (filteredImage_view != NULL)
1677 filteredImage_view=DestroyCacheView(filteredImage_view);
1680 ReleaseOpenCLCommandQueue(device,queue);
1682 ReleaseOpenCLDevice(device);
1683 if (imageBuffer!=NULL)
1684 clEnv->library->clReleaseMemObject(imageBuffer);
1685 for (k = 0; k < 2; k++)
1687 if (tempImageBuffer[k]!=NULL)
1688 clEnv->library->clReleaseMemObject(tempImageBuffer[k]);
1690 if (filteredImageBuffer!=NULL)
1691 clEnv->library->clReleaseMemObject(filteredImageBuffer);
1692 if (hullPass1!=NULL)
1693 ReleaseOpenCLKernel(hullPass1);
1694 if (hullPass2!=NULL)
1695 ReleaseOpenCLKernel(hullPass2);
1696 if (outputReady == MagickFalse && filteredImage != NULL)
1697 filteredImage=DestroyImage(filteredImage);
1699 return(filteredImage);
1702MagickPrivate
Image *AccelerateDespeckleImage(
const Image* image,
1711 assert(image != NULL);
1714 if (checkAccelerateConditionRGBA(image) == MagickFalse)
1715 return((
Image *) NULL);
1717 clEnv=getOpenCLEnvironment(exception);
1718 if (clEnv == (MagickCLEnv) NULL)
1719 return((
Image *) NULL);
1721 filteredImage=ComputeDespeckleImage(image,clEnv,exception);
1722 return(filteredImage);
1737static MagickBooleanType ComputeEqualizeImage(
Image *image,MagickCLEnv clEnv,
1740#define EqualizeImageTag "Equalize/Image"
1749 channel_mask=get32BitChannelValue(image->channel_mask),
1793 global_work_size[2];
1799 assert(image != (
Image *) NULL);
1800 assert(image->signature == MagickCoreSignature);
1801 if (IsEventLogging() != MagickFalse)
1802 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1811 histogramBuffer=NULL;
1812 equalizeMapBuffer=NULL;
1813 histogramKernel=NULL;
1814 equalizeKernel=NULL;
1815 outputReady=MagickFalse;
1820 device=RequestOpenCLDevice(clEnv);
1821 if (device == (MagickCLDevice) NULL)
1823 queue=AcquireOpenCLCommandQueue(device);
1824 if (queue == (cl_command_queue) NULL)
1830 histogram=(cl_uint4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*histogram));
1831 if (histogram == (cl_uint4 *) NULL)
1832 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1835 (void) memset(histogram,0,(MaxMap+1)*
sizeof(*histogram));
1840 image_view=AcquireAuthenticCacheView(image,exception);
1841 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
1843 if (inputPixels == (
void *) NULL)
1845 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
1851 if (ALIGNED(inputPixels,CLPixelPacket))
1853 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1857 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
1860 length = image->columns * image->rows;
1861 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1862 if (clStatus != CL_SUCCESS)
1864 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1871 if (ALIGNED(histogram,cl_uint4))
1873 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
1874 hostPtr = histogram;
1878 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1879 hostPtr = histogram;
1882 length = (MaxMap+1);
1883 histogramBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(cl_uint4), hostPtr, &clStatus);
1884 if (clStatus != CL_SUCCESS)
1886 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1890 status = LaunchHistogramKernel(clEnv, device, queue, imageBuffer, histogramBuffer, image, image->channel_mask, exception);
1891 if (status == MagickFalse)
1895 if (ALIGNED(histogram,cl_uint4))
1897 length = (MaxMap+1);
1898 clEnv->library->clEnqueueMapBuffer(queue, histogramBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(cl_uint4), 0, NULL, NULL, &clStatus);
1902 length = (MaxMap+1);
1903 clStatus = clEnv->library->clEnqueueReadBuffer(queue, histogramBuffer, CL_TRUE, 0, length *
sizeof(cl_uint4), histogram, 0, NULL, NULL);
1905 if (clStatus != CL_SUCCESS)
1907 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1912 if (ALIGNED(histogram,cl_uint4))
1914 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, histogramBuffer, histogram, 0, NULL, NULL);
1915 if (clStatus != CL_SUCCESS)
1917 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueUnmapMemObject failed.",
".");
1923#ifdef RECREATEBUFFER
1924 if (imageBuffer!=NULL)
1925 clEnv->library->clReleaseMemObject(imageBuffer);
1929 equalize_map=(
PixelPacket *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*equalize_map));
1931 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1933 map=(cl_float4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*map));
1934 if (map == (cl_float4 *) NULL)
1935 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1940 (void) memset(&intensity,0,
sizeof(intensity));
1941 for (i=0; i <= (ssize_t) MaxMap; i++)
1943 if ((image->channel_mask & SyncChannels) != 0)
1945 intensity.x+=histogram[i].s[2];
1949 if ((image->channel_mask & RedChannel) != 0)
1950 intensity.x+=histogram[i].s[2];
1951 if ((image->channel_mask & GreenChannel) != 0)
1952 intensity.y+=histogram[i].s[1];
1953 if ((image->channel_mask & BlueChannel) != 0)
1954 intensity.z+=histogram[i].s[0];
1955 if ((image->channel_mask & AlphaChannel) != 0)
1956 intensity.w+=histogram[i].s[3];
1960 white=map[(int) MaxMap];
1961 (void) memset(equalize_map,0,(MaxMap+1)*
sizeof(*equalize_map));
1962 for (i=0; i <= (ssize_t) MaxMap; i++)
1964 if ((image->channel_mask & SyncChannels) != 0)
1966 if (white.x != black.x)
1967 equalize_map[i].red=ScaleMapToQuantum((MagickRealType) ((MaxMap*
1968 (map[i].x-black.x))/(white.x-black.x)));
1971 if (((image->channel_mask & RedChannel) != 0) && (white.x != black.x))
1972 equalize_map[i].red=ScaleMapToQuantum((MagickRealType) ((MaxMap*
1973 (map[i].x-black.x))/(white.x-black.x)));
1974 if (((image->channel_mask & GreenChannel) != 0) && (white.y != black.y))
1975 equalize_map[i].green=ScaleMapToQuantum((MagickRealType) ((MaxMap*
1976 (map[i].y-black.y))/(white.y-black.y)));
1977 if (((image->channel_mask & BlueChannel) != 0) && (white.z != black.z))
1978 equalize_map[i].blue=ScaleMapToQuantum((MagickRealType) ((MaxMap*
1979 (map[i].z-black.z))/(white.z-black.z)));
1980 if (((image->channel_mask & AlphaChannel) != 0) && (white.w != black.w))
1981 equalize_map[i].alpha=ScaleMapToQuantum((MagickRealType) ((MaxMap*
1982 (map[i].w-black.w))/(white.w-black.w)));
1985 if (image->storage_class == PseudoClass)
1990 for (i=0; i < (ssize_t) image->colors; i++)
1992 if ((image->channel_mask & SyncChannels) != 0)
1994 if (white.x != black.x)
1996 image->colormap[i].red=equalize_map[
1997 ScaleQuantumToMap(image->colormap[i].red)].red;
1998 image->colormap[i].green=equalize_map[
1999 ScaleQuantumToMap(image->colormap[i].green)].red;
2000 image->colormap[i].blue=equalize_map[
2001 ScaleQuantumToMap(image->colormap[i].blue)].red;
2002 image->colormap[i].alpha=equalize_map[
2003 ScaleQuantumToMap(image->colormap[i].alpha)].red;
2007 if (((image->channel_mask & RedChannel) != 0) && (white.x != black.x))
2008 image->colormap[i].red=equalize_map[
2009 ScaleQuantumToMap(image->colormap[i].red)].red;
2010 if (((image->channel_mask & GreenChannel) != 0) && (white.y != black.y))
2011 image->colormap[i].green=equalize_map[
2012 ScaleQuantumToMap(image->colormap[i].green)].green;
2013 if (((image->channel_mask & BlueChannel) != 0) && (white.z != black.z))
2014 image->colormap[i].blue=equalize_map[
2015 ScaleQuantumToMap(image->colormap[i].blue)].blue;
2016 if (((image->channel_mask & AlphaChannel) != 0) && (white.w != black.w))
2017 image->colormap[i].alpha=equalize_map[
2018 ScaleQuantumToMap(image->colormap[i].alpha)].alpha;
2031#ifdef RECREATEBUFFER
2035 if (ALIGNED(inputPixels,CLPixelPacket))
2037 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
2041 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2044 length = image->columns * image->rows;
2045 imageBuffer = clEnv->library->clCreateBuffer(context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2046 if (clStatus != CL_SUCCESS)
2048 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2056 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
2057 hostPtr = equalize_map;
2061 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2062 hostPtr = equalize_map;
2065 length = (MaxMap+1);
2066 equalizeMapBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(
PixelPacket), hostPtr, &clStatus);
2067 if (clStatus != CL_SUCCESS)
2069 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2074 equalizeKernel = AcquireOpenCLKernel(device,
"Equalize");
2075 if (equalizeKernel == NULL)
2077 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2083 clStatus=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2084 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_int),&channel_mask);
2085 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_mem),(
void *)&equalizeMapBuffer);
2086 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_float4),&white);
2087 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_float4),&black);
2088 if (clStatus != CL_SUCCESS)
2090 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2095 global_work_size[0] = image->columns;
2096 global_work_size[1] = image->rows;
2098 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, equalizeKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
2100 if (clStatus != CL_SUCCESS)
2102 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2105 RecordProfileData(device,equalizeKernel,event);
2108 if (ALIGNED(inputPixels,CLPixelPacket))
2110 length = image->columns * image->rows;
2111 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2115 length = image->columns * image->rows;
2116 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
2118 if (clStatus != CL_SUCCESS)
2120 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
2124 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
2128 image_view=DestroyCacheView(image_view);
2130 if (imageBuffer!=NULL)
2131 clEnv->library->clReleaseMemObject(imageBuffer);
2133 map=(cl_float4 *) RelinquishMagickMemory(map);
2134 if (equalizeMapBuffer!=NULL)
2135 clEnv->library->clReleaseMemObject(equalizeMapBuffer);
2136 if (equalize_map!=NULL)
2137 equalize_map=(
PixelPacket *) RelinquishMagickMemory(equalize_map);
2138 if (histogramBuffer!=NULL)
2139 clEnv->library->clReleaseMemObject(histogramBuffer);
2140 if (histogram!=NULL)
2141 histogram=(cl_uint4 *) RelinquishMagickMemory(histogram);
2142 if (histogramKernel!=NULL)
2143 ReleaseOpenCLKernel(histogramKernel);
2144 if (equalizeKernel!=NULL)
2145 ReleaseOpenCLKernel(equalizeKernel);
2147 ReleaseOpenCLCommandQueue(device, queue);
2149 ReleaseOpenCLDevice(device);
2151 return(outputReady);
2154MagickPrivate MagickBooleanType AccelerateEqualizeImage(
Image *image,
2163 assert(image != NULL);
2165 if (IsEventLogging() != MagickFalse)
2166 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2168 if ((checkAccelerateConditionRGBA(image) == MagickFalse) ||
2169 (checkHistogramCondition(image,image->intensity) == MagickFalse))
2170 return(MagickFalse);
2172 clEnv=getOpenCLEnvironment(exception);
2173 if (clEnv == (MagickCLEnv) NULL)
2174 return(MagickFalse);
2176 status=ComputeEqualizeImage(image,clEnv,exception);
2192static MagickBooleanType ComputeFunctionImage(
Image *image,MagickCLEnv clEnv,
2193 const MagickFunction function,
const size_t number_parameters,
2200 channel_mask=get32BitChannelValue(image->channel_mask),
2215 *parametersBufferPtr;
2227 assert(image != (
Image *) NULL);
2228 assert(image->signature == MagickCoreSignature);
2229 if (IsEventLogging() != MagickFalse)
2230 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2234 functionKernel=NULL;
2235 parametersBuffer=NULL;
2236 outputReady=MagickFalse;
2238 device=RequestOpenCLDevice(clEnv);
2239 if (device == (MagickCLDevice) NULL)
2241 queue=AcquireOpenCLCommandQueue(device);
2242 if (queue == (cl_command_queue) NULL)
2244 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
2245 if (imageBuffer == (cl_mem) NULL)
2248 parametersBufferPtr=(
float *) AcquireQuantumMemory(number_parameters,
2250 if (parametersBufferPtr == (
float *) NULL)
2252 for (i=0; i<number_parameters; i++)
2253 parametersBufferPtr[i]=(
float) parameters[i];
2254 parametersBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
2255 CL_MEM_COPY_HOST_PTR,number_parameters*
sizeof(*parametersBufferPtr),
2256 parametersBufferPtr);
2257 parametersBufferPtr=(
float *) RelinquishMagickMemory(parametersBufferPtr);
2258 if (parametersBuffer == (cl_mem) NULL)
2260 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2261 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
2265 functionKernel=AcquireOpenCLKernel(device,
"ComputeFunction");
2266 if (functionKernel == (cl_kernel) NULL)
2268 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2269 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2273 number_channels=(cl_uint) image->number_channels;
2274 number_params=(cl_uint) number_parameters;
2277 status =SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2278 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
2279 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_int),&channel_mask);
2280 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(MagickFunction),(
void *)&function);
2281 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_uint),(
void *)&number_params);
2282 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_mem),(
void *)¶metersBuffer);
2283 if (status != CL_SUCCESS)
2285 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2286 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
2290 gsize[0]=image->columns;
2291 gsize[1]=image->rows;
2292 outputReady=EnqueueOpenCLKernel(queue,functionKernel,2,(
const size_t *) NULL,
2293 gsize,(
const size_t *) NULL,image,(
const Image *) NULL,MagickFalse,
2298 if (imageBuffer != (cl_mem) NULL)
2299 ReleaseOpenCLMemObject(imageBuffer);
2300 if (parametersBuffer != (cl_mem) NULL)
2301 ReleaseOpenCLMemObject(parametersBuffer);
2302 if (functionKernel != (cl_kernel) NULL)
2303 ReleaseOpenCLKernel(functionKernel);
2304 if (queue != (cl_command_queue) NULL)
2305 ReleaseOpenCLCommandQueue(device,queue);
2306 if (device != (MagickCLDevice) NULL)
2307 ReleaseOpenCLDevice(device);
2308 return(outputReady);
2311MagickPrivate MagickBooleanType AccelerateFunctionImage(
Image *image,
2312 const MagickFunction function,
const size_t number_parameters,
2321 assert(image != NULL);
2323 if (IsEventLogging() != MagickFalse)
2324 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2326 if (checkAccelerateCondition(image) == MagickFalse)
2327 return(MagickFalse);
2329 clEnv=getOpenCLEnvironment(exception);
2330 if (clEnv == (MagickCLEnv) NULL)
2331 return(MagickFalse);
2333 status=ComputeFunctionImage(image,clEnv,function,number_parameters,
2334 parameters,exception);
2350static MagickBooleanType ComputeGrayscaleImage(
Image *image,MagickCLEnv clEnv,
2380 assert(image != (
Image *) NULL);
2381 assert(image->signature == MagickCoreSignature);
2382 if (IsEventLogging() != MagickFalse)
2383 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2387 grayscaleKernel=NULL;
2388 outputReady=MagickFalse;
2390 device=RequestOpenCLDevice(clEnv);
2391 if (device == (MagickCLDevice) NULL)
2393 queue=AcquireOpenCLCommandQueue(device);
2394 if (queue == (cl_command_queue) NULL)
2396 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
2397 if (imageBuffer == (cl_mem) NULL)
2400 grayscaleKernel=AcquireOpenCLKernel(device,
"Grayscale");
2401 if (grayscaleKernel == (cl_kernel) NULL)
2403 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2404 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2408 number_channels=(cl_uint) image->number_channels;
2409 intensityMethod=(cl_uint) method;
2410 colorspace=(cl_uint) image->colorspace;
2413 status =SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2414 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&number_channels);
2415 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&colorspace);
2416 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&intensityMethod);
2417 if (status != CL_SUCCESS)
2419 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2420 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
2424 gsize[0]=image->columns;
2425 gsize[1]=image->rows;
2426 outputReady=EnqueueOpenCLKernel(queue,grayscaleKernel,2,
2427 (
const size_t *) NULL,gsize,(
const size_t *) NULL,image,(
Image *) NULL,
2428 MagickFalse,exception);
2432 if (imageBuffer != (cl_mem) NULL)
2433 ReleaseOpenCLMemObject(imageBuffer);
2434 if (grayscaleKernel != (cl_kernel) NULL)
2435 ReleaseOpenCLKernel(grayscaleKernel);
2436 if (queue != (cl_command_queue) NULL)
2437 ReleaseOpenCLCommandQueue(device,queue);
2438 if (device != (MagickCLDevice) NULL)
2439 ReleaseOpenCLDevice(device);
2441 return(outputReady);
2444MagickPrivate MagickBooleanType AccelerateGrayscaleImage(
Image* image,
2453 assert(image != NULL);
2455 if (IsEventLogging() != MagickFalse)
2456 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2458 if ((checkAccelerateCondition(image) == MagickFalse) ||
2459 (checkPixelIntensity(image,method) == MagickFalse))
2460 return(MagickFalse);
2462 if (image->number_channels < 3)
2463 return(MagickFalse);
2465 if ((GetPixelRedTraits(image) == UndefinedPixelTrait) ||
2466 (GetPixelGreenTraits(image) == UndefinedPixelTrait) ||
2467 (GetPixelBlueTraits(image) == UndefinedPixelTrait))
2468 return(MagickFalse);
2470 clEnv=getOpenCLEnvironment(exception);
2471 if (clEnv == (MagickCLEnv) NULL)
2472 return(MagickFalse);
2474 status=ComputeGrayscaleImage(image,clEnv,method,exception);
2490static Image *ComputeLocalContrastImage(
const Image *image,MagickCLEnv clEnv,
2491 const double radius,
const double strength,
ExceptionInfo *exception)
2494 *filteredImage_view,
2512 filteredImageBuffer,
2548 filteredImage_view=NULL;
2550 filteredImageBuffer=NULL;
2551 tempImageBuffer=NULL;
2552 imageKernelBuffer=NULL;
2554 blurColumnKernel=NULL;
2555 outputReady=MagickFalse;
2557 device=RequestOpenCLDevice(clEnv);
2558 if (device == (MagickCLDevice) NULL)
2560 queue=AcquireOpenCLCommandQueue(device);
2561 if (queue == (cl_command_queue) NULL)
2566 image_view=AcquireAuthenticCacheView(image,exception);
2567 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
2568 if (inputPixels == (
const void *) NULL)
2570 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
2577 if (ALIGNED(inputPixels,CLPixelPacket))
2579 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
2583 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
2586 length = image->columns * image->rows;
2587 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2588 if (clStatus != CL_SUCCESS)
2590 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2597 filteredImage = CloneImage(image,0,0,MagickTrue,exception);
2598 assert(filteredImage != NULL);
2599 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
2601 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"CloneImage failed.",
".");
2604 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
2605 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
2606 if (filteredPixels == (
void *) NULL)
2608 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
2612 if (ALIGNED(filteredPixels,CLPixelPacket))
2614 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
2615 hostPtr = filteredPixels;
2619 mem_flags = CL_MEM_WRITE_ONLY;
2624 length = image->columns * image->rows;
2625 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
2626 if (clStatus != CL_SUCCESS)
2628 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2636 length = image->columns * image->rows;
2637 tempImageBuffer = clEnv->library->clCreateBuffer(device->context, CL_MEM_READ_WRITE, length *
sizeof(
float), NULL, &clStatus);
2638 if (clStatus != CL_SUCCESS)
2640 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2647 blurRowKernel = AcquireOpenCLKernel(device,
"LocalContrastBlurRow");
2648 if (blurRowKernel == NULL)
2650 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2654 blurColumnKernel = AcquireOpenCLKernel(device,
"LocalContrastBlurApplyColumn");
2655 if (blurColumnKernel == NULL)
2657 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2663 imageColumns = (
unsigned int) image->columns;
2664 imageRows = (
unsigned int) image->rows;
2665 iRadius = (cl_int) (image->rows > image->columns ? image->rows : image->columns) * 0.002f * fabs(radius);
2667 passes = (((1.0f * imageRows) * imageColumns * iRadius) + 3999999999) / 4000000000.0f;
2668 passes = (passes < 1) ? 1: passes;
2672 clStatus=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2673 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
2674 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
2675 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_int),(
void *)&iRadius);
2676 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(
unsigned int),(
void *)&imageColumns);
2677 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(
unsigned int),(
void *)&imageRows);
2679 if (clStatus != CL_SUCCESS)
2681 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2689 for (x = 0; x < passes; ++x) {
2695 gsize[1] = (image->rows + passes - 1) / passes;
2699 goffset[1] = x * gsize[1];
2701 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, blurRowKernel, 2, goffset, gsize, wsize, 0, NULL, &event);
2702 if (clStatus != CL_SUCCESS)
2704 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2707 clEnv->library->clFlush(queue);
2708 RecordProfileData(device,blurRowKernel,event);
2713 cl_float FStrength = strength;
2715 clStatus=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2716 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
2717 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
2718 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&iRadius);
2719 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_float),(
void *)&FStrength);
2720 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&imageColumns);
2721 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&imageRows);
2723 if (clStatus != CL_SUCCESS)
2725 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2733 for (x = 0; x < passes; ++x) {
2738 gsize[0] = ((image->columns + 3) / 4) * 4;
2739 gsize[1] = ((((image->rows + 63) / 64) + (passes + 1)) / passes) * 64;
2743 goffset[1] = x * gsize[1];
2745 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, blurColumnKernel, 2, goffset, gsize, wsize, 0, NULL, &event);
2746 if (clStatus != CL_SUCCESS)
2748 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2751 clEnv->library->clFlush(queue);
2752 RecordProfileData(device,blurColumnKernel,event);
2758 if (ALIGNED(filteredPixels,CLPixelPacket))
2760 length = image->columns * image->rows;
2761 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2765 length = image->columns * image->rows;
2766 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
2768 if (clStatus != CL_SUCCESS)
2770 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
2774 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
2778 image_view=DestroyCacheView(image_view);
2779 if (filteredImage_view != NULL)
2780 filteredImage_view=DestroyCacheView(filteredImage_view);
2782 if (imageBuffer!=NULL)
2783 clEnv->library->clReleaseMemObject(imageBuffer);
2784 if (filteredImageBuffer!=NULL)
2785 clEnv->library->clReleaseMemObject(filteredImageBuffer);
2786 if (tempImageBuffer!=NULL)
2787 clEnv->library->clReleaseMemObject(tempImageBuffer);
2788 if (imageKernelBuffer!=NULL)
2789 clEnv->library->clReleaseMemObject(imageKernelBuffer);
2790 if (blurRowKernel!=NULL)
2791 ReleaseOpenCLKernel(blurRowKernel);
2792 if (blurColumnKernel!=NULL)
2793 ReleaseOpenCLKernel(blurColumnKernel);
2795 ReleaseOpenCLCommandQueue(device, queue);
2797 ReleaseOpenCLDevice(device);
2798 if (outputReady == MagickFalse)
2800 if (filteredImage != NULL)
2802 DestroyImage(filteredImage);
2803 filteredImage = NULL;
2807 return(filteredImage);
2810MagickPrivate
Image *AccelerateLocalContrastImage(
const Image *image,
2811 const double radius,
const double strength,
ExceptionInfo *exception)
2819 assert(image != NULL);
2822 if (checkAccelerateConditionRGBA(image) == MagickFalse)
2823 return((
Image *) NULL);
2825 clEnv=getOpenCLEnvironment(exception);
2826 if (clEnv == (MagickCLEnv) NULL)
2827 return((
Image *) NULL);
2829 filteredImage=ComputeLocalContrastImage(image,clEnv,radius,strength,
2831 return(filteredImage);
2846static MagickBooleanType ComputeModulateImage(
Image *image,MagickCLEnv clEnv,
2847 const double percent_brightness,
const double percent_hue,
2848 const double percent_saturation,
const ColorspaceType colorspace,
2893 assert(image != (
Image *) NULL);
2894 assert(image->signature == MagickCoreSignature);
2895 if (IsEventLogging() != MagickFalse)
2896 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2902 modulateKernel=NULL;
2903 outputReady=MagickFalse;
2908 device=RequestOpenCLDevice(clEnv);
2909 if (device == (MagickCLDevice) NULL)
2911 queue=AcquireOpenCLCommandQueue(device);
2912 if (queue == (cl_command_queue) NULL)
2919 image_view=AcquireAuthenticCacheView(image,exception);
2920 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
2921 if (inputPixels == (
void *) NULL)
2923 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
2931 if (ALIGNED(inputPixels,CLPixelPacket))
2933 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
2937 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2940 length = image->columns * image->rows;
2941 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2942 if (clStatus != CL_SUCCESS)
2944 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2948 modulateKernel = AcquireOpenCLKernel(device,
"Modulate");
2949 if (modulateKernel == NULL)
2951 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2955 bright=percent_brightness;
2957 saturation=percent_saturation;
2961 clStatus=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2962 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&bright);
2963 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&hue);
2964 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&saturation);
2965 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&color);
2966 if (clStatus != CL_SUCCESS)
2968 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2973 size_t global_work_size[2];
2974 global_work_size[0] = image->columns;
2975 global_work_size[1] = image->rows;
2977 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, modulateKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
2978 if (clStatus != CL_SUCCESS)
2980 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2983 RecordProfileData(device,modulateKernel,event);
2986 if (ALIGNED(inputPixels,CLPixelPacket))
2988 length = image->columns * image->rows;
2989 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2993 length = image->columns * image->rows;
2994 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
2996 if (clStatus != CL_SUCCESS)
2998 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
3002 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
3006 image_view=DestroyCacheView(image_view);
3008 if (imageBuffer!=NULL)
3009 clEnv->library->clReleaseMemObject(imageBuffer);
3010 if (modulateKernel!=NULL)
3011 ReleaseOpenCLKernel(modulateKernel);
3013 ReleaseOpenCLCommandQueue(device,queue);
3015 ReleaseOpenCLDevice(device);
3021MagickPrivate MagickBooleanType AccelerateModulateImage(
Image *image,
3022 const double percent_brightness,
const double percent_hue,
3023 const double percent_saturation,
const ColorspaceType colorspace,
3032 assert(image != NULL);
3034 if (IsEventLogging() != MagickFalse)
3035 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
3037 if (checkAccelerateConditionRGBA(image) == MagickFalse)
3038 return(MagickFalse);
3040 if ((colorspace != HSLColorspace) && (colorspace != UndefinedColorspace))
3041 return(MagickFalse);
3043 clEnv=getOpenCLEnvironment(exception);
3044 if (clEnv == (MagickCLEnv) NULL)
3045 return(MagickFalse);
3047 status=ComputeModulateImage(image,clEnv,percent_brightness,percent_hue,
3048 percent_saturation,colorspace,exception);
3064static Image* ComputeMotionBlurImage(
const Image *image,MagickCLEnv clEnv,
3065 const double *kernel,
const size_t width,
const OffsetInfo *offset,
3069 *filteredImage_view,
3079 channel_mask=get32BitChannelValue(image->channel_mask),
3089 filteredImageBuffer,
3122 global_work_size[2],
3135 assert(image != (
Image *) NULL);
3136 assert(image->signature == MagickCoreSignature);
3137 if (IsEventLogging() != MagickFalse)
3138 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
3143 filteredImage_view=NULL;
3145 filteredImageBuffer=NULL;
3146 imageKernelBuffer=NULL;
3147 motionBlurKernel=NULL;
3148 outputReady=MagickFalse;
3150 device=RequestOpenCLDevice(clEnv);
3151 if (device == (MagickCLDevice) NULL)
3156 image_view=AcquireAuthenticCacheView(image,exception);
3157 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,
3158 image->rows,exception);
3159 if (inputPixels == (
const void *) NULL)
3161 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
3162 "UnableToReadPixelCache.",
"`%s'",image->filename);
3171 if (ALIGNED(inputPixels,CLPixelPacket))
3173 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
3177 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
3182 length = image->columns * image->rows;
3183 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags,
3184 length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
3185 if (clStatus != CL_SUCCESS)
3187 (void) ThrowMagickException(exception, GetMagickModule(),
3188 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3193 filteredImage = CloneImage(image,image->columns,image->rows,
3194 MagickTrue,exception);
3195 assert(filteredImage != NULL);
3196 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
3198 (void) ThrowMagickException(exception, GetMagickModule(),
3199 ResourceLimitError,
"CloneImage failed.",
".");
3202 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
3203 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
3204 if (filteredPixels == (
void *) NULL)
3206 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
3207 "UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
3211 if (ALIGNED(filteredPixels,CLPixelPacket))
3213 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
3214 hostPtr = filteredPixels;
3218 mem_flags = CL_MEM_WRITE_ONLY;
3224 length = image->columns * image->rows;
3225 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags,
3226 length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
3227 if (clStatus != CL_SUCCESS)
3229 (void) ThrowMagickException(exception, GetMagickModule(),
3230 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3235 imageKernelBuffer = clEnv->library->clCreateBuffer(device->context,
3236 CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, width *
sizeof(
float), NULL,
3238 if (clStatus != CL_SUCCESS)
3240 (void) ThrowMagickException(exception, GetMagickModule(),
3241 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3245 queue=AcquireOpenCLCommandQueue(device);
3246 if (queue == (cl_command_queue) NULL)
3248 kernelBufferPtr = (
float*)clEnv->library->clEnqueueMapBuffer(queue, imageKernelBuffer,
3249 CL_TRUE, CL_MAP_WRITE, 0, width *
sizeof(
float), 0, NULL, NULL, &clStatus);
3250 if (clStatus != CL_SUCCESS)
3252 (void) ThrowMagickException(exception, GetMagickModule(),
3253 ResourceLimitError,
"clEnv->library->clEnqueueMapBuffer failed.",
".");
3256 for (i = 0; i < width; i++)
3258 kernelBufferPtr[i] = (float) kernel[i];
3260 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, imageKernelBuffer, kernelBufferPtr,
3262 if (clStatus != CL_SUCCESS)
3264 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3265 "clEnv->library->clEnqueueUnmapMemObject failed.",
".");
3269 offsetBuffer = clEnv->library->clCreateBuffer(device->context,
3270 CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, width *
sizeof(cl_int2), NULL,
3272 if (clStatus != CL_SUCCESS)
3274 (void) ThrowMagickException(exception, GetMagickModule(),
3275 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3279 offsetBufferPtr = (
int*)clEnv->library->clEnqueueMapBuffer(queue, offsetBuffer, CL_TRUE,
3280 CL_MAP_WRITE, 0, width *
sizeof(cl_int2), 0, NULL, NULL, &clStatus);
3281 if (clStatus != CL_SUCCESS)
3283 (void) ThrowMagickException(exception, GetMagickModule(),
3284 ResourceLimitError,
"clEnv->library->clEnqueueMapBuffer failed.",
".");
3287 for (i = 0; i < width; i++)
3289 offsetBufferPtr[2*i] = (int)offset[i].x;
3290 offsetBufferPtr[2*i+1] = (int)offset[i].y;
3292 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, offsetBuffer, offsetBufferPtr, 0,
3294 if (clStatus != CL_SUCCESS)
3296 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3297 "clEnv->library->clEnqueueUnmapMemObject failed.",
".");
3305 motionBlurKernel = AcquireOpenCLKernel(device,
"MotionBlur");
3306 if (motionBlurKernel == NULL)
3308 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3309 "AcquireOpenCLKernel failed.",
".");
3317 clStatus=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3318 (
void *)&imageBuffer);
3319 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3320 (
void *)&filteredImageBuffer);
3321 imageWidth = (
unsigned int) image->columns;
3322 imageHeight = (
unsigned int) image->rows;
3323 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3325 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3327 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3328 (
void *)&imageKernelBuffer);
3329 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3331 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3332 (
void *)&offsetBuffer);
3334 GetPixelInfo(image,&bias);
3335 biasPixel.s[0] = bias.red;
3336 biasPixel.s[1] = bias.green;
3337 biasPixel.s[2] = bias.blue;
3338 biasPixel.s[3] = bias.alpha;
3339 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_float4), &biasPixel);
3341 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_int),&channel_mask);
3342 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
3343 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int), &matte);
3344 if (clStatus != CL_SUCCESS)
3346 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3347 "clEnv->library->clSetKernelArg failed.",
".");
3354 local_work_size[0] = 16;
3355 local_work_size[1] = 16;
3356 global_work_size[0] = (size_t)padGlobalWorkgroupSizeToLocalWorkgroupSize(
3357 (
unsigned int) image->columns,(
unsigned int) local_work_size[0]);
3358 global_work_size[1] = (size_t)padGlobalWorkgroupSizeToLocalWorkgroupSize(
3359 (
unsigned int) image->rows,(
unsigned int) local_work_size[1]);
3360 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, motionBlurKernel, 2, NULL,
3361 global_work_size, local_work_size, 0, NULL, &event);
3363 if (clStatus != CL_SUCCESS)
3365 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3366 "clEnv->library->clEnqueueNDRangeKernel failed.",
".");
3369 RecordProfileData(device,motionBlurKernel,event);
3371 if (ALIGNED(filteredPixels,CLPixelPacket))
3373 length = image->columns * image->rows;
3374 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE,
3375 CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL,
3380 length = image->columns * image->rows;
3381 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0,
3382 length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
3384 if (clStatus != CL_SUCCESS)
3386 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3387 "Reading output image from CL buffer failed.",
".");
3390 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
3394 image_view=DestroyCacheView(image_view);
3395 if (filteredImage_view != NULL)
3396 filteredImage_view=DestroyCacheView(filteredImage_view);
3398 if (filteredImageBuffer!=NULL)
3399 clEnv->library->clReleaseMemObject(filteredImageBuffer);
3400 if (imageBuffer!=NULL)
3401 clEnv->library->clReleaseMemObject(imageBuffer);
3402 if (imageKernelBuffer!=NULL)
3403 clEnv->library->clReleaseMemObject(imageKernelBuffer);
3404 if (motionBlurKernel!=NULL)
3405 ReleaseOpenCLKernel(motionBlurKernel);
3407 ReleaseOpenCLCommandQueue(device,queue);
3409 ReleaseOpenCLDevice(device);
3410 if (outputReady == MagickFalse && filteredImage != NULL)
3411 filteredImage=DestroyImage(filteredImage);
3413 return(filteredImage);
3416MagickPrivate
Image *AccelerateMotionBlurImage(
const Image *image,
3417 const double* kernel,
const size_t width,
const OffsetInfo *offset,
3426 assert(image != NULL);
3427 assert(kernel != (
double *) NULL);
3431 if (checkAccelerateConditionRGBA(image) == MagickFalse)
3432 return((
Image *) NULL);
3434 clEnv=getOpenCLEnvironment(exception);
3435 if (clEnv == (MagickCLEnv) NULL)
3436 return((
Image *) NULL);
3438 filteredImage=ComputeMotionBlurImage(image,clEnv,kernel,width,offset,
3440 return(filteredImage);
3455static MagickBooleanType resizeHorizontalFilter(MagickCLDevice device,
3456 cl_command_queue queue,
const Image *image,
Image *filteredImage,
3457 cl_mem imageBuffer,cl_uint number_channels,cl_uint columns,cl_uint rows,
3458 cl_mem resizedImageBuffer,cl_uint resizedColumns,cl_uint resizedRows,
3459 const ResizeFilter *resizeFilter,cl_mem resizeFilterCubicCoefficients,
3469 workgroupSize = 256;
3473 resizeFilterSupport,
3474 resizeFilterWindowSupport,
3488 gammaAccumulatorLocalMemorySize,
3491 imageCacheLocalMemorySize,
3492 pixelAccumulatorLocalMemorySize,
3494 totalLocalMemorySize,
3495 weightAccumulatorLocalMemorySize;
3501 horizontalKernel=NULL;
3502 outputReady=MagickFalse;
3507 scale=MAGICK_MAX(1.0/xFactor+MagickEpsilon,1.0);
3508 support=scale*GetResizeFilterSupport(resizeFilter);
3515 support=(float) 0.5;
3518 scale=PerceptibleReciprocal(scale);
3520 if (resizedColumns < workgroupSize)
3523 pixelPerWorkgroup=32;
3527 chunkSize=workgroupSize;
3528 pixelPerWorkgroup=workgroupSize;
3531DisableMSCWarning(4127)
3536 numCachedPixels=(int) ceil((pixelPerWorkgroup-1)/xFactor+2*support);
3537 imageCacheLocalMemorySize=numCachedPixels*
sizeof(CLQuantum)*
3539 totalLocalMemorySize=imageCacheLocalMemorySize;
3542 pixelAccumulatorLocalMemorySize=chunkSize*
sizeof(cl_float4);
3543 totalLocalMemorySize+=pixelAccumulatorLocalMemorySize;
3546 weightAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3547 totalLocalMemorySize+=weightAccumulatorLocalMemorySize;
3550 if ((number_channels == 4) || (number_channels == 2))
3551 gammaAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3553 gammaAccumulatorLocalMemorySize=
sizeof(float);
3554 totalLocalMemorySize+=gammaAccumulatorLocalMemorySize;
3556 if (totalLocalMemorySize <= device->local_memory_size)
3560 pixelPerWorkgroup=pixelPerWorkgroup/2;
3561 chunkSize=chunkSize/2;
3562 if ((pixelPerWorkgroup == 0) || (chunkSize == 0))
3570 resizeFilterType=(int)GetResizeFilterWeightingType(resizeFilter);
3571 resizeWindowType=(int)GetResizeFilterWindowWeightingType(resizeFilter);
3573 horizontalKernel=AcquireOpenCLKernel(device,
"ResizeHorizontalFilter");
3574 if (horizontalKernel == (cl_kernel) NULL)
3576 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3577 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
3581 resizeFilterScale=(float) GetResizeFilterScale(resizeFilter);
3582 resizeFilterSupport=(float) GetResizeFilterSupport(resizeFilter);
3583 resizeFilterWindowSupport=(float) GetResizeFilterWindowSupport(resizeFilter);
3584 resizeFilterBlur=(float) GetResizeFilterBlur(resizeFilter);
3587 status =SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&imageBuffer);
3588 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&number_channels);
3589 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&columns);
3590 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&rows);
3591 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&resizedImageBuffer);
3592 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&resizedColumns);
3593 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&resizedRows);
3594 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&xFactor);
3595 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),(
void*)&resizeFilterType);
3596 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),(
void*)&resizeWindowType);
3597 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&resizeFilterCubicCoefficients);
3598 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterScale);
3599 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterSupport);
3600 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterWindowSupport);
3601 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterBlur);
3602 status|=SetOpenCLKernelArg(horizontalKernel,i++,imageCacheLocalMemorySize,NULL);
3603 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),&numCachedPixels);
3604 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
unsigned int),&pixelPerWorkgroup);
3605 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
unsigned int),&chunkSize);
3606 status|=SetOpenCLKernelArg(horizontalKernel,i++,pixelAccumulatorLocalMemorySize,NULL);
3607 status|=SetOpenCLKernelArg(horizontalKernel,i++,weightAccumulatorLocalMemorySize,NULL);
3608 status|=SetOpenCLKernelArg(horizontalKernel,i++,gammaAccumulatorLocalMemorySize,NULL);
3610 if (status != CL_SUCCESS)
3612 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3613 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
3617 gsize[0]=(resizedColumns+pixelPerWorkgroup-1)/pixelPerWorkgroup*
3619 gsize[1]=resizedRows;
3620 lsize[0]=workgroupSize;
3622 outputReady=EnqueueOpenCLKernel(queue,horizontalKernel,2,
3623 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
3628 if (horizontalKernel != (cl_kernel) NULL)
3629 ReleaseOpenCLKernel(horizontalKernel);
3631 return(outputReady);
3634static MagickBooleanType resizeVerticalFilter(MagickCLDevice device,
3635 cl_command_queue queue,
const Image *image,
Image * filteredImage,
3636 cl_mem imageBuffer,cl_uint number_channels,cl_uint columns,cl_uint rows,
3637 cl_mem resizedImageBuffer,cl_uint resizedColumns,cl_uint resizedRows,
3638 const ResizeFilter *resizeFilter,cl_mem resizeFilterCubicCoefficients,
3648 workgroupSize = 256;
3652 resizeFilterSupport,
3653 resizeFilterWindowSupport,
3667 gammaAccumulatorLocalMemorySize,
3670 imageCacheLocalMemorySize,
3671 pixelAccumulatorLocalMemorySize,
3673 totalLocalMemorySize,
3674 weightAccumulatorLocalMemorySize;
3680 verticalKernel=NULL;
3681 outputReady=MagickFalse;
3686 scale=MAGICK_MAX(1.0/yFactor+MagickEpsilon,1.0);
3687 support=scale*GetResizeFilterSupport(resizeFilter);
3694 support=(float) 0.5;
3697 scale=PerceptibleReciprocal(scale);
3699 if (resizedRows < workgroupSize)
3702 pixelPerWorkgroup=32;
3706 chunkSize=workgroupSize;
3707 pixelPerWorkgroup=workgroupSize;
3710DisableMSCWarning(4127)
3715 numCachedPixels=(int)ceil((pixelPerWorkgroup-1)/yFactor+2*support);
3716 imageCacheLocalMemorySize=numCachedPixels*
sizeof(CLQuantum)*
3718 totalLocalMemorySize=imageCacheLocalMemorySize;
3721 pixelAccumulatorLocalMemorySize=chunkSize*
sizeof(cl_float4);
3722 totalLocalMemorySize+=pixelAccumulatorLocalMemorySize;
3725 weightAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3726 totalLocalMemorySize+=weightAccumulatorLocalMemorySize;
3729 if ((number_channels == 4) || (number_channels == 2))
3730 gammaAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3732 gammaAccumulatorLocalMemorySize=
sizeof(float);
3733 totalLocalMemorySize+=gammaAccumulatorLocalMemorySize;
3735 if (totalLocalMemorySize <= device->local_memory_size)
3739 pixelPerWorkgroup=pixelPerWorkgroup/2;
3740 chunkSize=chunkSize/2;
3741 if ((pixelPerWorkgroup == 0) || (chunkSize == 0))
3749 resizeFilterType=(int)GetResizeFilterWeightingType(resizeFilter);
3750 resizeWindowType=(int)GetResizeFilterWindowWeightingType(resizeFilter);
3752 verticalKernel=AcquireOpenCLKernel(device,
"ResizeVerticalFilter");
3753 if (verticalKernel == (cl_kernel) NULL)
3755 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3756 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
3760 resizeFilterScale=(float) GetResizeFilterScale(resizeFilter);
3761 resizeFilterSupport=(float) GetResizeFilterSupport(resizeFilter);
3762 resizeFilterBlur=(float) GetResizeFilterBlur(resizeFilter);
3763 resizeFilterWindowSupport=(float) GetResizeFilterWindowSupport(resizeFilter);
3766 status =SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&imageBuffer);
3767 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&number_channels);
3768 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&columns);
3769 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&rows);
3770 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&resizedImageBuffer);
3771 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&resizedColumns);
3772 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&resizedRows);
3773 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&yFactor);
3774 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int),(
void*)&resizeFilterType);
3775 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int),(
void*)&resizeWindowType);
3776 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&resizeFilterCubicCoefficients);
3777 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterScale);
3778 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterSupport);
3779 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterWindowSupport);
3780 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterBlur);
3781 status|=SetOpenCLKernelArg(verticalKernel,i++,imageCacheLocalMemorySize, NULL);
3782 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int), &numCachedPixels);
3783 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
unsigned int), &pixelPerWorkgroup);
3784 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
unsigned int), &chunkSize);
3785 status|=SetOpenCLKernelArg(verticalKernel,i++,pixelAccumulatorLocalMemorySize, NULL);
3786 status|=SetOpenCLKernelArg(verticalKernel,i++,weightAccumulatorLocalMemorySize, NULL);
3787 status|=SetOpenCLKernelArg(verticalKernel,i++,gammaAccumulatorLocalMemorySize, NULL);
3789 if (status != CL_SUCCESS)
3791 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3792 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
3796 gsize[0]=resizedColumns;
3797 gsize[1]=(resizedRows+pixelPerWorkgroup-1)/pixelPerWorkgroup*
3800 lsize[1]=workgroupSize;
3801 outputReady=EnqueueOpenCLKernel(queue,verticalKernel,2,(
const size_t *) NULL,
3802 gsize,lsize,image,filteredImage,MagickFalse,exception);
3806 if (verticalKernel != (cl_kernel) NULL)
3807 ReleaseOpenCLKernel(verticalKernel);
3809 return(outputReady);
3812static Image *ComputeResizeImage(
const Image* image,MagickCLEnv clEnv,
3813 const size_t resizedColumns,
const size_t resizedRows,
3820 cubicCoefficientsBuffer,
3821 filteredImageBuffer,
3829 *resizeFilterCoefficient;
3832 coefficientBuffer[7],
3854 filteredImageBuffer=NULL;
3855 tempImageBuffer=NULL;
3856 cubicCoefficientsBuffer=NULL;
3857 outputReady=MagickFalse;
3859 device=RequestOpenCLDevice(clEnv);
3860 if (device == (MagickCLDevice) NULL)
3862 queue=AcquireOpenCLCommandQueue(device);
3863 if (queue == (cl_command_queue) NULL)
3865 filteredImage=CloneImage(image,resizedColumns,resizedRows,MagickTrue,
3867 if (filteredImage == (
Image *) NULL)
3869 if (filteredImage->number_channels != image->number_channels)
3871 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
3872 if (imageBuffer == (cl_mem) NULL)
3874 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
3875 if (filteredImageBuffer == (cl_mem) NULL)
3878 resizeFilterCoefficient=GetResizeFilterCoefficient(resizeFilter);
3879 for (i = 0; i < 7; i++)
3880 coefficientBuffer[i]=(
float) resizeFilterCoefficient[i];
3881 cubicCoefficientsBuffer=CreateOpenCLBuffer(device,CL_MEM_COPY_HOST_PTR |
3882 CL_MEM_READ_ONLY,
sizeof(coefficientBuffer),&coefficientBuffer);
3883 if (cubicCoefficientsBuffer == (cl_mem) NULL)
3885 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3886 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3890 number_channels=(cl_uint) image->number_channels;
3891 xFactor=(float) resizedColumns/(
float) image->columns;
3892 yFactor=(float) resizedRows/(
float) image->rows;
3893 if (xFactor > yFactor)
3895 length=resizedColumns*image->rows*number_channels;
3896 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
3897 sizeof(CLQuantum),(
void *) NULL);
3898 if (tempImageBuffer == (cl_mem) NULL)
3900 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3901 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3905 outputReady=resizeHorizontalFilter(device,queue,image,filteredImage,
3906 imageBuffer,number_channels,(cl_uint) image->columns,
3907 (cl_uint) image->rows,tempImageBuffer,(cl_uint) resizedColumns,
3908 (cl_uint) image->rows,resizeFilter,cubicCoefficientsBuffer,xFactor,
3910 if (outputReady == MagickFalse)
3913 outputReady=resizeVerticalFilter(device,queue,image,filteredImage,
3914 tempImageBuffer,number_channels,(cl_uint) resizedColumns,
3915 (cl_uint) image->rows,filteredImageBuffer,(cl_uint) resizedColumns,
3916 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,yFactor,
3918 if (outputReady == MagickFalse)
3923 length=image->columns*resizedRows*number_channels;
3924 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
3925 sizeof(CLQuantum),(
void *) NULL);
3926 if (tempImageBuffer == (cl_mem) NULL)
3928 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3929 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3933 outputReady=resizeVerticalFilter(device,queue,image,filteredImage,
3934 imageBuffer,number_channels,(cl_uint) image->columns,
3935 (cl_int) image->rows,tempImageBuffer,(cl_uint) image->columns,
3936 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,yFactor,
3938 if (outputReady == MagickFalse)
3941 outputReady=resizeHorizontalFilter(device,queue,image,filteredImage,
3942 tempImageBuffer,number_channels,(cl_uint) image->columns,
3943 (cl_uint) resizedRows,filteredImageBuffer,(cl_uint) resizedColumns,
3944 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,xFactor,
3946 if (outputReady == MagickFalse)
3952 if (imageBuffer != (cl_mem) NULL)
3953 ReleaseOpenCLMemObject(imageBuffer);
3954 if (filteredImageBuffer != (cl_mem) NULL)
3955 ReleaseOpenCLMemObject(filteredImageBuffer);
3956 if (tempImageBuffer != (cl_mem) NULL)
3957 ReleaseOpenCLMemObject(tempImageBuffer);
3958 if (cubicCoefficientsBuffer != (cl_mem) NULL)
3959 ReleaseOpenCLMemObject(cubicCoefficientsBuffer);
3960 if (queue != (cl_command_queue) NULL)
3961 ReleaseOpenCLCommandQueue(device,queue);
3962 if (device != (MagickCLDevice) NULL)
3963 ReleaseOpenCLDevice(device);
3964 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
3965 filteredImage=DestroyImage(filteredImage);
3967 return(filteredImage);
3970static MagickBooleanType gpuSupportedResizeWeighting(
3971 ResizeWeightingFunctionType f)
3978 if (supportedResizeWeighting[i] == LastWeightingFunction)
3980 if (supportedResizeWeighting[i] == f)
3983 return(MagickFalse);
3986MagickPrivate
Image *AccelerateResizeImage(
const Image *image,
3987 const size_t resizedColumns,
const size_t resizedRows,
3996 assert(image != NULL);
3999 if (checkAccelerateCondition(image) == MagickFalse)
4000 return((
Image *) NULL);
4002 if ((gpuSupportedResizeWeighting(GetResizeFilterWeightingType(
4003 resizeFilter)) == MagickFalse) ||
4004 (gpuSupportedResizeWeighting(GetResizeFilterWindowWeightingType(
4005 resizeFilter)) == MagickFalse))
4006 return((
Image *) NULL);
4008 clEnv=getOpenCLEnvironment(exception);
4009 if (clEnv == (MagickCLEnv) NULL)
4010 return((
Image *) NULL);
4012 filteredImage=ComputeResizeImage(image,clEnv,resizedColumns,resizedRows,
4013 resizeFilter,exception);
4014 return(filteredImage);
4029static Image* ComputeRotationalBlurImage(
const Image *image,MagickCLEnv clEnv,
4039 channel_mask=get32BitChannelValue(image->channel_mask),
4044 filteredImageBuffer,
4049 rotationalBlurKernel;
4075 assert(image != (
Image *) NULL);
4076 assert(image->signature == MagickCoreSignature);
4077 if (IsEventLogging() != MagickFalse)
4078 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
4083 filteredImageBuffer=NULL;
4084 sinThetaBuffer=NULL;
4085 cosThetaBuffer=NULL;
4086 rotationalBlurKernel=NULL;
4087 outputReady=MagickFalse;
4089 device=RequestOpenCLDevice(clEnv);
4090 if (device == (MagickCLDevice) NULL)
4092 queue=AcquireOpenCLCommandQueue(device);
4093 if (queue == (cl_command_queue) NULL)
4095 filteredImage=cloneImage(image,exception);
4096 if (filteredImage == (
Image *) NULL)
4098 if (filteredImage->number_channels != image->number_channels)
4100 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4101 if (imageBuffer == (cl_mem) NULL)
4103 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4104 if (filteredImageBuffer == (cl_mem) NULL)
4107 blurCenter.x=(float) (image->columns-1)/2.0;
4108 blurCenter.y=(float) (image->rows-1)/2.0;
4109 blurRadius=hypot(blurCenter.x,blurCenter.y);
4110 cossin_theta_size=(
unsigned int) fabs(4.0*DegreesToRadians(angle)*sqrt(
4111 (
double) blurRadius)+2UL);
4113 cosThetaPtr=(
float *) AcquireQuantumMemory(cossin_theta_size,
sizeof(
float));
4114 if (cosThetaPtr == (
float *) NULL)
4116 sinThetaPtr=(
float *) AcquireQuantumMemory(cossin_theta_size,
sizeof(
float));
4117 if (sinThetaPtr == (
float *) NULL)
4119 cosThetaPtr=(
float *) RelinquishMagickMemory(cosThetaPtr);
4123 theta=DegreesToRadians(angle)/(double) (cossin_theta_size-1);
4124 offset=theta*(float) (cossin_theta_size-1)/2.0;
4125 for (i=0; i < (ssize_t) cossin_theta_size; i++)
4127 cosThetaPtr[i]=(float)cos((
double) (theta*i-offset));
4128 sinThetaPtr[i]=(float)sin((
double) (theta*i-offset));
4131 sinThetaBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
4132 CL_MEM_COPY_HOST_PTR,cossin_theta_size*
sizeof(
float),sinThetaPtr);
4133 sinThetaPtr=(
float *) RelinquishMagickMemory(sinThetaPtr);
4134 cosThetaBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
4135 CL_MEM_COPY_HOST_PTR,cossin_theta_size*
sizeof(
float),cosThetaPtr);
4136 cosThetaPtr=(
float *) RelinquishMagickMemory(cosThetaPtr);
4137 if ((sinThetaBuffer == (cl_mem) NULL) || (cosThetaBuffer == (cl_mem) NULL))
4139 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4140 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
4144 rotationalBlurKernel=AcquireOpenCLKernel(device,
"RotationalBlur");
4145 if (rotationalBlurKernel == (cl_kernel) NULL)
4147 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4148 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4152 number_channels=(cl_uint) image->number_channels;
4155 status =SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4156 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_uint),&number_channels);
4157 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_int),&channel_mask);
4158 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_float2), &blurCenter);
4159 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&cosThetaBuffer);
4160 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&sinThetaBuffer);
4161 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_uint), &cossin_theta_size);
4162 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4163 if (status != CL_SUCCESS)
4165 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4166 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4170 gsize[0]=image->columns;
4171 gsize[1]=image->rows;
4172 outputReady=EnqueueOpenCLKernel(queue,rotationalBlurKernel,2,
4173 (
const size_t *) NULL,gsize,(
const size_t *) NULL,image,filteredImage,
4174 MagickFalse,exception);
4178 if (imageBuffer != (cl_mem) NULL)
4179 ReleaseOpenCLMemObject(imageBuffer);
4180 if (filteredImageBuffer != (cl_mem) NULL)
4181 ReleaseOpenCLMemObject(filteredImageBuffer);
4182 if (sinThetaBuffer != (cl_mem) NULL)
4183 ReleaseOpenCLMemObject(sinThetaBuffer);
4184 if (cosThetaBuffer != (cl_mem) NULL)
4185 ReleaseOpenCLMemObject(cosThetaBuffer);
4186 if (rotationalBlurKernel != (cl_kernel) NULL)
4187 ReleaseOpenCLKernel(rotationalBlurKernel);
4188 if (queue != (cl_command_queue) NULL)
4189 ReleaseOpenCLCommandQueue(device,queue);
4190 if (device != (MagickCLDevice) NULL)
4191 ReleaseOpenCLDevice(device);
4192 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
4193 filteredImage=DestroyImage(filteredImage);
4195 return(filteredImage);
4198MagickPrivate
Image* AccelerateRotationalBlurImage(
const Image *image,
4207 assert(image != NULL);
4209 if (IsEventLogging() != MagickFalse)
4210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
4212 if (checkAccelerateCondition(image) == MagickFalse)
4213 return((
Image *) NULL);
4215 clEnv=getOpenCLEnvironment(exception);
4216 if (clEnv == (MagickCLEnv) NULL)
4217 return((
Image *) NULL);
4219 filteredImage=ComputeRotationalBlurImage(image,clEnv,angle,exception);
4220 return filteredImage;
4235static Image *ComputeUnsharpMaskImage(
const Image *image,MagickCLEnv clEnv,
4236 const double radius,
const double sigma,
const double gain,
4243 channel_mask=get32BitChannelValue(image->channel_mask),
4248 unsharpMaskBlurColumnKernel;
4251 filteredImageBuffer,
4289 filteredImageBuffer=NULL;
4290 tempImageBuffer=NULL;
4291 imageKernelBuffer=NULL;
4293 unsharpMaskBlurColumnKernel=NULL;
4294 outputReady=MagickFalse;
4296 device=RequestOpenCLDevice(clEnv);
4297 if (device == (MagickCLDevice) NULL)
4299 queue=AcquireOpenCLCommandQueue(device);
4300 if (queue == (cl_command_queue) NULL)
4302 filteredImage=cloneImage(image,exception);
4303 if (filteredImage == (
Image *) NULL)
4305 if (filteredImage->number_channels != image->number_channels)
4307 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4308 if (imageBuffer == (cl_mem) NULL)
4310 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4311 if (filteredImageBuffer == (cl_mem) NULL)
4314 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
4317 length=image->columns*image->rows;
4318 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
4319 sizeof(cl_float4),NULL);
4320 if (tempImageBuffer == (cl_mem) NULL)
4322 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4323 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
4327 blurRowKernel=AcquireOpenCLKernel(device,
"BlurRow");
4328 if (blurRowKernel == (cl_kernel) NULL)
4330 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4331 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4335 unsharpMaskBlurColumnKernel=AcquireOpenCLKernel(device,
4336 "UnsharpMaskBlurColumn");
4337 if (unsharpMaskBlurColumnKernel == (cl_kernel) NULL)
4339 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4340 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4344 number_channels=(cl_uint) image->number_channels;
4345 imageColumns=(cl_uint) image->columns;
4346 imageRows=(cl_uint) image->rows;
4351 status =SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4352 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),&number_channels);
4353 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_int),&channel_mask);
4354 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4355 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4356 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4357 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4358 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
4359 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
4360 if (status != CL_SUCCESS)
4362 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4363 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4367 gsize[0]=chunkSize*((image->columns+chunkSize-1)/chunkSize);
4368 gsize[1]=image->rows;
4371 outputReady=EnqueueOpenCLKernel(queue,blurRowKernel,2,
4372 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
4377 fThreshold=(float) threshold;
4380 status =SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4381 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
4382 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),&number_channels);
4383 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_int),&channel_mask);
4384 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4385 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4386 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,(chunkSize+kernelWidth-1)*
sizeof(cl_float4),NULL);
4387 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,kernelWidth*
sizeof(
float),NULL);
4388 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4389 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4390 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(
float),(
void *)&fGain);
4391 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(
float),(
void *)&fThreshold);
4392 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4393 if (status != CL_SUCCESS)
4395 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4396 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4400 gsize[0]=image->columns;
4401 gsize[1]=chunkSize*((image->rows+chunkSize-1)/chunkSize);
4404 outputReady=EnqueueOpenCLKernel(queue,unsharpMaskBlurColumnKernel,2,
4405 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
4410 if (imageBuffer != (cl_mem) NULL)
4411 ReleaseOpenCLMemObject(imageBuffer);
4412 if (filteredImageBuffer != (cl_mem) NULL)
4413 ReleaseOpenCLMemObject(filteredImageBuffer);
4414 if (tempImageBuffer != (cl_mem) NULL)
4415 ReleaseOpenCLMemObject(tempImageBuffer);
4416 if (imageKernelBuffer != (cl_mem) NULL)
4417 ReleaseOpenCLMemObject(imageKernelBuffer);
4418 if (blurRowKernel != (cl_kernel) NULL)
4419 ReleaseOpenCLKernel(blurRowKernel);
4420 if (unsharpMaskBlurColumnKernel != (cl_kernel) NULL)
4421 ReleaseOpenCLKernel(unsharpMaskBlurColumnKernel);
4422 if (queue != (cl_command_queue) NULL)
4423 ReleaseOpenCLCommandQueue(device,queue);
4424 if (device != (MagickCLDevice) NULL)
4425 ReleaseOpenCLDevice(device);
4426 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
4427 filteredImage=DestroyImage(filteredImage);
4429 return(filteredImage);
4432static Image *ComputeUnsharpMaskImageSingle(
const Image *image,
4433 MagickCLEnv clEnv,
const double radius,
const double sigma,
const double gain,
4440 channel_mask=get32BitChannelValue(image->channel_mask),
4447 filteredImageBuffer,
4478 filteredImageBuffer=NULL;
4479 imageKernelBuffer=NULL;
4480 unsharpMaskKernel=NULL;
4481 outputReady=MagickFalse;
4483 device=RequestOpenCLDevice(clEnv);
4484 if (device == (MagickCLDevice) NULL)
4486 queue=AcquireOpenCLCommandQueue(device);
4487 if (queue == (cl_command_queue) NULL)
4489 filteredImage=cloneImage(image,exception);
4490 if (filteredImage == (
Image *) NULL)
4492 if (filteredImage->number_channels != image->number_channels)
4494 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4495 if (imageBuffer == (cl_mem) NULL)
4497 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4498 if (filteredImageBuffer == (cl_mem) NULL)
4501 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
4504 unsharpMaskKernel=AcquireOpenCLKernel(device,
"UnsharpMask");
4505 if (unsharpMaskKernel == NULL)
4507 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4508 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4512 imageColumns=(cl_uint) image->columns;
4513 imageRows=(cl_uint) image->rows;
4514 number_channels=(cl_uint) image->number_channels;
4516 fThreshold=(float) threshold;
4519 status =SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4520 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
4521 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_int),&channel_mask);
4522 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4523 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4524 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4525 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4526 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_float4)*(8 * (32 + kernelWidth)),(
void *) NULL);
4527 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(
float),(
void *)&fGain);
4528 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(
float),(
void *)&fThreshold);
4529 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4530 if (status != CL_SUCCESS)
4532 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4533 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
4537 gsize[0]=((image->columns + 7) / 8)*8;
4538 gsize[1]=((image->rows + 31) / 32)*32;
4541 outputReady=EnqueueOpenCLKernel(queue,unsharpMaskKernel,2,(
const size_t *) NULL,
4542 gsize,lsize,image,filteredImage,MagickFalse,exception);
4546 if (imageBuffer != (cl_mem) NULL)
4547 ReleaseOpenCLMemObject(imageBuffer);
4548 if (filteredImageBuffer != (cl_mem) NULL)
4549 ReleaseOpenCLMemObject(filteredImageBuffer);
4550 if (imageKernelBuffer != (cl_mem) NULL)
4551 ReleaseOpenCLMemObject(imageKernelBuffer);
4552 if (unsharpMaskKernel != (cl_kernel) NULL)
4553 ReleaseOpenCLKernel(unsharpMaskKernel);
4554 if (queue != (cl_command_queue) NULL)
4555 ReleaseOpenCLCommandQueue(device,queue);
4556 if (device != (MagickCLDevice) NULL)
4557 ReleaseOpenCLDevice(device);
4558 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
4559 filteredImage=DestroyImage(filteredImage);
4561 return(filteredImage);
4564MagickPrivate
Image *AccelerateUnsharpMaskImage(
const Image *image,
4565 const double radius,
const double sigma,
const double gain,
4574 assert(image != NULL);
4577 if (checkAccelerateCondition(image) == MagickFalse)
4578 return((
Image *) NULL);
4580 clEnv=getOpenCLEnvironment(exception);
4581 if (clEnv == (MagickCLEnv) NULL)
4582 return((
Image *) NULL);
4585 filteredImage=ComputeUnsharpMaskImageSingle(image,clEnv,radius,sigma,gain,
4586 threshold,exception);
4588 filteredImage=ComputeUnsharpMaskImage(image,clEnv,radius,sigma,gain,
4589 threshold,exception);
4590 return(filteredImage);
4593static Image *ComputeWaveletDenoiseImage(
const Image *image,MagickCLEnv clEnv,
4605 SIZE=TILESIZE-2*PAD;
4617 filteredImageBuffer,
4645 filteredImageBuffer=NULL;
4648 outputReady=MagickFalse;
4650 device=RequestOpenCLDevice(clEnv);
4651 if (device == (MagickCLDevice) NULL)
4654 if (strcmp(
"Intel(R) HD Graphics",device->name) == 0)
4656 queue=AcquireOpenCLCommandQueue(device);
4657 if (queue == (cl_command_queue) NULL)
4659 filteredImage=CloneImage(image,0,0,MagickTrue,
4661 if (filteredImage == (
Image *) NULL)
4663 if (filteredImage->number_channels != image->number_channels)
4665 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4666 if (imageBuffer == (cl_mem) NULL)
4668 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4669 if (filteredImageBuffer == (cl_mem) NULL)
4672 denoiseKernel=AcquireOpenCLKernel(device,
"WaveletDenoise");
4673 if (denoiseKernel == (cl_kernel) NULL)
4675 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4676 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4680 number_channels=(cl_uint)image->number_channels;
4681 width=(cl_uint)image->columns;
4682 height=(cl_uint)image->rows;
4683 max_channels=number_channels;
4684 if ((max_channels == 4) || (max_channels == 2))
4685 max_channels=max_channels-1;
4687 passes=(((1.0f*image->columns)*image->rows)+1999999.0f)/2000000.0f;
4688 passes=(passes < 1) ? 1 : passes;
4691 status =SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4692 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4693 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
4694 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&max_channels);
4695 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_float),(
void *)&thresh);
4696 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_int),(
void *)&PASSES);
4697 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&width);
4698 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&height);
4699 if (status != CL_SUCCESS)
4701 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4702 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
4706 for (x = 0; x < passes; ++x)
4708 gsize[0]=((width+(SIZE-1))/SIZE)*TILESIZE;
4709 gsize[1]=((((height+(SIZE-1))/SIZE)+passes-1)/passes)*4;
4713 goffset[1]=x*gsize[1];
4715 outputReady=EnqueueOpenCLKernel(queue,denoiseKernel,2,goffset,gsize,lsize,
4716 image,filteredImage,MagickTrue,exception);
4717 if (outputReady == MagickFalse)
4723 if (imageBuffer != (cl_mem) NULL)
4724 ReleaseOpenCLMemObject(imageBuffer);
4725 if (filteredImageBuffer != (cl_mem) NULL)
4726 ReleaseOpenCLMemObject(filteredImageBuffer);
4727 if (denoiseKernel != (cl_kernel) NULL)
4728 ReleaseOpenCLKernel(denoiseKernel);
4729 if (queue != (cl_command_queue) NULL)
4730 ReleaseOpenCLCommandQueue(device,queue);
4731 if (device != (MagickCLDevice) NULL)
4732 ReleaseOpenCLDevice(device);
4733 if ((outputReady == MagickFalse) && (filteredImage != (
Image *) NULL))
4734 filteredImage=DestroyImage(filteredImage);
4736 return(filteredImage);
4739MagickPrivate
Image *AccelerateWaveletDenoiseImage(
const Image *image,
4748 assert(image != NULL);
4751 if (checkAccelerateCondition(image) == MagickFalse)
4752 return((
Image *) NULL);
4754 clEnv=getOpenCLEnvironment(exception);
4755 if (clEnv == (MagickCLEnv) NULL)
4756 return((
Image *) NULL);
4758 filteredImage=ComputeWaveletDenoiseImage(image,clEnv,threshold,exception);
4760 return(filteredImage);