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);
239static Image *cloneImage(
const Image* image,ExceptionInfo *exception)
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,
267 const double sigma,cl_uint *width,ExceptionInfo *exception)
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);
287 if (kernel == (KernelInfo *) NULL)
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,
327 ExceptionInfo *exception)
333 channel_mask=get32BitChannelValue(channel),
350 histogramKernel=NULL;
351 outputReady=MagickFalse;
353 colorspace = image->colorspace;
354 method = image->intensity;
357 histogramKernel = AcquireOpenCLKernel(device,
"Histogram");
358 if (histogramKernel == NULL)
360 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
366 clStatus=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
367 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_int),&channel_mask);
368 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_uint),&colorspace);
369 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_uint),&method);
370 clStatus|=clEnv->library->clSetKernelArg(histogramKernel,i++,
sizeof(cl_mem),(
void *)&histogramBuffer);
371 if (clStatus != CL_SUCCESS)
373 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
378 global_work_size[0] = image->columns;
379 global_work_size[1] = image->rows;
381 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, histogramKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
383 if (clStatus != CL_SUCCESS)
385 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
388 RecordProfileData(device,histogramKernel,event);
390 outputReady = MagickTrue;
394 if (histogramKernel!=NULL)
395 ReleaseOpenCLKernel(histogramKernel);
412static Image *ComputeBlurImage(
const Image* image,MagickCLEnv clEnv,
413 const double radius,
const double sigma,ExceptionInfo *exception)
419 channel_mask=get32BitChannelValue(image->channel_mask),
457 filteredImageBuffer=NULL;
458 tempImageBuffer=NULL;
459 imageKernelBuffer=NULL;
461 blurColumnKernel=NULL;
462 outputReady=MagickFalse;
464 assert(image != (Image *) NULL);
465 assert(image->signature == MagickCoreSignature);
466 if (IsEventLogging() != MagickFalse)
467 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
469 device=RequestOpenCLDevice(clEnv);
470 if (device == (MagickCLDevice) NULL)
472 queue=AcquireOpenCLCommandQueue(device);
473 if (queue == (cl_command_queue) NULL)
475 filteredImage=cloneImage(image,exception);
476 if (filteredImage == (Image *) NULL)
478 if (filteredImage->number_channels != image->number_channels)
480 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
481 if (imageBuffer == (cl_mem) NULL)
483 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
484 if (filteredImageBuffer == (cl_mem) NULL)
487 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
489 if (imageKernelBuffer == (cl_mem) NULL)
492 length=image->columns*image->rows;
493 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
494 sizeof(cl_float4),(
void *) NULL);
495 if (tempImageBuffer == (cl_mem) NULL)
498 blurRowKernel=AcquireOpenCLKernel(device,
"BlurRow");
499 if (blurRowKernel == (cl_kernel) NULL)
501 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
502 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
506 number_channels=(cl_uint) image->number_channels;
507 imageColumns=(cl_uint) image->columns;
508 imageRows=(cl_uint) image->rows;
511 status =SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
512 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),&number_channels);
513 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_int),&channel_mask);
514 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
515 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
516 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
517 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
518 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
519 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
520 if (status != CL_SUCCESS)
522 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
523 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
527 gsize[0]=chunkSize*((image->columns+chunkSize-1)/chunkSize);
528 gsize[1]=image->rows;
532 outputReady=EnqueueOpenCLKernel(queue,blurRowKernel,2,(
size_t *) NULL,gsize,
533 lsize,image,filteredImage,MagickFalse,exception);
534 if (outputReady == MagickFalse)
537 blurColumnKernel=AcquireOpenCLKernel(device,
"BlurColumn");
538 if (blurColumnKernel == (cl_kernel) NULL)
540 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
541 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
546 status =SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
547 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),&number_channels);
548 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_int),&channel_mask);
549 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
550 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
551 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
552 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
553 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
554 status|=SetOpenCLKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
555 if (status != CL_SUCCESS)
557 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
558 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
562 gsize[0]=image->columns;
563 gsize[1]=chunkSize*((image->rows+chunkSize-1)/chunkSize);
567 outputReady=EnqueueOpenCLKernel(queue,blurColumnKernel,2,(
size_t *) NULL,gsize,
568 lsize,image,filteredImage,MagickFalse,exception);
572 if (imageBuffer != (cl_mem) NULL)
573 ReleaseOpenCLMemObject(imageBuffer);
574 if (filteredImageBuffer != (cl_mem) NULL)
575 ReleaseOpenCLMemObject(filteredImageBuffer);
576 if (tempImageBuffer != (cl_mem) NULL)
577 ReleaseOpenCLMemObject(tempImageBuffer);
578 if (imageKernelBuffer != (cl_mem) NULL)
579 ReleaseOpenCLMemObject(imageKernelBuffer);
580 if (blurRowKernel != (cl_kernel) NULL)
581 ReleaseOpenCLKernel(blurRowKernel);
582 if (blurColumnKernel != (cl_kernel) NULL)
583 ReleaseOpenCLKernel(blurColumnKernel);
584 if (queue != (cl_command_queue) NULL)
585 ReleaseOpenCLCommandQueue(device,queue);
586 if (device != (MagickCLDevice) NULL)
587 ReleaseOpenCLDevice(device);
588 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
589 filteredImage=DestroyImage(filteredImage);
591 return(filteredImage);
594MagickPrivate Image* AccelerateBlurImage(
const Image *image,
595 const double radius,
const double sigma,ExceptionInfo *exception)
603 assert(image != NULL);
604 assert(exception != (ExceptionInfo *) NULL);
605 if (IsEventLogging() != MagickFalse)
606 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
608 if (checkAccelerateCondition(image) == MagickFalse)
609 return((Image *) NULL);
611 clEnv=getOpenCLEnvironment(exception);
612 if (clEnv == (MagickCLEnv) NULL)
613 return((Image *) NULL);
615 filteredImage=ComputeBlurImage(image,clEnv,radius,sigma,exception);
616 return(filteredImage);
631static MagickBooleanType ComputeContrastImage(Image *image,MagickCLEnv clEnv,
632 const MagickBooleanType sharpen,ExceptionInfo *exception)
660 assert(image != (Image *) NULL);
661 assert(image->signature == MagickCoreSignature);
662 if (IsEventLogging() != MagickFalse)
663 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
668 outputReady=MagickFalse;
670 device=RequestOpenCLDevice(clEnv);
671 if (device == (MagickCLDevice) NULL)
673 queue=AcquireOpenCLCommandQueue(device);
674 if (queue == (cl_command_queue) NULL)
676 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
677 if (imageBuffer == (cl_mem) NULL)
680 contrastKernel=AcquireOpenCLKernel(device,
"Contrast");
681 if (contrastKernel == (cl_kernel) NULL)
683 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
684 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
688 number_channels=(cl_uint) image->number_channels;
689 sign=sharpen != MagickFalse ? 1 : -1;
692 status =SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
693 status|=SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_uint),&number_channels);
694 status|=SetOpenCLKernelArg(contrastKernel,i++,
sizeof(cl_int),&sign);
695 if (status != CL_SUCCESS)
697 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
698 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
702 gsize[0]=image->columns;
703 gsize[1]=image->rows;
705 outputReady=EnqueueOpenCLKernel(queue,contrastKernel,2,(
const size_t *) NULL,
706 gsize,(
const size_t *) NULL,image,(Image *) NULL,MagickFalse,exception);
710 if (imageBuffer != (cl_mem) NULL)
711 ReleaseOpenCLMemObject(imageBuffer);
712 if (contrastKernel != (cl_kernel) NULL)
713 ReleaseOpenCLKernel(contrastKernel);
714 if (queue != (cl_command_queue) NULL)
715 ReleaseOpenCLCommandQueue(device,queue);
716 if (device != (MagickCLDevice) NULL)
717 ReleaseOpenCLDevice(device);
722MagickPrivate MagickBooleanType AccelerateContrastImage(Image *image,
723 const MagickBooleanType sharpen,ExceptionInfo *exception)
731 assert(image != NULL);
732 assert(exception != (ExceptionInfo *) NULL);
733 if (IsEventLogging() != MagickFalse)
734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
736 if (checkAccelerateCondition(image) == MagickFalse)
739 clEnv=getOpenCLEnvironment(exception);
740 if (clEnv == (MagickCLEnv) NULL)
743 status=ComputeContrastImage(image,clEnv,sharpen,exception);
759static MagickBooleanType ComputeContrastStretchImage(Image *image,
760 MagickCLEnv clEnv,
const double black_point,
const double white_point,
761 ExceptionInfo *exception)
763#define ContrastStretchImageTag "ContrastStretch/Image"
764#define MaxRange(color) ((cl_float) ScaleQuantumToMap((Quantum) (color)))
773 channel_mask=get32BitChannelValue(image->channel_mask),
822 assert(image != (Image *) NULL);
823 assert(image->signature == MagickCoreSignature);
824 if (IsEventLogging() != MagickFalse)
825 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
833 histogramBuffer=NULL;
834 stretchMapBuffer=NULL;
835 histogramKernel=NULL;
837 outputReady=MagickFalse;
842 device=RequestOpenCLDevice(clEnv);
843 if (device == (MagickCLDevice) NULL)
845 queue=AcquireOpenCLCommandQueue(device);
846 if (queue == (cl_command_queue) NULL)
852 histogram=(cl_uint4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*histogram));
854 if (histogram == (cl_uint4 *) NULL)
855 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed", image->filename);
858 (void) memset(histogram,0,(MaxMap+1)*
sizeof(*histogram));
874 image_view=AcquireAuthenticCacheView(image,exception);
875 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
877 if (inputPixels == (
void *) NULL)
879 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
885 if (ALIGNED(inputPixels,CLPixelPacket))
887 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
891 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
894 length = image->columns * image->rows;
895 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
896 if (clStatus != CL_SUCCESS)
898 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
905 if (ALIGNED(histogram,cl_uint4))
907 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
912 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
917 histogramBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(cl_uint4), hostPtr, &clStatus);
918 if (clStatus != CL_SUCCESS)
920 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
924 status = LaunchHistogramKernel(clEnv, device, queue, imageBuffer, histogramBuffer, image, image->channel_mask,exception);
925 if (status == MagickFalse)
929 if (ALIGNED(histogram,cl_uint4))
932 clEnv->library->clEnqueueMapBuffer(queue, histogramBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(cl_uint4), 0, NULL, NULL, &clStatus);
937 clStatus = clEnv->library->clEnqueueReadBuffer(queue, histogramBuffer, CL_TRUE, 0, length *
sizeof(cl_uint4), histogram, 0, NULL, NULL);
939 if (clStatus != CL_SUCCESS)
941 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
946 if (ALIGNED(histogram,cl_uint4))
948 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, histogramBuffer, histogram, 0, NULL, NULL);
949 if (clStatus != CL_SUCCESS)
951 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueUnmapMemObject failed.",
".");
958 if (imageBuffer!=NULL)
959 clEnv->library->clReleaseMemObject(imageBuffer);
967 white.x=MaxRange(QuantumRange);
968 if ((image->channel_mask & RedChannel) != 0)
971 for (i=0; i <= (ssize_t) MaxMap; i++)
973 intensity+=histogram[i].s[2];
974 if (intensity > black_point)
977 black.x=(cl_float) i;
979 for (i=(ssize_t) MaxMap; i != 0; i--)
981 intensity+=histogram[i].s[2];
982 if (intensity > ((
double) image->columns*image->rows-white_point))
985 white.x=(cl_float) i;
988 white.y=MaxRange(QuantumRange);
989 if ((image->channel_mask & GreenChannel) != 0)
992 for (i=0; i <= (ssize_t) MaxMap; i++)
994 intensity+=histogram[i].s[2];
995 if (intensity > black_point)
998 black.y=(cl_float) i;
1000 for (i=(ssize_t) MaxMap; i != 0; i--)
1002 intensity+=histogram[i].s[2];
1003 if (intensity > ((
double) image->columns*image->rows-white_point))
1006 white.y=(cl_float) i;
1009 white.z=MaxRange(QuantumRange);
1010 if ((image->channel_mask & BlueChannel) != 0)
1013 for (i=0; i <= (ssize_t) MaxMap; i++)
1015 intensity+=histogram[i].s[2];
1016 if (intensity > black_point)
1019 black.z=(cl_float) i;
1021 for (i=(ssize_t) MaxMap; i != 0; i--)
1023 intensity+=histogram[i].s[2];
1024 if (intensity > ((
double) image->columns*image->rows-white_point))
1027 white.z=(cl_float) i;
1030 white.w=MaxRange(QuantumRange);
1031 if ((image->channel_mask & AlphaChannel) != 0)
1034 for (i=0; i <= (ssize_t) MaxMap; i++)
1036 intensity+=histogram[i].s[2];
1037 if (intensity > black_point)
1040 black.w=(cl_float) i;
1042 for (i=(ssize_t) MaxMap; i != 0; i--)
1044 intensity+=histogram[i].s[2];
1045 if (intensity > ((
double) image->columns*image->rows-white_point))
1048 white.w=(cl_float) i;
1051 stretch_map=(PixelPacket *) AcquireQuantumMemory(MaxMap+1UL,
1052 sizeof(*stretch_map));
1054 if (stretch_map == (PixelPacket *) NULL)
1055 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
1061 (void) memset(stretch_map,0,(MaxMap+1)*
sizeof(*stretch_map));
1062 for (i=0; i <= (ssize_t) MaxMap; i++)
1064 if ((image->channel_mask & RedChannel) != 0)
1066 if (i < (cl_uint) black.x)
1067 stretch_map[i].red=0;
1069 if (i > (cl_uint) white.x)
1070 stretch_map[i].red=(
unsigned int) QuantumRange;
1072 if (black.x != white.x)
1073 stretch_map[i].red=(
unsigned int) ScaleMapToQuantum(
1074 (MagickRealType) (MaxMap*(i-black.x)/(white.x-black.x)));
1076 if ((image->channel_mask & GreenChannel) != 0)
1078 if (i < (cl_uint) black.y)
1079 stretch_map[i].green=0;
1081 if (i > (cl_uint) white.y)
1082 stretch_map[i].green=(
unsigned int) QuantumRange;
1084 if (black.y != white.y)
1085 stretch_map[i].green=(
unsigned int) ScaleMapToQuantum(
1086 (MagickRealType) (MaxMap*(i-black.y)/(white.y-black.y)));
1088 if ((image->channel_mask & BlueChannel) != 0)
1090 if (i < (cl_uint) black.z)
1091 stretch_map[i].blue=0;
1093 if (i > (cl_uint) white.z)
1094 stretch_map[i].blue=(
unsigned int) QuantumRange;
1096 if (black.z != white.z)
1097 stretch_map[i].blue=(
unsigned int) ScaleMapToQuantum(
1098 (MagickRealType) (MaxMap*(i-black.z)/(white.z-black.z)));
1100 if ((image->channel_mask & AlphaChannel) != 0)
1102 if (i < (cl_uint) black.w)
1103 stretch_map[i].alpha=0;
1105 if (i > (cl_uint) white.w)
1106 stretch_map[i].alpha=(
unsigned int) QuantumRange;
1108 if (black.w != white.w)
1109 stretch_map[i].alpha=(
unsigned int) ScaleMapToQuantum(
1110 (MagickRealType) (MaxMap*(i-black.w)/(white.w-black.w)));
1117 if (((image->channel_mask & AlphaChannel) != 0) || (((image->channel_mask & IndexChannel) != 0) &&
1118 (image->colorspace == CMYKColorspace)))
1119 image->storage_class=DirectClass;
1120 if (image->storage_class == PseudoClass)
1125 for (i=0; i < (cl_uint) image->colors; i++)
1127 if ((image->channel_mask & RedChannel) != 0)
1129 if (black.x != white.x)
1130 image->colormap[i].red=stretch_map[
1131 ScaleQuantumToMap((
const Quantum) image->colormap[i].red)].red;
1133 if ((image->channel_mask & GreenChannel) != 0)
1135 if (black.y != white.y)
1136 image->colormap[i].green=stretch_map[
1137 ScaleQuantumToMap((
const Quantum) image->colormap[i].green)].green;
1139 if ((image->channel_mask & BlueChannel) != 0)
1141 if (black.z != white.z)
1142 image->colormap[i].blue=stretch_map[
1143 ScaleQuantumToMap((
const Quantum) image->colormap[i].blue)].blue;
1145 if ((image->channel_mask & AlphaChannel) != 0)
1147 if (black.w != white.w)
1148 image->colormap[i].alpha=stretch_map[
1149 ScaleQuantumToMap((
const Quantum) image->colormap[i].alpha)].alpha;
1164#ifdef RECREATEBUFFER
1168 if (ALIGNED(inputPixels,CLPixelPacket))
1170 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
1174 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1177 length = image->columns * image->rows;
1178 imageBuffer = clEnv->library->clCreateBuffer(context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1179 if (clStatus != CL_SUCCESS)
1181 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1187 if (ALIGNED(stretch_map, PixelPacket))
1189 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1190 hostPtr = stretch_map;
1194 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1195 hostPtr = stretch_map;
1198 length = (MaxMap+1);
1199 stretchMapBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(PixelPacket), hostPtr, &clStatus);
1200 if (clStatus != CL_SUCCESS)
1202 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1207 stretchKernel = AcquireOpenCLKernel(device,
"ContrastStretch");
1208 if (stretchKernel == NULL)
1210 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
1216 clStatus=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
1217 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_int),&channel_mask);
1218 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_mem),(
void *)&stretchMapBuffer);
1219 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_float4),&white);
1220 clStatus|=clEnv->library->clSetKernelArg(stretchKernel,i++,
sizeof(cl_float4),&black);
1221 if (clStatus != CL_SUCCESS)
1223 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1228 global_work_size[0] = image->columns;
1229 global_work_size[1] = image->rows;
1231 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, stretchKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1233 if (clStatus != CL_SUCCESS)
1235 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1238 RecordProfileData(device,stretchKernel,event);
1241 if (ALIGNED(inputPixels,CLPixelPacket))
1243 length = image->columns * image->rows;
1244 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
1248 length = image->columns * image->rows;
1249 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
1251 if (clStatus != CL_SUCCESS)
1253 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1257 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
1261 image_view=DestroyCacheView(image_view);
1263 if (imageBuffer!=NULL)
1264 clEnv->library->clReleaseMemObject(imageBuffer);
1266 if (stretchMapBuffer!=NULL)
1267 clEnv->library->clReleaseMemObject(stretchMapBuffer);
1268 if (stretch_map!=NULL)
1269 stretch_map=(PixelPacket *) RelinquishMagickMemory(stretch_map);
1270 if (histogramBuffer!=NULL)
1271 clEnv->library->clReleaseMemObject(histogramBuffer);
1272 if (histogram!=NULL)
1273 histogram=(cl_uint4 *) RelinquishMagickMemory(histogram);
1274 if (histogramKernel!=NULL)
1275 ReleaseOpenCLKernel(histogramKernel);
1276 if (stretchKernel!=NULL)
1277 ReleaseOpenCLKernel(stretchKernel);
1279 ReleaseOpenCLCommandQueue(device,queue);
1281 ReleaseOpenCLDevice(device);
1283 return(outputReady);
1286MagickPrivate MagickBooleanType AccelerateContrastStretchImage(
1287 Image *image,
const double black_point,
const double white_point,
1288 ExceptionInfo *exception)
1296 assert(image != NULL);
1297 assert(exception != (ExceptionInfo *) NULL);
1298 if (IsEventLogging() != MagickFalse)
1299 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1301 if ((checkAccelerateConditionRGBA(image) == MagickFalse) ||
1302 (checkHistogramCondition(image,image->intensity) == MagickFalse))
1303 return(MagickFalse);
1305 clEnv=getOpenCLEnvironment(exception);
1306 if (clEnv == (MagickCLEnv) NULL)
1307 return(MagickFalse);
1309 status=ComputeContrastStretchImage(image,clEnv,black_point,white_point,
1326static Image *ComputeDespeckleImage(
const Image *image,MagickCLEnv clEnv,
1327 ExceptionInfo*exception)
1330 X[4] = {0, 1, 1,-1},
1331 Y[4] = {1, 0, 1, 1};
1334 *filteredImage_view,
1354 filteredImageBuffer,
1375 global_work_size[2],
1390 filteredImage_view=NULL;
1391 filteredPixels=NULL;
1393 filteredImageBuffer=NULL;
1396 tempImageBuffer[0]=NULL;
1397 tempImageBuffer[1]=NULL;
1398 outputReady=MagickFalse;
1400 device=RequestOpenCLDevice(clEnv);
1401 if (device == (MagickCLDevice) NULL)
1403 queue=AcquireOpenCLCommandQueue(device);
1404 if (queue == (cl_command_queue) NULL)
1407 image_view=AcquireAuthenticCacheView(image,exception);
1408 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
1409 if (inputPixels == (
void *) NULL)
1411 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
1415 if (ALIGNED(inputPixels,CLPixelPacket))
1417 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1421 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
1424 length = image->columns * image->rows;
1425 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1426 if (clStatus != CL_SUCCESS)
1428 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1432 mem_flags = CL_MEM_READ_WRITE;
1433 length = image->columns * image->rows;
1434 for (k = 0; k < 2; k++)
1436 tempImageBuffer[k] = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), NULL, &clStatus);
1437 if (clStatus != CL_SUCCESS)
1439 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1444 filteredImage = CloneImage(image,0,0,MagickTrue,exception);
1445 assert(filteredImage != NULL);
1446 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
1448 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"CloneImage failed.",
".");
1451 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
1452 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
1453 if (filteredPixels == (
void *) NULL)
1455 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
1459 if (ALIGNED(filteredPixels,CLPixelPacket))
1461 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
1462 hostPtr = filteredPixels;
1466 mem_flags = CL_MEM_WRITE_ONLY;
1470 length = image->columns * image->rows;
1471 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
1472 if (clStatus != CL_SUCCESS)
1474 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1478 hullPass1 = AcquireOpenCLKernel(device,
"HullPass1");
1479 hullPass2 = AcquireOpenCLKernel(device,
"HullPass2");
1481 clStatus =clEnv->library->clSetKernelArg(hullPass1,0,
sizeof(cl_mem),(
void *)&imageBuffer);
1482 clStatus |=clEnv->library->clSetKernelArg(hullPass1,1,
sizeof(cl_mem),(
void *)(tempImageBuffer+1));
1483 imageWidth = (
unsigned int) image->columns;
1484 clStatus |=clEnv->library->clSetKernelArg(hullPass1,2,
sizeof(
unsigned int),(
void *)&imageWidth);
1485 imageHeight = (
unsigned int) image->rows;
1486 clStatus |=clEnv->library->clSetKernelArg(hullPass1,3,
sizeof(
unsigned int),(
void *)&imageHeight);
1487 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
1488 clStatus |=clEnv->library->clSetKernelArg(hullPass1,6,
sizeof(
int),(
void *)&matte);
1489 if (clStatus != CL_SUCCESS)
1491 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1495 clStatus = clEnv->library->clSetKernelArg(hullPass2,0,
sizeof(cl_mem),(
void *)(tempImageBuffer+1));
1496 clStatus |=clEnv->library->clSetKernelArg(hullPass2,1,
sizeof(cl_mem),(
void *)tempImageBuffer);
1497 imageWidth = (
unsigned int) image->columns;
1498 clStatus |=clEnv->library->clSetKernelArg(hullPass2,2,
sizeof(
unsigned int),(
void *)&imageWidth);
1499 imageHeight = (
unsigned int) image->rows;
1500 clStatus |=clEnv->library->clSetKernelArg(hullPass2,3,
sizeof(
unsigned int),(
void *)&imageHeight);
1501 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
1502 clStatus |=clEnv->library->clSetKernelArg(hullPass2,6,
sizeof(
int),(
void *)&matte);
1503 if (clStatus != CL_SUCCESS)
1505 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1510 global_work_size[0] = image->columns;
1511 global_work_size[1] = image->rows;
1514 for (k = 0; k < 4; k++)
1523 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1524 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1525 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1526 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1527 if (clStatus != CL_SUCCESS)
1529 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1533 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1534 if (clStatus != CL_SUCCESS)
1536 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1539 RecordProfileData(device,hullPass1,event);
1542 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1543 if (clStatus != CL_SUCCESS)
1545 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1548 RecordProfileData(device,hullPass2,event);
1551 clStatus =clEnv->library->clSetKernelArg(hullPass1,0,
sizeof(cl_mem),(
void *)(tempImageBuffer));
1552 offset.s[0] = -X[k];
1553 offset.s[1] = -Y[k];
1555 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1556 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1557 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1558 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1559 if (clStatus != CL_SUCCESS)
1561 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1565 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1566 if (clStatus != CL_SUCCESS)
1568 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1571 RecordProfileData(device,hullPass1,event);
1574 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1575 if (clStatus != CL_SUCCESS)
1577 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1580 RecordProfileData(device,hullPass2,event);
1582 offset.s[0] = -X[k];
1583 offset.s[1] = -Y[k];
1585 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1586 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1587 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1588 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1589 if (clStatus != CL_SUCCESS)
1591 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1595 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1596 if (clStatus != CL_SUCCESS)
1598 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1601 RecordProfileData(device,hullPass1,event);
1604 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1605 if (clStatus != CL_SUCCESS)
1607 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1610 RecordProfileData(device,hullPass2,event);
1615 clStatus = clEnv->library->clSetKernelArg(hullPass1,4,
sizeof(cl_int2),(
void *)&offset);
1616 clStatus|= clEnv->library->clSetKernelArg(hullPass1,5,
sizeof(
int),(
void *)&polarity);
1617 clStatus|=clEnv->library->clSetKernelArg(hullPass2,4,
sizeof(cl_int2),(
void *)&offset);
1618 clStatus|=clEnv->library->clSetKernelArg(hullPass2,5,
sizeof(
int),(
void *)&polarity);
1621 clStatus |=clEnv->library->clSetKernelArg(hullPass2,1,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
1623 if (clStatus != CL_SUCCESS)
1625 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
1629 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass1, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1630 if (clStatus != CL_SUCCESS)
1632 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1635 RecordProfileData(device,hullPass1,event);
1638 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, hullPass2, 2, NULL, global_work_size, NULL, 0, NULL, &event);
1639 if (clStatus != CL_SUCCESS)
1641 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
1644 RecordProfileData(device,hullPass2,event);
1647 if (ALIGNED(filteredPixels,CLPixelPacket))
1649 length = image->columns * image->rows;
1650 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
1654 length = image->columns * image->rows;
1655 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
1657 if (clStatus != CL_SUCCESS)
1659 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1663 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
1667 image_view=DestroyCacheView(image_view);
1668 if (filteredImage_view != NULL)
1669 filteredImage_view=DestroyCacheView(filteredImage_view);
1672 ReleaseOpenCLCommandQueue(device,queue);
1674 ReleaseOpenCLDevice(device);
1675 if (imageBuffer!=NULL)
1676 clEnv->library->clReleaseMemObject(imageBuffer);
1677 for (k = 0; k < 2; k++)
1679 if (tempImageBuffer[k]!=NULL)
1680 clEnv->library->clReleaseMemObject(tempImageBuffer[k]);
1682 if (filteredImageBuffer!=NULL)
1683 clEnv->library->clReleaseMemObject(filteredImageBuffer);
1684 if (hullPass1!=NULL)
1685 ReleaseOpenCLKernel(hullPass1);
1686 if (hullPass2!=NULL)
1687 ReleaseOpenCLKernel(hullPass2);
1688 if (outputReady == MagickFalse && filteredImage != NULL)
1689 filteredImage=DestroyImage(filteredImage);
1691 return(filteredImage);
1694MagickPrivate Image *AccelerateDespeckleImage(
const Image* image,
1695 ExceptionInfo* exception)
1703 assert(image != NULL);
1704 assert(exception != (ExceptionInfo *) NULL);
1706 if (checkAccelerateConditionRGBA(image) == MagickFalse)
1707 return((Image *) NULL);
1709 clEnv=getOpenCLEnvironment(exception);
1710 if (clEnv == (MagickCLEnv) NULL)
1711 return((Image *) NULL);
1713 filteredImage=ComputeDespeckleImage(image,clEnv,exception);
1714 return(filteredImage);
1729static MagickBooleanType ComputeEqualizeImage(Image *image,MagickCLEnv clEnv,
1730 ExceptionInfo *exception)
1732#define EqualizeImageTag "Equalize/Image"
1741 channel_mask=get32BitChannelValue(image->channel_mask),
1782 global_work_size[2],
1789 assert(image != (Image *) NULL);
1790 assert(image->signature == MagickCoreSignature);
1791 if (IsEventLogging() != MagickFalse)
1792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1801 histogramBuffer=NULL;
1802 equalizeMapBuffer=NULL;
1803 histogramKernel=NULL;
1804 equalizeKernel=NULL;
1805 outputReady=MagickFalse;
1810 device=RequestOpenCLDevice(clEnv);
1811 if (device == (MagickCLDevice) NULL)
1813 queue=AcquireOpenCLCommandQueue(device);
1814 if (queue == (cl_command_queue) NULL)
1820 histogram=(cl_uint4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*histogram));
1821 if (histogram == (cl_uint4 *) NULL)
1822 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1825 (void) memset(histogram,0,(MaxMap+1)*
sizeof(*histogram));
1830 image_view=AcquireAuthenticCacheView(image,exception);
1831 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
1833 if (inputPixels == (
void *) NULL)
1835 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
1841 if (ALIGNED(inputPixels,CLPixelPacket))
1843 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
1847 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
1850 length = image->columns * image->rows;
1851 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
1852 if (clStatus != CL_SUCCESS)
1854 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1861 if (ALIGNED(histogram,cl_uint4))
1863 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
1864 hostPtr = histogram;
1868 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
1869 hostPtr = histogram;
1872 length = (MaxMap+1);
1873 histogramBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(cl_uint4), hostPtr, &clStatus);
1874 if (clStatus != CL_SUCCESS)
1876 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
1880 status = LaunchHistogramKernel(clEnv, device, queue, imageBuffer, histogramBuffer, image, image->channel_mask, exception);
1881 if (status == MagickFalse)
1885 if (ALIGNED(histogram,cl_uint4))
1887 length = (MaxMap+1);
1888 clEnv->library->clEnqueueMapBuffer(queue, histogramBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(cl_uint4), 0, NULL, NULL, &clStatus);
1892 length = (MaxMap+1);
1893 clStatus = clEnv->library->clEnqueueReadBuffer(queue, histogramBuffer, CL_TRUE, 0, length *
sizeof(cl_uint4), histogram, 0, NULL, NULL);
1895 if (clStatus != CL_SUCCESS)
1897 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
1902 if (ALIGNED(histogram,cl_uint4))
1904 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, histogramBuffer, histogram, 0, NULL, NULL);
1905 if (clStatus != CL_SUCCESS)
1907 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueUnmapMemObject failed.",
".");
1913#ifdef RECREATEBUFFER
1914 if (imageBuffer!=NULL)
1915 clEnv->library->clReleaseMemObject(imageBuffer);
1919 equalize_map=(PixelPacket *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*equalize_map));
1920 if (equalize_map == (PixelPacket *) NULL)
1921 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1923 map=(cl_float4 *) AcquireQuantumMemory(MaxMap+1UL,
sizeof(*map));
1924 if (map == (cl_float4 *) NULL)
1925 ThrowBinaryException(ResourceLimitWarning,
"MemoryAllocationFailed", image->filename);
1930 (void) memset(&intensity,0,
sizeof(intensity));
1931 for (i=0; i <= (ssize_t) MaxMap; i++)
1933 if ((image->channel_mask & SyncChannels) != 0)
1935 intensity.x+=histogram[i].s[2];
1939 if ((image->channel_mask & RedChannel) != 0)
1940 intensity.x+=histogram[i].s[2];
1941 if ((image->channel_mask & GreenChannel) != 0)
1942 intensity.y+=histogram[i].s[1];
1943 if ((image->channel_mask & BlueChannel) != 0)
1944 intensity.z+=histogram[i].s[0];
1945 if ((image->channel_mask & AlphaChannel) != 0)
1946 intensity.w+=histogram[i].s[3];
1950 white=map[(int) MaxMap];
1951 (void) memset(equalize_map,0,(MaxMap+1)*
sizeof(*equalize_map));
1952 for (i=0; i <= (ssize_t) MaxMap; i++)
1954 if ((image->channel_mask & SyncChannels) != 0)
1956 if (white.x != black.x)
1957 equalize_map[i].red=(
unsigned int) ScaleMapToQuantum(
1958 (MagickRealType) ((MaxMap*(map[i].x-black.x))/(white.x-black.x)));
1961 if (((image->channel_mask & RedChannel) != 0) && (white.x != black.x))
1962 equalize_map[i].red=(
unsigned int) ScaleMapToQuantum(
1963 (MagickRealType) ((MaxMap*(map[i].x-black.x))/(white.x-black.x)));
1964 if (((image->channel_mask & GreenChannel) != 0) && (white.y != black.y))
1965 equalize_map[i].green=(
unsigned int) ScaleMapToQuantum(
1966 (MagickRealType) ((MaxMap*(map[i].y-black.y))/(white.y-black.y)));
1967 if (((image->channel_mask & BlueChannel) != 0) && (white.z != black.z))
1968 equalize_map[i].blue=(
unsigned int) ScaleMapToQuantum(
1969 (MagickRealType) ((MaxMap*(map[i].z-black.z))/(white.z-black.z)));
1970 if (((image->channel_mask & AlphaChannel) != 0) && (white.w != black.w))
1971 equalize_map[i].alpha=(
unsigned int) ScaleMapToQuantum(
1972 (MagickRealType) ((MaxMap*(map[i].w-black.w))/(white.w-black.w)));
1975 if (image->storage_class == PseudoClass)
1980 for (i=0; i < (cl_uint) image->colors; i++)
1982 if ((image->channel_mask & SyncChannels) != 0)
1984 if (white.x != black.x)
1986 image->colormap[i].red=equalize_map[
1987 ScaleQuantumToMap((
const Quantum) image->colormap[i].red)].red;
1988 image->colormap[i].green=equalize_map[
1989 ScaleQuantumToMap((
const Quantum) image->colormap[i].green)].red;
1990 image->colormap[i].blue=equalize_map[
1991 ScaleQuantumToMap((
const Quantum) image->colormap[i].blue)].red;
1992 image->colormap[i].alpha=equalize_map[
1993 ScaleQuantumToMap((
const Quantum) image->colormap[i].alpha)].red;
1997 if (((image->channel_mask & RedChannel) != 0) && (white.x != black.x))
1998 image->colormap[i].red=equalize_map[
1999 ScaleQuantumToMap((
const Quantum) image->colormap[i].red)].red;
2000 if (((image->channel_mask & GreenChannel) != 0) && (white.y != black.y))
2001 image->colormap[i].green=equalize_map[
2002 ScaleQuantumToMap((
const Quantum) image->colormap[i].green)].green;
2003 if (((image->channel_mask & BlueChannel) != 0) && (white.z != black.z))
2004 image->colormap[i].blue=equalize_map[
2005 ScaleQuantumToMap((
const Quantum) image->colormap[i].blue)].blue;
2006 if (((image->channel_mask & AlphaChannel) != 0) && (white.w != black.w))
2007 image->colormap[i].alpha=equalize_map[
2008 ScaleQuantumToMap((
const Quantum) image->colormap[i].alpha)].alpha;
2021#ifdef RECREATEBUFFER
2025 if (ALIGNED(inputPixels,CLPixelPacket))
2027 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
2031 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2034 length = image->columns * image->rows;
2035 imageBuffer = clEnv->library->clCreateBuffer(context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2036 if (clStatus != CL_SUCCESS)
2038 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2044 if (ALIGNED(equalize_map, PixelPacket))
2046 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
2047 hostPtr = equalize_map;
2051 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2052 hostPtr = equalize_map;
2055 length = (MaxMap+1);
2056 equalizeMapBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(PixelPacket), hostPtr, &clStatus);
2057 if (clStatus != CL_SUCCESS)
2059 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2064 equalizeKernel = AcquireOpenCLKernel(device,
"Equalize");
2065 if (equalizeKernel == NULL)
2067 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2073 clStatus=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2074 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_int),&channel_mask);
2075 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_mem),(
void *)&equalizeMapBuffer);
2076 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_float4),&white);
2077 clStatus|=clEnv->library->clSetKernelArg(equalizeKernel,i++,
sizeof(cl_float4),&black);
2078 if (clStatus != CL_SUCCESS)
2080 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2085 global_work_size[0] = image->columns;
2086 global_work_size[1] = image->rows;
2088 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, equalizeKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
2090 if (clStatus != CL_SUCCESS)
2092 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2095 RecordProfileData(device,equalizeKernel,event);
2098 if (ALIGNED(inputPixels,CLPixelPacket))
2100 length = image->columns * image->rows;
2101 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2105 length = image->columns * image->rows;
2106 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
2108 if (clStatus != CL_SUCCESS)
2110 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
2114 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
2118 image_view=DestroyCacheView(image_view);
2120 if (imageBuffer!=NULL)
2121 clEnv->library->clReleaseMemObject(imageBuffer);
2123 map=(cl_float4 *) RelinquishMagickMemory(map);
2124 if (equalizeMapBuffer!=NULL)
2125 clEnv->library->clReleaseMemObject(equalizeMapBuffer);
2126 if (equalize_map!=NULL)
2127 equalize_map=(PixelPacket *) RelinquishMagickMemory(equalize_map);
2128 if (histogramBuffer!=NULL)
2129 clEnv->library->clReleaseMemObject(histogramBuffer);
2130 if (histogram!=NULL)
2131 histogram=(cl_uint4 *) RelinquishMagickMemory(histogram);
2132 if (histogramKernel!=NULL)
2133 ReleaseOpenCLKernel(histogramKernel);
2134 if (equalizeKernel!=NULL)
2135 ReleaseOpenCLKernel(equalizeKernel);
2137 ReleaseOpenCLCommandQueue(device, queue);
2139 ReleaseOpenCLDevice(device);
2141 return(outputReady);
2144MagickPrivate MagickBooleanType AccelerateEqualizeImage(Image *image,
2145 ExceptionInfo *exception)
2153 assert(image != NULL);
2154 assert(exception != (ExceptionInfo *) NULL);
2155 if (IsEventLogging() != MagickFalse)
2156 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2158 if ((checkAccelerateConditionRGBA(image) == MagickFalse) ||
2159 (checkHistogramCondition(image,image->intensity) == MagickFalse))
2160 return(MagickFalse);
2162 clEnv=getOpenCLEnvironment(exception);
2163 if (clEnv == (MagickCLEnv) NULL)
2164 return(MagickFalse);
2166 status=ComputeEqualizeImage(image,clEnv,exception);
2182static MagickBooleanType ComputeFunctionImage(Image *image,MagickCLEnv clEnv,
2183 const MagickFunction function,
const size_t number_parameters,
2184 const double *parameters,ExceptionInfo *exception)
2190 channel_mask=get32BitChannelValue(image->channel_mask),
2205 *parametersBufferPtr;
2217 assert(image != (Image *) NULL);
2218 assert(image->signature == MagickCoreSignature);
2219 if (IsEventLogging() != MagickFalse)
2220 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2224 functionKernel=NULL;
2225 parametersBuffer=NULL;
2226 outputReady=MagickFalse;
2228 device=RequestOpenCLDevice(clEnv);
2229 if (device == (MagickCLDevice) NULL)
2231 queue=AcquireOpenCLCommandQueue(device);
2232 if (queue == (cl_command_queue) NULL)
2234 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
2235 if (imageBuffer == (cl_mem) NULL)
2238 parametersBufferPtr=(
float *) AcquireQuantumMemory(number_parameters,
2240 if (parametersBufferPtr == (
float *) NULL)
2242 for (i=0; i<number_parameters; i++)
2243 parametersBufferPtr[i]=(
float) parameters[i];
2244 parametersBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
2245 CL_MEM_COPY_HOST_PTR,number_parameters*
sizeof(*parametersBufferPtr),
2246 parametersBufferPtr);
2247 parametersBufferPtr=(
float *) RelinquishMagickMemory(parametersBufferPtr);
2248 if (parametersBuffer == (cl_mem) NULL)
2250 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2251 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
2255 functionKernel=AcquireOpenCLKernel(device,
"ComputeFunction");
2256 if (functionKernel == (cl_kernel) NULL)
2258 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2259 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2263 number_channels=(cl_uint) image->number_channels;
2264 number_params=(cl_uint) number_parameters;
2267 status =SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2268 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
2269 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_int),&channel_mask);
2270 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(MagickFunction),(
void *)&function);
2271 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_uint),(
void *)&number_params);
2272 status|=SetOpenCLKernelArg(functionKernel,i++,
sizeof(cl_mem),(
void *)¶metersBuffer);
2273 if (status != CL_SUCCESS)
2275 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2276 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
2280 gsize[0]=image->columns;
2281 gsize[1]=image->rows;
2282 outputReady=EnqueueOpenCLKernel(queue,functionKernel,2,(
const size_t *) NULL,
2283 gsize,(
const size_t *) NULL,image,(
const Image *) NULL,MagickFalse,
2288 if (imageBuffer != (cl_mem) NULL)
2289 ReleaseOpenCLMemObject(imageBuffer);
2290 if (parametersBuffer != (cl_mem) NULL)
2291 ReleaseOpenCLMemObject(parametersBuffer);
2292 if (functionKernel != (cl_kernel) NULL)
2293 ReleaseOpenCLKernel(functionKernel);
2294 if (queue != (cl_command_queue) NULL)
2295 ReleaseOpenCLCommandQueue(device,queue);
2296 if (device != (MagickCLDevice) NULL)
2297 ReleaseOpenCLDevice(device);
2298 return(outputReady);
2301MagickPrivate MagickBooleanType AccelerateFunctionImage(Image *image,
2302 const MagickFunction function,
const size_t number_parameters,
2303 const double *parameters,ExceptionInfo *exception)
2311 assert(image != NULL);
2312 assert(exception != (ExceptionInfo *) NULL);
2313 if (IsEventLogging() != MagickFalse)
2314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2316 if (checkAccelerateCondition(image) == MagickFalse)
2317 return(MagickFalse);
2319 clEnv=getOpenCLEnvironment(exception);
2320 if (clEnv == (MagickCLEnv) NULL)
2321 return(MagickFalse);
2323 status=ComputeFunctionImage(image,clEnv,function,number_parameters,
2324 parameters,exception);
2340static MagickBooleanType ComputeGrayscaleImage(Image *image,MagickCLEnv clEnv,
2341 const PixelIntensityMethod method,ExceptionInfo *exception)
2370 assert(image != (Image *) NULL);
2371 assert(image->signature == MagickCoreSignature);
2372 if (IsEventLogging() != MagickFalse)
2373 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2377 grayscaleKernel=NULL;
2378 outputReady=MagickFalse;
2380 device=RequestOpenCLDevice(clEnv);
2381 if (device == (MagickCLDevice) NULL)
2383 queue=AcquireOpenCLCommandQueue(device);
2384 if (queue == (cl_command_queue) NULL)
2386 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
2387 if (imageBuffer == (cl_mem) NULL)
2390 grayscaleKernel=AcquireOpenCLKernel(device,
"Grayscale");
2391 if (grayscaleKernel == (cl_kernel) NULL)
2393 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2394 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2398 number_channels=(cl_uint) image->number_channels;
2399 intensityMethod=(cl_uint) method;
2400 colorspace=(cl_uint) image->colorspace;
2403 status =SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2404 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&number_channels);
2405 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&colorspace);
2406 status|=SetOpenCLKernelArg(grayscaleKernel,i++,
sizeof(cl_uint),&intensityMethod);
2407 if (status != CL_SUCCESS)
2409 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
2410 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
2414 gsize[0]=image->columns;
2415 gsize[1]=image->rows;
2416 outputReady=EnqueueOpenCLKernel(queue,grayscaleKernel,2,
2417 (
const size_t *) NULL,gsize,(
const size_t *) NULL,image,(Image *) NULL,
2418 MagickFalse,exception);
2422 if (imageBuffer != (cl_mem) NULL)
2423 ReleaseOpenCLMemObject(imageBuffer);
2424 if (grayscaleKernel != (cl_kernel) NULL)
2425 ReleaseOpenCLKernel(grayscaleKernel);
2426 if (queue != (cl_command_queue) NULL)
2427 ReleaseOpenCLCommandQueue(device,queue);
2428 if (device != (MagickCLDevice) NULL)
2429 ReleaseOpenCLDevice(device);
2431 return(outputReady);
2434MagickPrivate MagickBooleanType AccelerateGrayscaleImage(Image* image,
2435 const PixelIntensityMethod method,ExceptionInfo *exception)
2443 assert(image != NULL);
2444 assert(exception != (ExceptionInfo *) NULL);
2445 if (IsEventLogging() != MagickFalse)
2446 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2448 if ((checkAccelerateCondition(image) == MagickFalse) ||
2449 (checkPixelIntensity(image,method) == MagickFalse))
2450 return(MagickFalse);
2452 if (image->number_channels < 3)
2453 return(MagickFalse);
2455 if ((GetPixelRedTraits(image) == UndefinedPixelTrait) ||
2456 (GetPixelGreenTraits(image) == UndefinedPixelTrait) ||
2457 (GetPixelBlueTraits(image) == UndefinedPixelTrait))
2458 return(MagickFalse);
2460 clEnv=getOpenCLEnvironment(exception);
2461 if (clEnv == (MagickCLEnv) NULL)
2462 return(MagickFalse);
2464 status=ComputeGrayscaleImage(image,clEnv,method,exception);
2480static Image *ComputeLocalContrastImage(
const Image *image,MagickCLEnv clEnv,
2481 const double radius,
const double strength,ExceptionInfo *exception)
2484 *filteredImage_view,
2502 filteredImageBuffer,
2540 filteredImage_view=NULL;
2542 filteredImageBuffer=NULL;
2543 tempImageBuffer=NULL;
2544 imageKernelBuffer=NULL;
2546 blurColumnKernel=NULL;
2547 outputReady=MagickFalse;
2549 device=RequestOpenCLDevice(clEnv);
2550 if (device == (MagickCLDevice) NULL)
2552 queue=AcquireOpenCLCommandQueue(device);
2553 if (queue == (cl_command_queue) NULL)
2558 image_view=AcquireAuthenticCacheView(image,exception);
2559 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
2560 if (inputPixels == (
const void *) NULL)
2562 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
2569 if (ALIGNED(inputPixels,CLPixelPacket))
2571 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
2575 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
2578 length = image->columns * image->rows;
2579 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2580 if (clStatus != CL_SUCCESS)
2582 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2589 filteredImage = CloneImage(image,0,0,MagickTrue,exception);
2590 assert(filteredImage != NULL);
2591 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
2593 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"CloneImage failed.",
".");
2596 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
2597 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
2598 if (filteredPixels == (
void *) NULL)
2600 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
2604 if (ALIGNED(filteredPixels,CLPixelPacket))
2606 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
2607 hostPtr = filteredPixels;
2611 mem_flags = CL_MEM_WRITE_ONLY;
2616 length = image->columns * image->rows;
2617 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
2618 if (clStatus != CL_SUCCESS)
2620 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2628 length = image->columns * image->rows;
2629 tempImageBuffer = clEnv->library->clCreateBuffer(device->context, CL_MEM_READ_WRITE, length *
sizeof(
float), NULL, &clStatus);
2630 if (clStatus != CL_SUCCESS)
2632 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2639 blurRowKernel = AcquireOpenCLKernel(device,
"LocalContrastBlurRow");
2640 if (blurRowKernel == NULL)
2642 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2646 blurColumnKernel = AcquireOpenCLKernel(device,
"LocalContrastBlurApplyColumn");
2647 if (blurColumnKernel == NULL)
2649 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2655 imageColumns = (
unsigned int) image->columns;
2656 imageRows = (
unsigned int) image->rows;
2658 iRadius = (cl_int) ((image->rows > image->columns ? image->rows : image->columns) * 0.002f * fabs(radius));
2660 passes = (
unsigned int) ((((1.0f * imageRows) * imageColumns * iRadius) + 3999999999) / 4000000000.0f);
2661 passes = (passes < 1) ? 1: passes;
2665 clStatus=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2666 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
2667 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
2668 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(cl_int),(
void *)&iRadius);
2669 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(
unsigned int),(
void *)&imageColumns);
2670 clStatus|=clEnv->library->clSetKernelArg(blurRowKernel,i++,
sizeof(
unsigned int),(
void *)&imageRows);
2672 if (clStatus != CL_SUCCESS)
2674 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2682 for (x = 0; x < (int) passes; ++x) {
2688 gsize[1] = (image->rows + passes - 1) / passes;
2692 goffset[1] = x * gsize[1];
2694 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, blurRowKernel, 2, goffset, gsize, wsize, 0, NULL, &event);
2695 if (clStatus != CL_SUCCESS)
2697 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2700 clEnv->library->clFlush(queue);
2701 RecordProfileData(device,blurRowKernel,event);
2706 cl_float FStrength = (cl_float) strength;
2708 clStatus=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2709 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
2710 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
2711 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&iRadius);
2712 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(cl_float),(
void *)&FStrength);
2713 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&imageColumns);
2714 clStatus|=clEnv->library->clSetKernelArg(blurColumnKernel,i++,
sizeof(
unsigned int),(
void *)&imageRows);
2716 if (clStatus != CL_SUCCESS)
2718 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2726 for (x = 0; x < (int) passes; ++x) {
2731 gsize[0] = ((image->columns + 3) / 4) * 4;
2732 gsize[1] = ((((image->rows + 63) / 64) + (passes + 1)) / passes) * 64;
2736 goffset[1] = x * gsize[1];
2738 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, blurColumnKernel, 2, goffset, gsize, wsize, 0, NULL, &event);
2739 if (clStatus != CL_SUCCESS)
2741 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2744 clEnv->library->clFlush(queue);
2745 RecordProfileData(device,blurColumnKernel,event);
2751 if (ALIGNED(filteredPixels,CLPixelPacket))
2753 length = image->columns * image->rows;
2754 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2758 length = image->columns * image->rows;
2759 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
2761 if (clStatus != CL_SUCCESS)
2763 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
2767 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
2771 image_view=DestroyCacheView(image_view);
2772 if (filteredImage_view != NULL)
2773 filteredImage_view=DestroyCacheView(filteredImage_view);
2775 if (imageBuffer!=NULL)
2776 clEnv->library->clReleaseMemObject(imageBuffer);
2777 if (filteredImageBuffer!=NULL)
2778 clEnv->library->clReleaseMemObject(filteredImageBuffer);
2779 if (tempImageBuffer!=NULL)
2780 clEnv->library->clReleaseMemObject(tempImageBuffer);
2781 if (imageKernelBuffer!=NULL)
2782 clEnv->library->clReleaseMemObject(imageKernelBuffer);
2783 if (blurRowKernel!=NULL)
2784 ReleaseOpenCLKernel(blurRowKernel);
2785 if (blurColumnKernel!=NULL)
2786 ReleaseOpenCLKernel(blurColumnKernel);
2788 ReleaseOpenCLCommandQueue(device, queue);
2790 ReleaseOpenCLDevice(device);
2791 if (outputReady == MagickFalse)
2793 if (filteredImage != NULL)
2795 DestroyImage(filteredImage);
2796 filteredImage = NULL;
2800 return(filteredImage);
2803MagickPrivate Image *AccelerateLocalContrastImage(
const Image *image,
2804 const double radius,
const double strength,ExceptionInfo *exception)
2812 assert(image != NULL);
2813 assert(exception != (ExceptionInfo *) NULL);
2815 if (checkAccelerateConditionRGBA(image) == MagickFalse)
2816 return((Image *) NULL);
2818 clEnv=getOpenCLEnvironment(exception);
2819 if (clEnv == (MagickCLEnv) NULL)
2820 return((Image *) NULL);
2822 filteredImage=ComputeLocalContrastImage(image,clEnv,radius,strength,
2824 return(filteredImage);
2839static MagickBooleanType ComputeModulateImage(Image *image,MagickCLEnv clEnv,
2840 const double percent_brightness,
const double percent_hue,
2841 const double percent_saturation,
const ColorspaceType colorspace,
2842 ExceptionInfo *exception)
2886 assert(image != (Image *) NULL);
2887 assert(image->signature == MagickCoreSignature);
2888 if (IsEventLogging() != MagickFalse)
2889 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2895 modulateKernel=NULL;
2896 outputReady=MagickFalse;
2901 device=RequestOpenCLDevice(clEnv);
2902 if (device == (MagickCLDevice) NULL)
2904 queue=AcquireOpenCLCommandQueue(device);
2905 if (queue == (cl_command_queue) NULL)
2912 image_view=AcquireAuthenticCacheView(image,exception);
2913 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,image->rows,exception);
2914 if (inputPixels == (
void *) NULL)
2916 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),CacheWarning,
"UnableToReadPixelCache.",
"`%s'",image->filename);
2924 if (ALIGNED(inputPixels,CLPixelPacket))
2926 mem_flags = CL_MEM_READ_WRITE|CL_MEM_USE_HOST_PTR;
2930 mem_flags = CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR;
2933 length = image->columns * image->rows;
2934 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags, length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
2935 if (clStatus != CL_SUCCESS)
2937 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clCreateBuffer failed.",
".");
2941 modulateKernel = AcquireOpenCLKernel(device,
"Modulate");
2942 if (modulateKernel == NULL)
2944 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
2948 bright=(cl_float) percent_brightness;
2949 hue=(cl_float) percent_hue;
2950 saturation=(cl_float) percent_saturation;
2951 color=(cl_int) colorspace;
2954 clStatus=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
2955 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&bright);
2956 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&hue);
2957 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&saturation);
2958 clStatus|=clEnv->library->clSetKernelArg(modulateKernel,i++,
sizeof(cl_float),&color);
2959 if (clStatus != CL_SUCCESS)
2961 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
2966 size_t global_work_size[2];
2967 global_work_size[0] = image->columns;
2968 global_work_size[1] = image->rows;
2970 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, modulateKernel, 2, NULL, global_work_size, NULL, 0, NULL, &event);
2971 if (clStatus != CL_SUCCESS)
2973 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"clEnv->library->clEnqueueNDRangeKernel failed.",
".");
2976 RecordProfileData(device,modulateKernel,event);
2979 if (ALIGNED(inputPixels,CLPixelPacket))
2981 length = image->columns * image->rows;
2982 clEnv->library->clEnqueueMapBuffer(queue, imageBuffer, CL_TRUE, CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL, NULL, &clStatus);
2986 length = image->columns * image->rows;
2987 clStatus = clEnv->library->clEnqueueReadBuffer(queue, imageBuffer, CL_TRUE, 0, length *
sizeof(CLPixelPacket), inputPixels, 0, NULL, NULL);
2989 if (clStatus != CL_SUCCESS)
2991 (void) OpenCLThrowMagickException(device,exception, GetMagickModule(), ResourceLimitWarning,
"Reading output image from CL buffer failed.",
".");
2995 outputReady=SyncCacheViewAuthenticPixels(image_view,exception);
2999 image_view=DestroyCacheView(image_view);
3001 if (imageBuffer!=NULL)
3002 clEnv->library->clReleaseMemObject(imageBuffer);
3003 if (modulateKernel!=NULL)
3004 ReleaseOpenCLKernel(modulateKernel);
3006 ReleaseOpenCLCommandQueue(device,queue);
3008 ReleaseOpenCLDevice(device);
3014MagickPrivate MagickBooleanType AccelerateModulateImage(Image *image,
3015 const double percent_brightness,
const double percent_hue,
3016 const double percent_saturation,
const ColorspaceType colorspace,
3017 ExceptionInfo *exception)
3025 assert(image != NULL);
3026 assert(exception != (ExceptionInfo *) NULL);
3027 if (IsEventLogging() != MagickFalse)
3028 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
3030 if (checkAccelerateConditionRGBA(image) == MagickFalse)
3031 return(MagickFalse);
3033 if ((colorspace != HSLColorspace) && (colorspace != UndefinedColorspace))
3034 return(MagickFalse);
3036 clEnv=getOpenCLEnvironment(exception);
3037 if (clEnv == (MagickCLEnv) NULL)
3038 return(MagickFalse);
3040 status=ComputeModulateImage(image,clEnv,percent_brightness,percent_hue,
3041 percent_saturation,colorspace,exception);
3057static Image* ComputeMotionBlurImage(
const Image *image,MagickCLEnv clEnv,
3058 const double *kernel,
const size_t width,
const OffsetInfo *offset,
3059 ExceptionInfo *exception)
3062 *filteredImage_view,
3072 channel_mask=get32BitChannelValue(image->channel_mask),
3082 filteredImageBuffer,
3112 global_work_size[2],
3126 assert(image != (Image *) NULL);
3127 assert(image->signature == MagickCoreSignature);
3128 if (IsEventLogging() != MagickFalse)
3129 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
3134 filteredImage_view=NULL;
3136 filteredImageBuffer=NULL;
3137 imageKernelBuffer=NULL;
3138 motionBlurKernel=NULL;
3139 outputReady=MagickFalse;
3141 device=RequestOpenCLDevice(clEnv);
3142 if (device == (MagickCLDevice) NULL)
3147 image_view=AcquireAuthenticCacheView(image,exception);
3148 inputPixels=GetCacheViewAuthenticPixels(image_view,0,0,image->columns,
3149 image->rows,exception);
3150 if (inputPixels == (
const void *) NULL)
3152 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
3153 "UnableToReadPixelCache.",
"`%s'",image->filename);
3162 if (ALIGNED(inputPixels,CLPixelPacket))
3164 mem_flags = CL_MEM_READ_ONLY|CL_MEM_USE_HOST_PTR;
3168 mem_flags = CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR;
3173 length = image->columns * image->rows;
3174 imageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags,
3175 length *
sizeof(CLPixelPacket), (
void*)inputPixels, &clStatus);
3176 if (clStatus != CL_SUCCESS)
3178 (void) ThrowMagickException(exception, GetMagickModule(),
3179 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3184 filteredImage = CloneImage(image,image->columns,image->rows,
3185 MagickTrue,exception);
3186 assert(filteredImage != NULL);
3187 if (SetImageStorageClass(filteredImage,DirectClass,exception) != MagickTrue)
3189 (void) ThrowMagickException(exception, GetMagickModule(),
3190 ResourceLimitError,
"CloneImage failed.",
".");
3193 filteredImage_view=AcquireAuthenticCacheView(filteredImage,exception);
3194 filteredPixels=GetCacheViewAuthenticPixels(filteredImage_view,0,0,filteredImage->columns,filteredImage->rows,exception);
3195 if (filteredPixels == (
void *) NULL)
3197 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
3198 "UnableToReadPixelCache.",
"`%s'",filteredImage->filename);
3202 if (ALIGNED(filteredPixels,CLPixelPacket))
3204 mem_flags = CL_MEM_WRITE_ONLY|CL_MEM_USE_HOST_PTR;
3205 hostPtr = filteredPixels;
3209 mem_flags = CL_MEM_WRITE_ONLY;
3215 length = image->columns * image->rows;
3216 filteredImageBuffer = clEnv->library->clCreateBuffer(device->context, mem_flags,
3217 length *
sizeof(CLPixelPacket), hostPtr, &clStatus);
3218 if (clStatus != CL_SUCCESS)
3220 (void) ThrowMagickException(exception, GetMagickModule(),
3221 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3226 imageKernelBuffer = clEnv->library->clCreateBuffer(device->context,
3227 CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, width *
sizeof(
float), NULL,
3229 if (clStatus != CL_SUCCESS)
3231 (void) ThrowMagickException(exception, GetMagickModule(),
3232 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3236 queue=AcquireOpenCLCommandQueue(device);
3237 if (queue == (cl_command_queue) NULL)
3239 kernelBufferPtr = (
float*)clEnv->library->clEnqueueMapBuffer(queue, imageKernelBuffer,
3240 CL_TRUE, CL_MAP_WRITE, 0, width *
sizeof(
float), 0, NULL, NULL, &clStatus);
3241 if (clStatus != CL_SUCCESS)
3243 (void) ThrowMagickException(exception, GetMagickModule(),
3244 ResourceLimitError,
"clEnv->library->clEnqueueMapBuffer failed.",
".");
3247 for (i = 0; i < width; i++)
3249 kernelBufferPtr[i] = (float) kernel[i];
3251 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, imageKernelBuffer, kernelBufferPtr,
3253 if (clStatus != CL_SUCCESS)
3255 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3256 "clEnv->library->clEnqueueUnmapMemObject failed.",
".");
3260 offsetBuffer = clEnv->library->clCreateBuffer(device->context,
3261 CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, width *
sizeof(cl_int2), NULL,
3263 if (clStatus != CL_SUCCESS)
3265 (void) ThrowMagickException(exception, GetMagickModule(),
3266 ResourceLimitError,
"clEnv->library->clCreateBuffer failed.",
".");
3270 offsetBufferPtr = (
int*)clEnv->library->clEnqueueMapBuffer(queue, offsetBuffer, CL_TRUE,
3271 CL_MAP_WRITE, 0, width *
sizeof(cl_int2), 0, NULL, NULL, &clStatus);
3272 if (clStatus != CL_SUCCESS)
3274 (void) ThrowMagickException(exception, GetMagickModule(),
3275 ResourceLimitError,
"clEnv->library->clEnqueueMapBuffer failed.",
".");
3278 for (i = 0; i < width; i++)
3280 offsetBufferPtr[2*i] = (int)offset[i].x;
3281 offsetBufferPtr[2*i+1] = (int)offset[i].y;
3283 clStatus = clEnv->library->clEnqueueUnmapMemObject(queue, offsetBuffer, offsetBufferPtr, 0,
3285 if (clStatus != CL_SUCCESS)
3287 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3288 "clEnv->library->clEnqueueUnmapMemObject failed.",
".");
3296 motionBlurKernel = AcquireOpenCLKernel(device,
"MotionBlur");
3297 if (motionBlurKernel == NULL)
3299 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3300 "AcquireOpenCLKernel failed.",
".");
3308 clStatus=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3309 (
void *)&imageBuffer);
3310 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3311 (
void *)&filteredImageBuffer);
3312 imageWidth = (
unsigned int) image->columns;
3313 imageHeight = (
unsigned int) image->rows;
3314 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3316 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3318 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3319 (
void *)&imageKernelBuffer);
3320 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int),
3322 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_mem),
3323 (
void *)&offsetBuffer);
3325 GetPixelInfo(image,&bias);
3326 biasPixel.s[0] = (cl_float) bias.red;
3327 biasPixel.s[1] = (cl_float) bias.green;
3328 biasPixel.s[2] = (cl_float) bias.blue;
3329 biasPixel.s[3] = (cl_float) bias.alpha;
3330 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_float4), &biasPixel);
3332 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(cl_int),&channel_mask);
3333 matte = (image->alpha_trait > CopyPixelTrait)?1:0;
3334 clStatus|=clEnv->library->clSetKernelArg(motionBlurKernel,i++,
sizeof(
unsigned int), &matte);
3335 if (clStatus != CL_SUCCESS)
3337 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3338 "clEnv->library->clSetKernelArg failed.",
".");
3345 local_work_size[0] = 16;
3346 local_work_size[1] = 16;
3347 global_work_size[0] = (size_t)padGlobalWorkgroupSizeToLocalWorkgroupSize(
3348 (
unsigned int) image->columns,(
unsigned int) local_work_size[0]);
3349 global_work_size[1] = (size_t)padGlobalWorkgroupSizeToLocalWorkgroupSize(
3350 (
unsigned int) image->rows,(
unsigned int) local_work_size[1]);
3351 clStatus = clEnv->library->clEnqueueNDRangeKernel(queue, motionBlurKernel, 2, NULL,
3352 global_work_size, local_work_size, 0, NULL, &event);
3354 if (clStatus != CL_SUCCESS)
3356 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3357 "clEnv->library->clEnqueueNDRangeKernel failed.",
".");
3360 RecordProfileData(device,motionBlurKernel,event);
3362 if (ALIGNED(filteredPixels,CLPixelPacket))
3364 length = image->columns * image->rows;
3365 clEnv->library->clEnqueueMapBuffer(queue, filteredImageBuffer, CL_TRUE,
3366 CL_MAP_READ|CL_MAP_WRITE, 0, length *
sizeof(CLPixelPacket), 0, NULL,
3371 length = image->columns * image->rows;
3372 clStatus = clEnv->library->clEnqueueReadBuffer(queue, filteredImageBuffer, CL_TRUE, 0,
3373 length *
sizeof(CLPixelPacket), filteredPixels, 0, NULL, NULL);
3375 if (clStatus != CL_SUCCESS)
3377 (void) ThrowMagickException(exception, GetMagickModule(), ModuleFatalError,
3378 "Reading output image from CL buffer failed.",
".");
3381 outputReady=SyncCacheViewAuthenticPixels(filteredImage_view,exception);
3385 image_view=DestroyCacheView(image_view);
3386 if (filteredImage_view != NULL)
3387 filteredImage_view=DestroyCacheView(filteredImage_view);
3389 if (filteredImageBuffer!=NULL)
3390 clEnv->library->clReleaseMemObject(filteredImageBuffer);
3391 if (imageBuffer!=NULL)
3392 clEnv->library->clReleaseMemObject(imageBuffer);
3393 if (imageKernelBuffer!=NULL)
3394 clEnv->library->clReleaseMemObject(imageKernelBuffer);
3395 if (motionBlurKernel!=NULL)
3396 ReleaseOpenCLKernel(motionBlurKernel);
3398 ReleaseOpenCLCommandQueue(device,queue);
3400 ReleaseOpenCLDevice(device);
3401 if (outputReady == MagickFalse && filteredImage != NULL)
3402 filteredImage=DestroyImage(filteredImage);
3404 return(filteredImage);
3407MagickPrivate Image *AccelerateMotionBlurImage(
const Image *image,
3408 const double* kernel,
const size_t width,
const OffsetInfo *offset,
3409 ExceptionInfo *exception)
3417 assert(image != NULL);
3418 assert(kernel != (
double *) NULL);
3419 assert(offset != (OffsetInfo *) NULL);
3420 assert(exception != (ExceptionInfo *) NULL);
3422 if (checkAccelerateConditionRGBA(image) == MagickFalse)
3423 return((Image *) NULL);
3425 clEnv=getOpenCLEnvironment(exception);
3426 if (clEnv == (MagickCLEnv) NULL)
3427 return((Image *) NULL);
3429 filteredImage=ComputeMotionBlurImage(image,clEnv,kernel,width,offset,
3431 return(filteredImage);
3446static MagickBooleanType resizeHorizontalFilter(MagickCLDevice device,
3447 cl_command_queue queue,
const Image *image,Image *filteredImage,
3448 cl_mem imageBuffer,cl_uint number_channels,cl_uint columns,cl_uint rows,
3449 cl_mem resizedImageBuffer,cl_uint resizedColumns,cl_uint resizedRows,
3450 const ResizeFilter *resizeFilter,cl_mem resizeFilterCubicCoefficients,
3451 const float xFactor,ExceptionInfo *exception)
3463 workgroupSize = 256;
3467 resizeFilterSupport,
3468 resizeFilterWindowSupport,
3482 gammaAccumulatorLocalMemorySize,
3484 imageCacheLocalMemorySize,
3485 pixelAccumulatorLocalMemorySize,
3487 totalLocalMemorySize,
3488 weightAccumulatorLocalMemorySize;
3494 horizontalKernel=NULL;
3495 outputReady=MagickFalse;
3500 scale=(float) MAGICK_MAX(1.0/xFactor+MagickEpsilon,1.0);
3501 support=scale*(float) GetResizeFilterSupport(resizeFilter);
3508 support=(float) 0.5;
3511 scale=(float) MagickSafeReciprocal(scale);
3513 if (resizedColumns < workgroupSize)
3516 pixelPerWorkgroup=32;
3520 chunkSize=workgroupSize;
3521 pixelPerWorkgroup=workgroupSize;
3524DisableMSCWarning(4127)
3529 numCachedPixels=(int) ceil((pixelPerWorkgroup-1)/xFactor+2*support);
3530 imageCacheLocalMemorySize=numCachedPixels*
sizeof(CLQuantum)*
3532 totalLocalMemorySize=imageCacheLocalMemorySize;
3535 pixelAccumulatorLocalMemorySize=chunkSize*
sizeof(cl_float4);
3536 totalLocalMemorySize+=pixelAccumulatorLocalMemorySize;
3539 weightAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3540 totalLocalMemorySize+=weightAccumulatorLocalMemorySize;
3543 if ((number_channels == 4) || (number_channels == 2))
3544 gammaAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3546 gammaAccumulatorLocalMemorySize=
sizeof(float);
3547 totalLocalMemorySize+=gammaAccumulatorLocalMemorySize;
3549 if (totalLocalMemorySize <= device->local_memory_size)
3553 pixelPerWorkgroup=pixelPerWorkgroup/2;
3554 chunkSize=chunkSize/2;
3555 if ((pixelPerWorkgroup == 0) || (chunkSize == 0))
3563 resizeFilterType=(int)GetResizeFilterWeightingType(resizeFilter);
3564 resizeWindowType=(int)GetResizeFilterWindowWeightingType(resizeFilter);
3566 horizontalKernel=AcquireOpenCLKernel(device,
"ResizeHorizontalFilter");
3567 if (horizontalKernel == (cl_kernel) NULL)
3569 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3570 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
3574 resizeFilterScale=(float) GetResizeFilterScale(resizeFilter);
3575 resizeFilterSupport=(float) GetResizeFilterSupport(resizeFilter);
3576 resizeFilterWindowSupport=(float) GetResizeFilterWindowSupport(resizeFilter);
3577 resizeFilterBlur=(float) GetResizeFilterBlur(resizeFilter);
3580 status =SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&imageBuffer);
3581 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&number_channels);
3582 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&columns);
3583 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&rows);
3584 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&resizedImageBuffer);
3585 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&resizedColumns);
3586 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_uint),(
void*)&resizedRows);
3587 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&xFactor);
3588 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),(
void*)&resizeFilterType);
3589 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),(
void*)&resizeWindowType);
3590 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(cl_mem),(
void*)&resizeFilterCubicCoefficients);
3591 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterScale);
3592 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterSupport);
3593 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterWindowSupport);
3594 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
float),(
void*)&resizeFilterBlur);
3595 status|=SetOpenCLKernelArg(horizontalKernel,i++,imageCacheLocalMemorySize,NULL);
3596 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
int),&numCachedPixels);
3597 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
unsigned int),&pixelPerWorkgroup);
3598 status|=SetOpenCLKernelArg(horizontalKernel,i++,
sizeof(
unsigned int),&chunkSize);
3599 status|=SetOpenCLKernelArg(horizontalKernel,i++,pixelAccumulatorLocalMemorySize,NULL);
3600 status|=SetOpenCLKernelArg(horizontalKernel,i++,weightAccumulatorLocalMemorySize,NULL);
3601 status|=SetOpenCLKernelArg(horizontalKernel,i++,gammaAccumulatorLocalMemorySize,NULL);
3603 if (status != CL_SUCCESS)
3605 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3606 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
3610 gsize[0]=(resizedColumns+pixelPerWorkgroup-1)/pixelPerWorkgroup*
3612 gsize[1]=resizedRows;
3613 lsize[0]=workgroupSize;
3615 outputReady=EnqueueOpenCLKernel(queue,horizontalKernel,2,
3616 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
3621 if (horizontalKernel != (cl_kernel) NULL)
3622 ReleaseOpenCLKernel(horizontalKernel);
3624 return(outputReady);
3627static MagickBooleanType resizeVerticalFilter(MagickCLDevice device,
3628 cl_command_queue queue,
const Image *image,Image * filteredImage,
3629 cl_mem imageBuffer,cl_uint number_channels,cl_uint columns,cl_uint rows,
3630 cl_mem resizedImageBuffer,cl_uint resizedColumns,cl_uint resizedRows,
3631 const ResizeFilter *resizeFilter,cl_mem resizeFilterCubicCoefficients,
3632 const float yFactor,ExceptionInfo *exception)
3641 workgroupSize = 256;
3645 resizeFilterSupport,
3646 resizeFilterWindowSupport,
3660 gammaAccumulatorLocalMemorySize,
3663 imageCacheLocalMemorySize,
3664 pixelAccumulatorLocalMemorySize,
3666 totalLocalMemorySize,
3667 weightAccumulatorLocalMemorySize;
3673 verticalKernel=NULL;
3674 outputReady=MagickFalse;
3679 scale=(float) MAGICK_MAX(1.0/yFactor+MagickEpsilon,1.0);
3680 support=scale*(float) GetResizeFilterSupport(resizeFilter);
3687 support=(float) 0.5;
3690 scale=(float) MagickSafeReciprocal(scale);
3692 if (resizedRows < workgroupSize)
3695 pixelPerWorkgroup=32;
3699 chunkSize=workgroupSize;
3700 pixelPerWorkgroup=workgroupSize;
3703DisableMSCWarning(4127)
3708 numCachedPixels=(int)ceil((pixelPerWorkgroup-1)/yFactor+2*support);
3709 imageCacheLocalMemorySize=numCachedPixels*
sizeof(CLQuantum)*
3711 totalLocalMemorySize=imageCacheLocalMemorySize;
3714 pixelAccumulatorLocalMemorySize=chunkSize*
sizeof(cl_float4);
3715 totalLocalMemorySize+=pixelAccumulatorLocalMemorySize;
3718 weightAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3719 totalLocalMemorySize+=weightAccumulatorLocalMemorySize;
3722 if ((number_channels == 4) || (number_channels == 2))
3723 gammaAccumulatorLocalMemorySize=chunkSize*
sizeof(float);
3725 gammaAccumulatorLocalMemorySize=
sizeof(float);
3726 totalLocalMemorySize+=gammaAccumulatorLocalMemorySize;
3728 if (totalLocalMemorySize <= device->local_memory_size)
3732 pixelPerWorkgroup=pixelPerWorkgroup/2;
3733 chunkSize=chunkSize/2;
3734 if ((pixelPerWorkgroup == 0) || (chunkSize == 0))
3742 resizeFilterType=(int)GetResizeFilterWeightingType(resizeFilter);
3743 resizeWindowType=(int)GetResizeFilterWindowWeightingType(resizeFilter);
3745 verticalKernel=AcquireOpenCLKernel(device,
"ResizeVerticalFilter");
3746 if (verticalKernel == (cl_kernel) NULL)
3748 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3749 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
3753 resizeFilterScale=(float) GetResizeFilterScale(resizeFilter);
3754 resizeFilterSupport=(float) GetResizeFilterSupport(resizeFilter);
3755 resizeFilterBlur=(float) GetResizeFilterBlur(resizeFilter);
3756 resizeFilterWindowSupport=(float) GetResizeFilterWindowSupport(resizeFilter);
3759 status =SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&imageBuffer);
3760 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&number_channels);
3761 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&columns);
3762 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&rows);
3763 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&resizedImageBuffer);
3764 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&resizedColumns);
3765 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_uint),(
void*)&resizedRows);
3766 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&yFactor);
3767 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int),(
void*)&resizeFilterType);
3768 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int),(
void*)&resizeWindowType);
3769 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(cl_mem),(
void*)&resizeFilterCubicCoefficients);
3770 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterScale);
3771 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterSupport);
3772 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterWindowSupport);
3773 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
float),(
void*)&resizeFilterBlur);
3774 status|=SetOpenCLKernelArg(verticalKernel,i++,imageCacheLocalMemorySize, NULL);
3775 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
int), &numCachedPixels);
3776 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
unsigned int), &pixelPerWorkgroup);
3777 status|=SetOpenCLKernelArg(verticalKernel,i++,
sizeof(
unsigned int), &chunkSize);
3778 status|=SetOpenCLKernelArg(verticalKernel,i++,pixelAccumulatorLocalMemorySize, NULL);
3779 status|=SetOpenCLKernelArg(verticalKernel,i++,weightAccumulatorLocalMemorySize, NULL);
3780 status|=SetOpenCLKernelArg(verticalKernel,i++,gammaAccumulatorLocalMemorySize, NULL);
3782 if (status != CL_SUCCESS)
3784 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3785 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
3789 gsize[0]=resizedColumns;
3790 gsize[1]=(resizedRows+pixelPerWorkgroup-1)/pixelPerWorkgroup*
3793 lsize[1]=workgroupSize;
3794 outputReady=EnqueueOpenCLKernel(queue,verticalKernel,2,(
const size_t *) NULL,
3795 gsize,lsize,image,filteredImage,MagickFalse,exception);
3799 if (verticalKernel != (cl_kernel) NULL)
3800 ReleaseOpenCLKernel(verticalKernel);
3802 return(outputReady);
3805static Image *ComputeResizeImage(
const Image* image,MagickCLEnv clEnv,
3806 const size_t resizedColumns,
const size_t resizedRows,
3807 const ResizeFilter *resizeFilter,ExceptionInfo *exception)
3813 cubicCoefficientsBuffer,
3814 filteredImageBuffer,
3822 *resizeFilterCoefficient;
3825 coefficientBuffer[7],
3845 filteredImageBuffer=NULL;
3846 tempImageBuffer=NULL;
3847 cubicCoefficientsBuffer=NULL;
3848 outputReady=MagickFalse;
3850 device=RequestOpenCLDevice(clEnv);
3851 if (device == (MagickCLDevice) NULL)
3853 queue=AcquireOpenCLCommandQueue(device);
3854 if (queue == (cl_command_queue) NULL)
3856 filteredImage=CloneImage(image,resizedColumns,resizedRows,MagickTrue,
3858 if (filteredImage == (Image *) NULL)
3860 if (filteredImage->number_channels != image->number_channels)
3862 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
3863 if (imageBuffer == (cl_mem) NULL)
3865 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
3866 if (filteredImageBuffer == (cl_mem) NULL)
3869 resizeFilterCoefficient=GetResizeFilterCoefficient(resizeFilter);
3870 for (i = 0; i < 7; i++)
3871 coefficientBuffer[i]=(
float) resizeFilterCoefficient[i];
3872 cubicCoefficientsBuffer=CreateOpenCLBuffer(device,CL_MEM_COPY_HOST_PTR |
3873 CL_MEM_READ_ONLY,
sizeof(coefficientBuffer),&coefficientBuffer);
3874 if (cubicCoefficientsBuffer == (cl_mem) NULL)
3876 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3877 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3881 number_channels=(cl_uint) image->number_channels;
3882 xFactor=(float) resizedColumns/(
float) image->columns;
3883 yFactor=(float) resizedRows/(
float) image->rows;
3884 if (xFactor > yFactor)
3886 length=resizedColumns*image->rows*number_channels;
3887 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
3888 sizeof(CLQuantum),(
void *) NULL);
3889 if (tempImageBuffer == (cl_mem) NULL)
3891 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3892 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3896 outputReady=resizeHorizontalFilter(device,queue,image,filteredImage,
3897 imageBuffer,number_channels,(cl_uint) image->columns,
3898 (cl_uint) image->rows,tempImageBuffer,(cl_uint) resizedColumns,
3899 (cl_uint) image->rows,resizeFilter,cubicCoefficientsBuffer,xFactor,
3901 if (outputReady == MagickFalse)
3904 outputReady=resizeVerticalFilter(device,queue,image,filteredImage,
3905 tempImageBuffer,number_channels,(cl_uint) resizedColumns,
3906 (cl_uint) image->rows,filteredImageBuffer,(cl_uint) resizedColumns,
3907 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,yFactor,
3909 if (outputReady == MagickFalse)
3914 length=image->columns*resizedRows*number_channels;
3915 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
3916 sizeof(CLQuantum),(
void *) NULL);
3917 if (tempImageBuffer == (cl_mem) NULL)
3919 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
3920 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
3924 outputReady=resizeVerticalFilter(device,queue,image,filteredImage,
3925 imageBuffer,number_channels,(cl_uint) image->columns,
3926 (cl_int) image->rows,tempImageBuffer,(cl_uint) image->columns,
3927 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,yFactor,
3929 if (outputReady == MagickFalse)
3932 outputReady=resizeHorizontalFilter(device,queue,image,filteredImage,
3933 tempImageBuffer,number_channels,(cl_uint) image->columns,
3934 (cl_uint) resizedRows,filteredImageBuffer,(cl_uint) resizedColumns,
3935 (cl_uint) resizedRows,resizeFilter,cubicCoefficientsBuffer,xFactor,
3937 if (outputReady == MagickFalse)
3943 if (imageBuffer != (cl_mem) NULL)
3944 ReleaseOpenCLMemObject(imageBuffer);
3945 if (filteredImageBuffer != (cl_mem) NULL)
3946 ReleaseOpenCLMemObject(filteredImageBuffer);
3947 if (tempImageBuffer != (cl_mem) NULL)
3948 ReleaseOpenCLMemObject(tempImageBuffer);
3949 if (cubicCoefficientsBuffer != (cl_mem) NULL)
3950 ReleaseOpenCLMemObject(cubicCoefficientsBuffer);
3951 if (queue != (cl_command_queue) NULL)
3952 ReleaseOpenCLCommandQueue(device,queue);
3953 if (device != (MagickCLDevice) NULL)
3954 ReleaseOpenCLDevice(device);
3955 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
3956 filteredImage=DestroyImage(filteredImage);
3958 return(filteredImage);
3961static MagickBooleanType gpuSupportedResizeWeighting(
3962 ResizeWeightingFunctionType f)
3969 if (supportedResizeWeighting[i] == LastWeightingFunction)
3971 if (supportedResizeWeighting[i] == f)
3974 return(MagickFalse);
3977MagickPrivate Image *AccelerateResizeImage(
const Image *image,
3978 const size_t resizedColumns,
const size_t resizedRows,
3979 const ResizeFilter *resizeFilter,ExceptionInfo *exception)
3987 assert(image != NULL);
3988 assert(exception != (ExceptionInfo *) NULL);
3990 if (checkAccelerateCondition(image) == MagickFalse)
3991 return((Image *) NULL);
3993 if ((gpuSupportedResizeWeighting(GetResizeFilterWeightingType(
3994 resizeFilter)) == MagickFalse) ||
3995 (gpuSupportedResizeWeighting(GetResizeFilterWindowWeightingType(
3996 resizeFilter)) == MagickFalse))
3997 return((Image *) NULL);
3999 clEnv=getOpenCLEnvironment(exception);
4000 if (clEnv == (MagickCLEnv) NULL)
4001 return((Image *) NULL);
4003 filteredImage=ComputeResizeImage(image,clEnv,resizedColumns,resizedRows,
4004 resizeFilter,exception);
4005 return(filteredImage);
4020static Image* ComputeRotationalBlurImage(
const Image *image,MagickCLEnv clEnv,
4021 const double angle,ExceptionInfo *exception)
4030 channel_mask=get32BitChannelValue(image->channel_mask),
4035 filteredImageBuffer,
4040 rotationalBlurKernel;
4066 assert(image != (Image *) NULL);
4067 assert(image->signature == MagickCoreSignature);
4068 if (IsEventLogging() != MagickFalse)
4069 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
4074 filteredImageBuffer=NULL;
4075 sinThetaBuffer=NULL;
4076 cosThetaBuffer=NULL;
4077 rotationalBlurKernel=NULL;
4078 outputReady=MagickFalse;
4080 device=RequestOpenCLDevice(clEnv);
4081 if (device == (MagickCLDevice) NULL)
4083 queue=AcquireOpenCLCommandQueue(device);
4084 if (queue == (cl_command_queue) NULL)
4086 filteredImage=cloneImage(image,exception);
4087 if (filteredImage == (Image *) NULL)
4089 if (filteredImage->number_channels != image->number_channels)
4091 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4092 if (imageBuffer == (cl_mem) NULL)
4094 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4095 if (filteredImageBuffer == (cl_mem) NULL)
4098 blurCenter.x=(cl_float) ((image->columns-1)/2.0);
4099 blurCenter.y=(cl_float) ((image->rows-1)/2.0);
4100 blurRadius=(float) hypot(blurCenter.x,blurCenter.y);
4101 cossin_theta_size=(
unsigned int) fabs(4.0*DegreesToRadians(angle)*sqrt(
4102 (
double) blurRadius)+2UL);
4104 cosThetaPtr=(
float *) AcquireQuantumMemory(cossin_theta_size,
sizeof(
float));
4105 if (cosThetaPtr == (
float *) NULL)
4107 sinThetaPtr=(
float *) AcquireQuantumMemory(cossin_theta_size,
sizeof(
float));
4108 if (sinThetaPtr == (
float *) NULL)
4110 cosThetaPtr=(
float *) RelinquishMagickMemory(cosThetaPtr);
4114 theta=(float) (DegreesToRadians(angle)/(
double) (cossin_theta_size-1));
4115 offset=theta*(float) ((cossin_theta_size-1)/2.0);
4116 for (i=0; i < (size_t) cossin_theta_size; i++)
4118 cosThetaPtr[i]=(float)cos((
double) (theta*i-offset));
4119 sinThetaPtr[i]=(float)sin((
double) (theta*i-offset));
4122 sinThetaBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
4123 CL_MEM_COPY_HOST_PTR,cossin_theta_size*
sizeof(
float),sinThetaPtr);
4124 sinThetaPtr=(
float *) RelinquishMagickMemory(sinThetaPtr);
4125 cosThetaBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_ONLY |
4126 CL_MEM_COPY_HOST_PTR,cossin_theta_size*
sizeof(
float),cosThetaPtr);
4127 cosThetaPtr=(
float *) RelinquishMagickMemory(cosThetaPtr);
4128 if ((sinThetaBuffer == (cl_mem) NULL) || (cosThetaBuffer == (cl_mem) NULL))
4130 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4131 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
4135 rotationalBlurKernel=AcquireOpenCLKernel(device,
"RotationalBlur");
4136 if (rotationalBlurKernel == (cl_kernel) NULL)
4138 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4139 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4143 number_channels=(cl_uint) image->number_channels;
4146 status =SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4147 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_uint),&number_channels);
4148 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_int),&channel_mask);
4149 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_float2), &blurCenter);
4150 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&cosThetaBuffer);
4151 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&sinThetaBuffer);
4152 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_uint), &cossin_theta_size);
4153 status|=SetOpenCLKernelArg(rotationalBlurKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4154 if (status != CL_SUCCESS)
4156 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4157 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4161 gsize[0]=image->columns;
4162 gsize[1]=image->rows;
4163 outputReady=EnqueueOpenCLKernel(queue,rotationalBlurKernel,2,
4164 (
const size_t *) NULL,gsize,(
const size_t *) NULL,image,filteredImage,
4165 MagickFalse,exception);
4169 if (imageBuffer != (cl_mem) NULL)
4170 ReleaseOpenCLMemObject(imageBuffer);
4171 if (filteredImageBuffer != (cl_mem) NULL)
4172 ReleaseOpenCLMemObject(filteredImageBuffer);
4173 if (sinThetaBuffer != (cl_mem) NULL)
4174 ReleaseOpenCLMemObject(sinThetaBuffer);
4175 if (cosThetaBuffer != (cl_mem) NULL)
4176 ReleaseOpenCLMemObject(cosThetaBuffer);
4177 if (rotationalBlurKernel != (cl_kernel) NULL)
4178 ReleaseOpenCLKernel(rotationalBlurKernel);
4179 if (queue != (cl_command_queue) NULL)
4180 ReleaseOpenCLCommandQueue(device,queue);
4181 if (device != (MagickCLDevice) NULL)
4182 ReleaseOpenCLDevice(device);
4183 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
4184 filteredImage=DestroyImage(filteredImage);
4186 return(filteredImage);
4189MagickPrivate Image* AccelerateRotationalBlurImage(
const Image *image,
4190 const double angle,ExceptionInfo *exception)
4198 assert(image != NULL);
4199 assert(exception != (ExceptionInfo *) NULL);
4200 if (IsEventLogging() != MagickFalse)
4201 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
4203 if (checkAccelerateCondition(image) == MagickFalse)
4204 return((Image *) NULL);
4206 clEnv=getOpenCLEnvironment(exception);
4207 if (clEnv == (MagickCLEnv) NULL)
4208 return((Image *) NULL);
4210 filteredImage=ComputeRotationalBlurImage(image,clEnv,angle,exception);
4211 return filteredImage;
4226static Image *ComputeUnsharpMaskImage(
const Image *image,MagickCLEnv clEnv,
4227 const double radius,
const double sigma,
const double gain,
4228 const double threshold,ExceptionInfo *exception)
4234 channel_mask=get32BitChannelValue(image->channel_mask),
4239 unsharpMaskBlurColumnKernel;
4242 filteredImageBuffer,
4278 filteredImageBuffer=NULL;
4279 tempImageBuffer=NULL;
4280 imageKernelBuffer=NULL;
4282 unsharpMaskBlurColumnKernel=NULL;
4283 outputReady=MagickFalse;
4285 device=RequestOpenCLDevice(clEnv);
4286 if (device == (MagickCLDevice) NULL)
4288 queue=AcquireOpenCLCommandQueue(device);
4289 if (queue == (cl_command_queue) NULL)
4291 filteredImage=cloneImage(image,exception);
4292 if (filteredImage == (Image *) NULL)
4294 if (filteredImage->number_channels != image->number_channels)
4296 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4297 if (imageBuffer == (cl_mem) NULL)
4299 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4300 if (filteredImageBuffer == (cl_mem) NULL)
4303 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
4306 length=image->columns*image->rows;
4307 tempImageBuffer=CreateOpenCLBuffer(device,CL_MEM_READ_WRITE,length*
4308 sizeof(cl_float4),NULL);
4309 if (tempImageBuffer == (cl_mem) NULL)
4311 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4312 ResourceLimitWarning,
"CreateOpenCLBuffer failed.",
".");
4316 blurRowKernel=AcquireOpenCLKernel(device,
"BlurRow");
4317 if (blurRowKernel == (cl_kernel) NULL)
4319 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4320 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4324 unsharpMaskBlurColumnKernel=AcquireOpenCLKernel(device,
4325 "UnsharpMaskBlurColumn");
4326 if (unsharpMaskBlurColumnKernel == (cl_kernel) NULL)
4328 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4329 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4333 number_channels=(cl_uint) image->number_channels;
4334 imageColumns=(cl_uint) image->columns;
4335 imageRows=(cl_uint) image->rows;
4340 status =SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4341 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),&number_channels);
4342 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_int),&channel_mask);
4343 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4344 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4345 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4346 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4347 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_float4)*(chunkSize+kernelWidth),(
void *) NULL);
4348 status|=SetOpenCLKernelArg(blurRowKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
4349 if (status != CL_SUCCESS)
4351 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4352 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4356 gsize[0]=chunkSize*((image->columns+chunkSize-1)/chunkSize);
4357 gsize[1]=image->rows;
4360 outputReady=EnqueueOpenCLKernel(queue,blurRowKernel,2,
4361 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
4366 fThreshold=(float) threshold;
4369 status =SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4370 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&tempImageBuffer);
4371 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),&number_channels);
4372 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_int),&channel_mask);
4373 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4374 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4375 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,(chunkSize+kernelWidth-1)*
sizeof(cl_float4),NULL);
4376 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,kernelWidth*
sizeof(
float),NULL);
4377 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4378 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4379 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(
float),(
void *)&fGain);
4380 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(
float),(
void *)&fThreshold);
4381 status|=SetOpenCLKernelArg(unsharpMaskBlurColumnKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4382 if (status != CL_SUCCESS)
4384 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4385 ResourceLimitWarning,
"clEnv->library->clSetKernelArg failed.",
".");
4389 gsize[0]=image->columns;
4390 gsize[1]=chunkSize*((image->rows+chunkSize-1)/chunkSize);
4393 outputReady=EnqueueOpenCLKernel(queue,unsharpMaskBlurColumnKernel,2,
4394 (
const size_t *) NULL,gsize,lsize,image,filteredImage,MagickFalse,
4399 if (imageBuffer != (cl_mem) NULL)
4400 ReleaseOpenCLMemObject(imageBuffer);
4401 if (filteredImageBuffer != (cl_mem) NULL)
4402 ReleaseOpenCLMemObject(filteredImageBuffer);
4403 if (tempImageBuffer != (cl_mem) NULL)
4404 ReleaseOpenCLMemObject(tempImageBuffer);
4405 if (imageKernelBuffer != (cl_mem) NULL)
4406 ReleaseOpenCLMemObject(imageKernelBuffer);
4407 if (blurRowKernel != (cl_kernel) NULL)
4408 ReleaseOpenCLKernel(blurRowKernel);
4409 if (unsharpMaskBlurColumnKernel != (cl_kernel) NULL)
4410 ReleaseOpenCLKernel(unsharpMaskBlurColumnKernel);
4411 if (queue != (cl_command_queue) NULL)
4412 ReleaseOpenCLCommandQueue(device,queue);
4413 if (device != (MagickCLDevice) NULL)
4414 ReleaseOpenCLDevice(device);
4415 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
4416 filteredImage=DestroyImage(filteredImage);
4418 return(filteredImage);
4421static Image *ComputeUnsharpMaskImageSingle(
const Image *image,
4422 MagickCLEnv clEnv,
const double radius,
const double sigma,
const double gain,
4423 const double threshold,ExceptionInfo *exception)
4429 channel_mask=get32BitChannelValue(image->channel_mask),
4436 filteredImageBuffer,
4467 filteredImageBuffer=NULL;
4468 imageKernelBuffer=NULL;
4469 unsharpMaskKernel=NULL;
4470 outputReady=MagickFalse;
4472 device=RequestOpenCLDevice(clEnv);
4473 if (device == (MagickCLDevice) NULL)
4475 queue=AcquireOpenCLCommandQueue(device);
4476 if (queue == (cl_command_queue) NULL)
4478 filteredImage=cloneImage(image,exception);
4479 if (filteredImage == (Image *) NULL)
4481 if (filteredImage->number_channels != image->number_channels)
4483 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4484 if (imageBuffer == (cl_mem) NULL)
4486 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4487 if (filteredImageBuffer == (cl_mem) NULL)
4490 imageKernelBuffer=createKernelInfo(device,radius,sigma,&kernelWidth,
4493 unsharpMaskKernel=AcquireOpenCLKernel(device,
"UnsharpMask");
4494 if (unsharpMaskKernel == NULL)
4496 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4497 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4501 imageColumns=(cl_uint) image->columns;
4502 imageRows=(cl_uint) image->rows;
4503 number_channels=(cl_uint) image->number_channels;
4505 fThreshold=(float) threshold;
4508 status =SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4509 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
4510 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_int),&channel_mask);
4511 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&imageKernelBuffer);
4512 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&kernelWidth);
4513 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&imageColumns);
4514 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_uint),(
void *)&imageRows);
4515 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_float4)*(8 * (32 + kernelWidth)),(
void *) NULL);
4516 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(
float),(
void *)&fGain);
4517 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(
float),(
void *)&fThreshold);
4518 status|=SetOpenCLKernelArg(unsharpMaskKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4519 if (status != CL_SUCCESS)
4521 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4522 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
4526 gsize[0]=((image->columns + 7) / 8)*8;
4527 gsize[1]=((image->rows + 31) / 32)*32;
4530 outputReady=EnqueueOpenCLKernel(queue,unsharpMaskKernel,2,(
const size_t *) NULL,
4531 gsize,lsize,image,filteredImage,MagickFalse,exception);
4535 if (imageBuffer != (cl_mem) NULL)
4536 ReleaseOpenCLMemObject(imageBuffer);
4537 if (filteredImageBuffer != (cl_mem) NULL)
4538 ReleaseOpenCLMemObject(filteredImageBuffer);
4539 if (imageKernelBuffer != (cl_mem) NULL)
4540 ReleaseOpenCLMemObject(imageKernelBuffer);
4541 if (unsharpMaskKernel != (cl_kernel) NULL)
4542 ReleaseOpenCLKernel(unsharpMaskKernel);
4543 if (queue != (cl_command_queue) NULL)
4544 ReleaseOpenCLCommandQueue(device,queue);
4545 if (device != (MagickCLDevice) NULL)
4546 ReleaseOpenCLDevice(device);
4547 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
4548 filteredImage=DestroyImage(filteredImage);
4550 return(filteredImage);
4553MagickPrivate Image *AccelerateUnsharpMaskImage(
const Image *image,
4554 const double radius,
const double sigma,
const double gain,
4555 const double threshold,ExceptionInfo *exception)
4563 assert(image != NULL);
4564 assert(exception != (ExceptionInfo *) NULL);
4566 if (checkAccelerateCondition(image) == MagickFalse)
4567 return((Image *) NULL);
4569 clEnv=getOpenCLEnvironment(exception);
4570 if (clEnv == (MagickCLEnv) NULL)
4571 return((Image *) NULL);
4574 filteredImage=ComputeUnsharpMaskImageSingle(image,clEnv,radius,sigma,gain,
4575 threshold,exception);
4577 filteredImage=ComputeUnsharpMaskImage(image,clEnv,radius,sigma,gain,
4578 threshold,exception);
4579 return(filteredImage);
4582static Image *ComputeWaveletDenoiseImage(
const Image *image,MagickCLEnv clEnv,
4583 const double threshold,ExceptionInfo *exception)
4594 SIZE=TILESIZE-2*PAD;
4606 filteredImageBuffer,
4634 filteredImageBuffer=NULL;
4637 outputReady=MagickFalse;
4639 device=RequestOpenCLDevice(clEnv);
4640 if (device == (MagickCLDevice) NULL)
4643 if (strcmp(
"Intel(R) HD Graphics",device->name) == 0)
4645 queue=AcquireOpenCLCommandQueue(device);
4646 if (queue == (cl_command_queue) NULL)
4648 filteredImage=CloneImage(image,0,0,MagickTrue,
4650 if (filteredImage == (Image *) NULL)
4652 if (filteredImage->number_channels != image->number_channels)
4654 imageBuffer=GetAuthenticOpenCLBuffer(image,device,exception);
4655 if (imageBuffer == (cl_mem) NULL)
4657 filteredImageBuffer=GetAuthenticOpenCLBuffer(filteredImage,device,exception);
4658 if (filteredImageBuffer == (cl_mem) NULL)
4661 denoiseKernel=AcquireOpenCLKernel(device,
"WaveletDenoise");
4662 if (denoiseKernel == (cl_kernel) NULL)
4664 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4665 ResourceLimitWarning,
"AcquireOpenCLKernel failed.",
".");
4669 number_channels=(cl_uint)image->number_channels;
4670 width=(cl_uint)image->columns;
4671 height=(cl_uint)image->rows;
4672 max_channels=number_channels;
4673 if ((max_channels == 4) || (max_channels == 2))
4674 max_channels=max_channels-1;
4675 thresh=(cl_float) threshold;
4676 passes=(size_t) ((((1.0f*image->columns)*image->rows)+1999999.0f)/2000000.0f);
4677 passes=(passes < 1) ? 1 : passes;
4680 status =SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_mem),(
void *)&imageBuffer);
4681 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_mem),(
void *)&filteredImageBuffer);
4682 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&number_channels);
4683 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&max_channels);
4684 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_float),(
void *)&thresh);
4685 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_int),(
void *)&PASSES);
4686 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&width);
4687 status|=SetOpenCLKernelArg(denoiseKernel,i++,
sizeof(cl_uint),(
void *)&height);
4688 if (status != CL_SUCCESS)
4690 (void) OpenCLThrowMagickException(device,exception,GetMagickModule(),
4691 ResourceLimitWarning,
"SetOpenCLKernelArg failed.",
".");
4695 for (x = 0; x < passes; ++x)
4697 gsize[0]=((width+(SIZE-1))/SIZE)*TILESIZE;
4698 gsize[1]=((((height+(SIZE-1))/SIZE)+passes-1)/passes)*4;
4702 goffset[1]=x*gsize[1];
4704 outputReady=EnqueueOpenCLKernel(queue,denoiseKernel,2,goffset,gsize,lsize,
4705 image,filteredImage,MagickTrue,exception);
4706 if (outputReady == MagickFalse)
4712 if (imageBuffer != (cl_mem) NULL)
4713 ReleaseOpenCLMemObject(imageBuffer);
4714 if (filteredImageBuffer != (cl_mem) NULL)
4715 ReleaseOpenCLMemObject(filteredImageBuffer);
4716 if (denoiseKernel != (cl_kernel) NULL)
4717 ReleaseOpenCLKernel(denoiseKernel);
4718 if (queue != (cl_command_queue) NULL)
4719 ReleaseOpenCLCommandQueue(device,queue);
4720 if (device != (MagickCLDevice) NULL)
4721 ReleaseOpenCLDevice(device);
4722 if ((outputReady == MagickFalse) && (filteredImage != (Image *) NULL))
4723 filteredImage=DestroyImage(filteredImage);
4725 return(filteredImage);
4728MagickPrivate Image *AccelerateWaveletDenoiseImage(
const Image *image,
4729 const double threshold,ExceptionInfo *exception)
4737 assert(image != NULL);
4738 assert(exception != (ExceptionInfo *)NULL);
4740 if (checkAccelerateCondition(image) == MagickFalse)
4741 return((Image *) NULL);
4743 clEnv=getOpenCLEnvironment(exception);
4744 if (clEnv == (MagickCLEnv) NULL)
4745 return((Image *) NULL);
4747 filteredImage=ComputeWaveletDenoiseImage(image,clEnv,threshold,exception);
4749 return(filteredImage);