19 #ifndef _MAGICKCORE_ACCELERATE_PRIVATE_H 20 #define _MAGICKCORE_ACCELERATE_PRIVATE_H 22 #if defined(__cplusplus) || defined(c_plusplus) 27 #if defined(MAGICKCORE_OPENCL_SUPPORT) 29 #define OPENCL_DEFINE(VAR,...) "\n #""define " #VAR " " #__VA_ARGS__ " \n" 30 #define OPENCL_ELIF(...) "\n #""elif " #__VA_ARGS__ " \n" 31 #define OPENCL_ELSE() "\n #""else " " \n" 32 #define OPENCL_ENDIF() "\n #""endif " " \n" 33 #define OPENCL_IF(...) "\n #""if " #__VA_ARGS__ " \n" 34 #define STRINGIFY(...) #__VA_ARGS__ "\n" 36 typedef struct _FloatPixelPacket
38 #ifdef MAGICK_PIXEL_RGBA 45 #ifdef MAGICK_PIXEL_BGRA 54 const char* accelerateKernels =
87 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
89 return((CLQuantum) value);
96 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
98 return((CLQuantum) (257.0f*value));
105 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
107 return((CLQuantum) (16843009.0*value));
115 inline
int ClampToCanvas(const
int offset,const
int range)
117 return clamp(offset, (
int)0, range-1);
122 inline int ClampToCanvasWithHalo(
const int offset,
const int range,
const int edge,
const int section)
124 return clamp(offset, section?(
int)(0-edge):(
int)0, section?(range-1):(range-1+edge));
131 return (CLQuantum) (clamp(value, 0.0f, (
float)
QuantumRange) + 0.5f);
136 inline uint ScaleQuantumToMap(CLQuantum value)
138 if (value >= (CLQuantum)
MaxMap)
141 return ((uint)value);
148 float sign = x < (float) 0.0 ? (
float) -1.0 : (float) 1.0;
214 return clamp(value,0.0f,1.0f);
220 inline CLQuantum getBlue(CLPixelType p) {
return p.x; }
221 inline void setBlue(CLPixelType* p, CLQuantum value) { (*p).x = value; }
222 inline float getBlueF4(float4 p) {
return p.x; }
223 inline void setBlueF4(float4* p,
float value) { (*p).x = value; }
225 inline CLQuantum getGreen(CLPixelType p) {
return p.y; }
226 inline void setGreen(CLPixelType* p, CLQuantum value) { (*p).y = value; }
227 inline float getGreenF4(float4 p) {
return p.y; }
228 inline void setGreenF4(float4* p,
float value) { (*p).y = value; }
230 inline CLQuantum getRed(CLPixelType p) {
return p.z; }
231 inline void setRed(CLPixelType* p, CLQuantum value) { (*p).z = value; }
232 inline float getRedF4(float4 p) {
return p.z; }
233 inline void setRedF4(float4* p,
float value) { (*p).z = value; }
235 inline CLQuantum getOpacity(CLPixelType p) {
return p.w; }
236 inline void setOpacity(CLPixelType* p, CLQuantum value) { (*p).w = value; }
237 inline float getOpacityF4(float4 p) {
return p.w; }
238 inline void setOpacityF4(float4* p,
float value) { (*p).w = value; }
240 inline void setGray(CLPixelType* p, CLQuantum value) { (*p).z = value; (*p).y = value; (*p).x = value; }
242 inline float GetPixelIntensity(
const int method,
const int colorspace, CLPixelType p)
244 float red = getRed(p);
245 float green = getGreen(p);
246 float blue = getBlue(p);
257 intensity=(red+green+blue)/3.0;
262 intensity=max(max(red,green),blue);
267 intensity=(min(min(red,green),blue)+
268 max(max(red,green),blue))/2.0;
273 intensity=(float) (((
float) red*red+green*green+blue*blue)/
287 intensity=0.298839*red+0.586811*green+0.114350*blue;
300 intensity=0.298839*red+0.586811*green+0.114350*blue;
314 intensity=0.212656*red+0.715158*green+0.072186*blue;
327 intensity=0.212656*red+0.715158*green+0.072186*blue;
332 intensity=(float) (sqrt((
float) red*red+green*green+blue*blue)/
345 void ConvolveOptimized(
const __global CLPixelType *input, __global CLPixelType *output,
346 const unsigned int imageWidth,
const unsigned int imageHeight,
347 __constant
float *filter,
const unsigned int filterWidth,
const unsigned int filterHeight,
348 const uint matte,
const ChannelType channel, __local CLPixelType *pixelLocalCache, __local
float* filterCache) {
351 blockID.x = get_group_id(0);
352 blockID.y = get_group_id(1);
356 imageAreaOrg.x = blockID.x * get_local_size(0);
357 imageAreaOrg.y = blockID.y * get_local_size(1);
360 midFilterDimen.x = (filterWidth-1)/2;
361 midFilterDimen.y = (filterHeight-1)/2;
363 int2 cachedAreaOrg = imageAreaOrg - midFilterDimen;
366 int2 cachedAreaDimen;
367 cachedAreaDimen.x = get_local_size(0) + filterWidth - 1;
368 cachedAreaDimen.y = get_local_size(1) + filterHeight - 1;
371 int localID = get_local_id(1)*get_local_size(0)+get_local_id(0);
372 int cachedAreaNumPixels = cachedAreaDimen.x * cachedAreaDimen.y;
373 int groupSize = get_local_size(0) * get_local_size(1);
374 for (
int i = localID; i < cachedAreaNumPixels; i+=groupSize) {
376 int2 cachedAreaIndex;
377 cachedAreaIndex.x = i % cachedAreaDimen.x;
378 cachedAreaIndex.y = i / cachedAreaDimen.x;
380 int2 imagePixelIndex;
381 imagePixelIndex = cachedAreaOrg + cachedAreaIndex;
385 imagePixelIndex.x = ClampToCanvas(imagePixelIndex.x, imageWidth);
386 imagePixelIndex.y = ClampToCanvas(imagePixelIndex.y, imageHeight);
388 pixelLocalCache[i] = input[imagePixelIndex.y * imageWidth + imagePixelIndex.x];
392 for (
int i = localID; i < filterHeight*filterWidth; i+=groupSize) {
393 filterCache[i] = filter[i];
395 barrier(CLK_LOCAL_MEM_FENCE);
399 imageIndex.x = imageAreaOrg.x + get_local_id(0);
400 imageIndex.y = imageAreaOrg.y + get_local_id(1);
403 if (imageIndex.x >= imageWidth
404 || imageIndex.y >= imageHeight) {
409 float4 sum = (float4)0.0f;
412 int cacheIndexY = get_local_id(1);
413 for (
int j = 0; j < filterHeight; j++) {
414 int cacheIndexX = get_local_id(0);
415 for (
int i = 0; i < filterWidth; i++) {
416 CLPixelType p = pixelLocalCache[cacheIndexY*cachedAreaDimen.x + cacheIndexX];
417 float f = filterCache[filterIndex];
432 int cacheIndexY = get_local_id(1);
433 for (
int j = 0; j < filterHeight; j++) {
434 int cacheIndexX = get_local_id(0);
435 for (
int i = 0; i < filterWidth; i++) {
437 CLPixelType p = pixelLocalCache[cacheIndexY*cachedAreaDimen.x + cacheIndexX];
439 float f = filterCache[filterIndex];
454 sum.xyz = gamma*sum.xyz;
456 CLPixelType outputPixel;
462 output[imageIndex.y * imageWidth + imageIndex.x] = outputPixel;
468 void Convolve(
const __global CLPixelType *input, __global CLPixelType *output,
469 const uint imageWidth,
const uint imageHeight,
470 __constant
float *filter,
const unsigned int filterWidth,
const unsigned int filterHeight,
474 imageIndex.x = get_global_id(0);
475 imageIndex.y = get_global_id(1);
481 if (imageIndex.x >= imageWidth
482 || imageIndex.y >= imageHeight)
486 midFilterDimen.x = (filterWidth-1)/2;
487 midFilterDimen.y = (filterHeight-1)/2;
490 float4 sum = (float4)0.0f;
492 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
493 for (
int j = 0; j < filterHeight; j++) {
494 int2 inputPixelIndex;
495 inputPixelIndex.y = imageIndex.y - midFilterDimen.y + j;
496 inputPixelIndex.y = ClampToCanvas(inputPixelIndex.y, imageHeight);
497 for (
int i = 0; i < filterWidth; i++) {
498 inputPixelIndex.x = imageIndex.x - midFilterDimen.x + i;
499 inputPixelIndex.x = ClampToCanvas(inputPixelIndex.x, imageWidth);
501 CLPixelType p = input[inputPixelIndex.y * imageWidth + inputPixelIndex.x];
502 float f = filter[filterIndex];
517 for (
int j = 0; j < filterHeight; j++) {
518 int2 inputPixelIndex;
519 inputPixelIndex.y = imageIndex.y - midFilterDimen.y + j;
520 inputPixelIndex.y = ClampToCanvas(inputPixelIndex.y, imageHeight);
521 for (
int i = 0; i < filterWidth; i++) {
522 inputPixelIndex.x = imageIndex.x - midFilterDimen.x + i;
523 inputPixelIndex.x = ClampToCanvas(inputPixelIndex.x, imageWidth);
525 CLPixelType p = input[inputPixelIndex.y * imageWidth + inputPixelIndex.x];
527 float f = filter[filterIndex];
542 sum.xyz = gamma*sum.xyz;
545 CLPixelType outputPixel;
551 output[imageIndex.y * imageWidth + imageIndex.x] = outputPixel;
571 CLPixelType
ApplyFunction(CLPixelType pixel,
const MagickFunction
function,
572 const unsigned int number_parameters,
573 __constant
float *parameters)
575 float4 result = (float4) 0.0f;
580 for (
unsigned int i=0; i < number_parameters; i++)
581 result = result*(float4)
QuantumScale*convert_float4(pixel) + parameters[i];
587 float freq,phase,ampl,bias;
588 freq = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
589 phase = ( number_parameters >= 2 ) ? parameters[1] : 0.0f;
590 ampl = ( number_parameters >= 3 ) ? parameters[2] : 0.5f;
591 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
593 (freq*
QuantumScale*(
float)pixel.x + phase/360.0f)) + bias);
595 (freq*
QuantumScale*(
float)pixel.y + phase/360.0f)) + bias);
597 (freq*
QuantumScale*(
float)pixel.z + phase/360.0f)) + bias);
599 (freq*
QuantumScale*(
float)pixel.w + phase/360.0f)) + bias);
604 float width,range,center,bias;
605 width = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
606 center = ( number_parameters >= 2 ) ? parameters[1] : 0.5f;
607 range = ( number_parameters >= 3 ) ? parameters[2] : 1.0f;
608 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
610 result.x = 2.0f/width*(
QuantumScale*(float)pixel.x - center);
611 result.x = range/
MagickPI*asin(result.x)+bias;
612 result.x = ( result.x <= -1.0f ) ? bias - range/2.0f : result.x;
613 result.x = ( result.x >= 1.0f ) ? bias + range/2.0f : result.x;
615 result.y = 2.0f/width*(
QuantumScale*(float)pixel.y - center);
616 result.y = range/
MagickPI*asin(result.y)+bias;
617 result.y = ( result.y <= -1.0f ) ? bias - range/2.0f : result.y;
618 result.y = ( result.y >= 1.0f ) ? bias + range/2.0f : result.y;
620 result.z = 2.0f/width*(
QuantumScale*(float)pixel.z - center);
621 result.z = range/
MagickPI*asin(result.z)+bias;
622 result.z = ( result.z <= -1.0f ) ? bias - range/2.0f : result.x;
623 result.z = ( result.z >= 1.0f ) ? bias + range/2.0f : result.x;
626 result.w = 2.0f/width*(
QuantumScale*(float)pixel.w - center);
627 result.w = range/
MagickPI*asin(result.w)+bias;
628 result.w = ( result.w <= -1.0f ) ? bias - range/2.0f : result.w;
629 result.w = ( result.w >= 1.0f ) ? bias + range/2.0f : result.w;
636 float slope,range,center,bias;
637 slope = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
638 center = ( number_parameters >= 2 ) ? parameters[1] : 0.5f;
639 range = ( number_parameters >= 3 ) ? parameters[2] : 1.0f;
640 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
641 result = (float4)
MagickPI*(float4)slope*((float4)
QuantumScale*convert_float4(pixel)-(float4)center);
662 const ChannelType channel,
const MagickFunction
function,
663 const unsigned int number_parameters, __constant
float *parameters)
665 const int x = get_global_id(0);
666 const int y = get_global_id(1);
667 const int columns = get_global_size(0);
668 const int c = x + y * columns;
669 im[c] =
ApplyFunction(im[c],
function, number_parameters, parameters);
676 __kernel
void Stretch(__global CLPixelType * restrict im,
678 __global CLPixelType * restrict stretch_map,
679 const float4 white,
const float4 black)
681 const int x = get_global_id(0);
682 const int y = get_global_id(1);
683 const int columns = get_global_size(0);
684 const int c = x + y * columns;
687 CLPixelType oValue, eValue;
688 CLQuantum red, green, blue, opacity;
695 if (getRedF4(white) != getRedF4(black))
697 ePos = ScaleQuantumToMap(getRed(oValue));
698 eValue = stretch_map[ePos];
699 red = getRed(eValue);
705 if (getGreenF4(white) != getGreenF4(black))
707 ePos = ScaleQuantumToMap(getGreen(oValue));
708 eValue = stretch_map[ePos];
709 green = getGreen(eValue);
715 if (getBlueF4(white) != getBlueF4(black))
717 ePos = ScaleQuantumToMap(getBlue(oValue));
718 eValue = stretch_map[ePos];
719 blue = getBlue(eValue);
723 if ((channel & OpacityChannel) != 0)
725 if (getOpacityF4(white) != getOpacityF4(black))
727 ePos = ScaleQuantumToMap(getOpacity(oValue));
728 eValue = stretch_map[ePos];
729 opacity = getOpacity(eValue);
734 im[c]=(CLPixelType)(blue, green, red, opacity);
743 __kernel
void Equalize(__global CLPixelType * restrict im,
745 __global CLPixelType * restrict equalize_map,
746 const float4 white,
const float4 black)
748 const int x = get_global_id(0);
749 const int y = get_global_id(1);
750 const int columns = get_global_size(0);
751 const int c = x + y * columns;
754 CLPixelType oValue, eValue;
755 CLQuantum red, green, blue, opacity;
762 if (getRedF4(white) != getRedF4(black))
764 ePos = ScaleQuantumToMap(getRed(oValue));
765 eValue = equalize_map[ePos];
766 red = getRed(eValue);
767 ePos = ScaleQuantumToMap(getGreen(oValue));
768 eValue = equalize_map[ePos];
769 green = getRed(eValue);
770 ePos = ScaleQuantumToMap(getBlue(oValue));
771 eValue = equalize_map[ePos];
772 blue = getRed(eValue);
773 ePos = ScaleQuantumToMap(getOpacity(oValue));
774 eValue = equalize_map[ePos];
775 opacity = getRed(eValue);
778 im[c]=(CLPixelType)(blue, green, red, opacity);
792 __kernel
void Histogram(__global CLPixelType * restrict im,
795 const int colorspace,
796 __global uint4 * restrict histogram)
798 const int x = get_global_id(0);
799 const int y = get_global_id(1);
800 const int columns = get_global_size(0);
801 const int c = x + y * columns;
802 if ((channel & SyncChannels) != 0)
806 atomic_inc((__global uint *)(&(histogram[pos]))+2);
824 __kernel
void BlurRow(__global CLPixelType *im, __global float4 *filtered_im,
825 const ChannelType channel, __constant
float *filter,
826 const unsigned int width,
827 const unsigned int imageColumns,
const unsigned int imageRows,
828 __local CLPixelType *temp)
830 const int x = get_global_id(0);
831 const int y = get_global_id(1);
833 const int columns = imageColumns;
835 const unsigned int radius = (width-1)/2;
836 const int wsize = get_local_size(0);
837 const unsigned int loadSize = wsize+width;
865 const int groupX=get_local_size(0)*get_group_id(0);
866 const int groupY=get_local_size(1)*get_group_id(1);
869 for (
int i=get_local_id(0); i < loadSize; i=i+get_local_size(0))
872 temp[i] = im[y * columns + ClampToCanvas(i+groupX-radius, columns)];
881 barrier(CLK_LOCAL_MEM_FENCE);
884 if (get_global_id(0) < columns)
887 float4 result = (float4) 0;
891 \n #ifndef UFACTOR \n
892 \n #define UFACTOR 8 \n
895 for ( ; i+UFACTOR < width; )
897 \n #pragma unroll UFACTOR\n
898 for (
int j=0; j < UFACTOR; j++, i++)
900 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
904 for ( ; i < width; i++)
906 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
915 filtered_im[y*columns+x] = result;
928 __kernel
void BlurRowSection(__global CLPixelType *im, __global float4 *filtered_im,
929 const ChannelType channel, __constant
float *filter,
930 const unsigned int width,
931 const unsigned int imageColumns,
const unsigned int imageRows,
932 __local CLPixelType *temp,
933 const unsigned int offsetRows,
const unsigned int section)
935 const int x = get_global_id(0);
936 const int y = get_global_id(1);
938 const int columns = imageColumns;
940 const unsigned int radius = (width-1)/2;
941 const int wsize = get_local_size(0);
942 const unsigned int loadSize = wsize+width;
945 const int groupX=get_local_size(0)*get_group_id(0);
946 const int groupY=get_local_size(1)*get_group_id(1);
949 im += imageColumns * (offsetRows - radius * section);
952 for (
int i=get_local_id(0); i < loadSize; i=i+get_local_size(0))
955 temp[i] = im[y * columns + ClampToCanvas(i+groupX-radius, columns)];
964 barrier(CLK_LOCAL_MEM_FENCE);
967 if (get_global_id(0) < columns)
970 float4 result = (float4) 0;
974 \n #ifndef UFACTOR \n
975 \n #define UFACTOR 8 \n
978 for ( ; i+UFACTOR < width; )
980 \n #pragma unroll UFACTOR\n
981 for (
int j=0; j < UFACTOR; j++, i++)
983 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
987 for ( ; i < width; i++)
989 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
998 filtered_im[y*columns+x] = result;
1012 __kernel
void BlurColumn(
const __global float4 *blurRowData, __global CLPixelType *filtered_im,
1013 const ChannelType channel, __constant
float *filter,
1014 const unsigned int width,
1015 const unsigned int imageColumns,
const unsigned int imageRows,
1016 __local float4 *temp)
1018 const int x = get_global_id(0);
1019 const int y = get_global_id(1);
1023 const int columns = imageColumns;
1024 const int rows = imageRows;
1026 unsigned int radius = (width-1)/2;
1027 const int wsize = get_local_size(1);
1028 const unsigned int loadSize = wsize+width;
1031 const int groupX=get_local_size(0)*get_group_id(0);
1032 const int groupY=get_local_size(1)*get_group_id(1);
1037 for (
int i = get_local_id(1); i < loadSize; i=i+get_local_size(1))
1039 temp[i] = blurRowData[ClampToCanvas(i+groupY-radius, rows) * columns + groupX];
1043 barrier(CLK_LOCAL_MEM_FENCE);
1046 if (get_global_id(1) < rows)
1049 float4 result = (float4) 0;
1053 \n #ifndef UFACTOR \n
1054 \n #define UFACTOR 8 \n
1057 for ( ; i+UFACTOR < width; )
1059 \n #pragma unroll UFACTOR \n
1060 for (
int j=0; j < UFACTOR; j++, i++)
1062 result+=filter[i]*temp[i+get_local_id(1)];
1066 for ( ; i < width; i++)
1068 result+=filter[i]*temp[i+get_local_id(1)];
1077 filtered_im[y*columns+x] = (CLPixelType) (result.x,result.y,result.z,result.w);
1092 __kernel
void BlurColumnSection(
const __global float4 *blurRowData, __global CLPixelType *filtered_im,
1093 const ChannelType channel, __constant
float *filter,
1094 const unsigned int width,
1095 const unsigned int imageColumns,
const unsigned int imageRows,
1096 __local float4 *temp,
1097 const unsigned int offsetRows,
const unsigned int section)
1099 const int x = get_global_id(0);
1100 const int y = get_global_id(1);
1104 const int columns = imageColumns;
1105 const int rows = imageRows;
1107 unsigned int radius = (width-1)/2;
1108 const int wsize = get_local_size(1);
1109 const unsigned int loadSize = wsize+width;
1112 const int groupX=get_local_size(0)*get_group_id(0);
1113 const int groupY=get_local_size(1)*get_group_id(1);
1118 blurRowData += imageColumns * radius * section;
1121 for (
int i = get_local_id(1); i < loadSize; i=i+get_local_size(1))
1123 int pos = ClampToCanvasWithHalo(i+groupY-radius, rows, radius, section) * columns + groupX;
1124 temp[i] = *(blurRowData+pos);
1128 barrier(CLK_LOCAL_MEM_FENCE);
1131 if (get_global_id(1) < rows)
1134 float4 result = (float4) 0;
1138 \n #ifndef UFACTOR \n
1139 \n #define UFACTOR 8 \n
1142 for ( ; i+UFACTOR < width; )
1144 \n #pragma unroll UFACTOR \n
1145 for (
int j=0; j < UFACTOR; j++, i++)
1147 result+=filter[i]*temp[i+get_local_id(1)];
1150 for ( ; i < width; i++)
1152 result+=filter[i]*temp[i+get_local_id(1)];
1161 filtered_im += imageColumns * offsetRows;
1164 filtered_im[y*columns+x] = (CLPixelType) (result.x,result.y,result.z,result.w);
1172 __kernel
void UnsharpMaskBlurColumn(
const __global CLPixelType* inputImage,
1173 const __global float4 *blurRowData, __global CLPixelType *filtered_im,
1174 const unsigned int imageColumns,
const unsigned int imageRows,
1175 __local float4* cachedData, __local
float* cachedFilter,
1176 const ChannelType channel,
const __global
float *filter,
const unsigned int width,
1177 const float gain,
const float threshold)
1179 const unsigned int radius = (width-1)/2;
1182 const int groupX = get_group_id(0);
1183 const int groupStartY = get_group_id(1)*get_local_size(1) - radius;
1184 const int groupStopY = (get_group_id(1)+1)*get_local_size(1) + radius;
1186 if (groupStartY >= 0
1187 && groupStopY < imageRows) {
1188 event_t e = async_work_group_strided_copy(cachedData
1189 ,blurRowData+groupStartY*imageColumns+groupX
1190 ,groupStopY-groupStartY,imageColumns,0);
1191 wait_group_events(1,&e);
1194 for (
int i = get_local_id(1); i < (groupStopY - groupStartY); i+=get_local_size(1)) {
1195 cachedData[i] = blurRowData[ClampToCanvas(groupStartY+i,imageRows)*imageColumns+ groupX];
1197 barrier(CLK_LOCAL_MEM_FENCE);
1200 event_t e = async_work_group_copy(cachedFilter,filter,width,0);
1201 wait_group_events(1,&e);
1205 const int cy = get_global_id(1);
1207 if (cy < imageRows) {
1208 float4 blurredPixel = (float4) 0.0f;
1212 \n #ifndef UFACTOR \n
1213 \n #define UFACTOR 8 \n
1216 for ( ; i+UFACTOR < width; )
1218 \n #pragma unroll UFACTOR \n
1219 for (
int j=0; j < UFACTOR; j++, i++)
1221 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
1225 for ( ; i < width; i++)
1227 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
1233 float4 inputImagePixel = convert_float4(inputImage[cy*imageColumns+groupX]);
1234 float4 outputPixel = inputImagePixel - blurredPixel;
1238 int4 mask = isless(fabs(2.0f*outputPixel), (float4)quantumThreshold);
1239 outputPixel = select(inputImagePixel + outputPixel * gain, inputImagePixel, mask);
1248 __kernel
void UnsharpMaskBlurColumnSection(
const __global CLPixelType* inputImage,
1249 const __global float4 *blurRowData, __global CLPixelType *filtered_im,
1250 const unsigned int imageColumns,
const unsigned int imageRows,
1251 __local float4* cachedData, __local
float* cachedFilter,
1252 const ChannelType channel,
const __global
float *filter,
const unsigned int width,
1253 const float gain,
const float threshold,
1254 const unsigned int offsetRows,
const unsigned int section)
1256 const unsigned int radius = (width-1)/2;
1259 const int groupX = get_group_id(0);
1260 const int groupStartY = get_group_id(1)*get_local_size(1) - radius;
1261 const int groupStopY = (get_group_id(1)+1)*get_local_size(1) + radius;
1264 blurRowData += imageColumns * radius * section;
1266 if (groupStartY >= 0
1267 && groupStopY < imageRows) {
1268 event_t e = async_work_group_strided_copy(cachedData
1269 ,blurRowData+groupStartY*imageColumns+groupX
1270 ,groupStopY-groupStartY,imageColumns,0);
1271 wait_group_events(1,&e);
1274 for (
int i = get_local_id(1); i < (groupStopY - groupStartY); i+=get_local_size(1)) {
1275 int pos = ClampToCanvasWithHalo(groupStartY+i,imageRows, radius, section)*imageColumns+ groupX;
1276 cachedData[i] = *(blurRowData + pos);
1278 barrier(CLK_LOCAL_MEM_FENCE);
1281 event_t e = async_work_group_copy(cachedFilter,filter,width,0);
1282 wait_group_events(1,&e);
1286 const int cy = get_global_id(1);
1288 if (cy < imageRows) {
1289 float4 blurredPixel = (float4) 0.0f;
1293 \n #ifndef UFACTOR \n
1294 \n #define UFACTOR 8 \n
1297 for ( ; i+UFACTOR < width; )
1299 \n #pragma unroll UFACTOR \n
1300 for (
int j=0; j < UFACTOR; j++, i++)
1302 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
1306 for ( ; i < width; i++)
1308 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
1315 inputImage += imageColumns * offsetRows;
1316 filtered_im += imageColumns * offsetRows;
1318 float4 inputImagePixel = convert_float4(inputImage[cy*imageColumns+groupX]);
1319 float4 outputPixel = inputImagePixel - blurredPixel;
1323 int4 mask = isless(fabs(2.0f*outputPixel), (float4)quantumThreshold);
1324 outputPixel = select(inputImagePixel + outputPixel * gain, inputImagePixel, mask);
1338 __kernel
void UnsharpMask(__global CLPixelType *im, __global CLPixelType *filtered_im,
1339 __constant
float *filter,
1340 const unsigned int width,
1341 const unsigned int imageColumns,
const unsigned int imageRows,
1342 __local float4 *pixels,
1343 const float gain,
const float threshold,
const unsigned int justBlur)
1345 const int x = get_global_id(0);
1346 const int y = get_global_id(1);
1348 const unsigned int radius = (width - 1) / 2;
1350 int row = y - radius;
1351 int baseRow = get_group_id(1) * get_local_size(1) - radius;
1352 int endRow = (get_group_id(1) + 1) * get_local_size(1) + radius;
1354 while (row < endRow) {
1355 int srcy = (row < 0) ? -row : row;
1356 srcy = (srcy >= imageRows) ? (2 * imageRows - srcy - 1) : srcy;
1358 float4 value = 0.0f;
1360 int ix = x - radius;
1363 while (i + 7 < width) {
1364 for (
int j = 0; j < 8; ++j) {
1366 srcx = (srcx < 0) ? -srcx : srcx;
1367 srcx = (srcx >= imageColumns) ? (2 * imageColumns - srcx - 1) : srcx;
1368 value += filter[i + j] * convert_float4(im[srcx + srcy * imageColumns]);
1375 int srcx = (ix < 0) ? -ix : ix;
1376 srcx = (srcx >= imageColumns) ? (2 * imageColumns - srcx - 1) : srcx;
1377 value += filter[i] * convert_float4(im[srcx + srcy * imageColumns]);
1381 pixels[(row - baseRow) * get_local_size(0) + get_local_id(0)] = value;
1382 row += get_local_size(1);
1386 barrier(CLK_LOCAL_MEM_FENCE);
1389 const int px = get_local_id(0);
1390 const int py = get_local_id(1);
1391 const int prp = get_local_size(0);
1392 float4 value = (float4)(0.0f);
1395 while (i + 7 < width) {
1396 value += (float4)(filter[i]) * pixels[px + (py + i) * prp];
1397 value += (float4)(filter[i]) * pixels[px + (py + i + 1) * prp];
1398 value += (float4)(filter[i]) * pixels[px + (py + i + 2) * prp];
1399 value += (float4)(filter[i]) * pixels[px + (py + i + 3) * prp];
1400 value += (float4)(filter[i]) * pixels[px + (py + i + 4) * prp];
1401 value += (float4)(filter[i]) * pixels[px + (py + i + 5) * prp];
1402 value += (float4)(filter[i]) * pixels[px + (py + i + 6) * prp];
1403 value += (float4)(filter[i]) * pixels[px + (py + i + 7) * prp];
1407 value += (float4)(filter[i]) * pixels[px + (py + i) * prp];
1411 if (justBlur == 0) {
1412 float4 srcPixel = convert_float4(im[x + y * imageColumns]);
1413 float4 diff = srcPixel - value;
1417 int4 mask = isless(fabs(2.0f * diff), (float4)quantumThreshold);
1418 value = select(srcPixel + diff * gain, srcPixel, mask);
1421 if ((x < imageColumns) && (y < imageRows))
1429 __kernel
void HullPass1(
const __global CLPixelType *inputImage, __global CLPixelType *outputImage
1430 ,
const unsigned int imageWidth,
const unsigned int imageHeight
1431 ,
const int2 offset,
const int polarity,
const int matte) {
1433 int x = get_global_id(0);
1434 int y = get_global_id(1);
1436 CLPixelType v = inputImage[y*imageWidth+x];
1439 neighbor.y = y + offset.y;
1440 neighbor.x = x + offset.x;
1442 int2 clampedNeighbor;
1443 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1444 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1446 CLPixelType r = (clampedNeighbor.x == neighbor.x
1447 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1463 \n #pragma unroll 4\n
1464 for (
unsigned int i = 0; i < 4; i++) {
1465 sv[i] = (sr[i] >= (sv[i]+ScaleCharToQuantum(2)))?(sv[i]+ScaleCharToQuantum(1)):sv[i];
1469 \n #pragma unroll 4\n
1470 for (
unsigned int i = 0; i < 4; i++) {
1471 sv[i] = (sr[i] <= (sv[i]-ScaleCharToQuantum(2)))?(sv[i]-ScaleCharToQuantum(1)):sv[i];
1476 v.x = (CLQuantum)sv[0];
1477 v.y = (CLQuantum)sv[1];
1478 v.z = (CLQuantum)sv[2];
1481 v.w = (CLQuantum)sv[3];
1483 outputImage[y*imageWidth+x] = v;
1494 __kernel
void HullPass2(
const __global CLPixelType *inputImage, __global CLPixelType *outputImage
1495 ,
const unsigned int imageWidth,
const unsigned int imageHeight
1496 ,
const int2 offset,
const int polarity,
const int matte) {
1498 int x = get_global_id(0);
1499 int y = get_global_id(1);
1501 CLPixelType v = inputImage[y*imageWidth+x];
1503 int2 neighbor, clampedNeighbor;
1505 neighbor.y = y + offset.y;
1506 neighbor.x = x + offset.x;
1507 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1508 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1510 CLPixelType r = (clampedNeighbor.x == neighbor.x
1511 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1515 neighbor.y = y - offset.y;
1516 neighbor.x = x - offset.x;
1517 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1518 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1520 CLPixelType s = (clampedNeighbor.x == neighbor.x
1521 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1544 \n #pragma unroll 4\n
1545 for (
unsigned int i = 0; i < 4; i++) {
1550 sv[i] =(( (int)( ss[i] < (sv[i]+ScaleCharToQuantum(2))) + (int) ( sr[i] <= sv[i] ) ) !=0) ? sv[i]:(sv[i]+ScaleCharToQuantum(1));
1554 \n #pragma unroll 4\n
1555 for (
unsigned int i = 0; i < 4; i++) {
1559 sv[i] = (( (int)(ss[i] > (sv[i]-ScaleCharToQuantum(2))) + (int)( sr[i] >= sv[i] )) !=0) ? sv[i]:(sv[i]-ScaleCharToQuantum(1));
1563 v.x = (CLQuantum)sv[0];
1564 v.y = (CLQuantum)sv[1];
1565 v.z = (CLQuantum)sv[2];
1568 v.w = (CLQuantum)sv[3];
1570 outputImage[y*imageWidth+x] = v;
1579 __kernel
void RadialBlur(
const __global CLPixelType *im, __global CLPixelType *filtered_im,
1581 const unsigned int channel,
const unsigned int matte,
1582 const float2 blurCenter,
1583 __constant
float *cos_theta, __constant
float *sin_theta,
1584 const unsigned int cossin_theta_size)
1586 const int x = get_global_id(0);
1587 const int y = get_global_id(1);
1588 const int columns = get_global_size(0);
1589 const int rows = get_global_size(1);
1590 unsigned int step = 1;
1591 float center_x = (float) x - blurCenter.x;
1592 float center_y = (
float) y - blurCenter.y;
1593 float radius = hypot(center_x, center_y);
1596 float blur_radius = hypot(blurCenter.x, blurCenter.y);
1600 step = (
unsigned int) (blur_radius / radius);
1603 if (step >= cossin_theta_size)
1604 step = cossin_theta_size-1;
1608 result.x = (float)bias.x;
1609 result.y = (
float)bias.y;
1610 result.z = (float)bias.z;
1611 result.w = (
float)bias.w;
1612 float normalize = 0.0f;
1614 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
1615 for (
unsigned int i=0; i<cossin_theta_size; i+=step)
1617 result += convert_float4(im[
1618 ClampToCanvas(blurCenter.x+center_x*cos_theta[i]-center_y*sin_theta[i]+0.5f,columns)+
1619 ClampToCanvas(blurCenter.y+center_x*sin_theta[i]+center_y*cos_theta[i]+0.5f, rows)*columns]);
1623 result = result * normalize;
1627 for (
unsigned int i=0; i<cossin_theta_size; i+=step)
1629 float4 p = convert_float4(im[
1630 ClampToCanvas(blurCenter.x+center_x*cos_theta[i]-center_y*sin_theta[i]+0.5f,columns)+
1631 ClampToCanvas(blurCenter.y+center_x*sin_theta[i]+center_y*cos_theta[i]+0.5f, rows)*columns]);
1634 result.x += alpha * p.x;
1635 result.y += alpha * p.y;
1636 result.z += alpha * p.z;
1643 result.x = gamma*result.x;
1644 result.y = gamma*result.y;
1645 result.z = gamma*result.z;
1646 result.w = normalize*result.w;
1656 float3 HueSaturationBrightness;
1657 HueSaturationBrightness.x = 0.0f;
1658 HueSaturationBrightness.y = 0.0f;
1659 HueSaturationBrightness.z = 0.0f;
1661 float r=(float) getRed(pixel);
1662 float g=(float) getGreen(pixel);
1663 float b=(float) getBlue(pixel);
1665 float tmin=min(min(r,g),b);
1666 float tmax=max(max(r,g),b);
1669 float delta=tmax-tmin;
1670 HueSaturationBrightness.y=delta/tmax;
1673 if (delta != 0.0f) {
1674 HueSaturationBrightness.x = ((r == tmax)?0.0f:((g == tmax)?2.0f:4.0f));
1675 HueSaturationBrightness.x += ((r == tmax)?(g-b):((g == tmax)?(b-r):(r-g)))/delta;
1676 HueSaturationBrightness.x/=6.0f;
1677 HueSaturationBrightness.x += (HueSaturationBrightness.x < 0.0f)?0.0f:1.0f;
1680 return HueSaturationBrightness;
1685 float hue = HueSaturationBrightness.x;
1686 float brightness = HueSaturationBrightness.z;
1687 float saturation = HueSaturationBrightness.y;
1691 if (saturation == 0.0f) {
1693 setGreen(&rgb,getRed(rgb));
1694 setBlue(&rgb,getRed(rgb));
1698 float h=6.0f*(hue-floor(hue));
1700 float p=brightness*(1.0f-saturation);
1701 float q=brightness*(1.0f-saturation*f);
1702 float t=brightness*(1.0f-(saturation*(1.0f-f)));
1709 setRed(&rgb, (ih == 1)?clamped_q:
1710 (ih == 2 || ih == 3)?clamped_p:
1711 (ih == 4)?clamped_t:
1714 setGreen(&rgb, (ih == 1 || ih == 2)?clampedBrightness:
1715 (ih == 3)?clamped_q:
1716 (ih == 4 || ih == 5)?clamped_p:
1719 setBlue(&rgb, (ih == 2)?clamped_t:
1720 (ih == 3 || ih == 4)?clampedBrightness:
1721 (ih == 5)?clamped_q:
1727 __kernel
void Contrast(__global CLPixelType *im,
const unsigned int sharpen)
1730 const int sign = sharpen!=0?1:-1;
1731 const int x = get_global_id(0);
1732 const int y = get_global_id(1);
1733 const int columns = get_global_size(0);
1734 const int c = x + y * columns;
1736 CLPixelType pixel = im[c];
1738 float brightness = HueSaturationBrightness.z;
1739 brightness+=0.5f*sign*(0.5f*(sinpi(brightness-0.5f)+1.0f)-brightness);
1740 brightness = clamp(brightness,0.0f,1.0f);
1741 HueSaturationBrightness.z = brightness;
1744 filteredPixel.w = pixel.w;
1745 im[c] = filteredPixel;
1753 inline void ConvertRGBToHSL(
const CLQuantum red,
const CLQuantum green,
const CLQuantum blue,
1754 float *hue,
float *saturation,
float *lightness)
1769 *lightness=(tmax+tmin)/2.0;
1790 if (*lightness <= 0.5)
1791 *saturation=c/(2.0*(*lightness));
1793 *saturation=c/(2.0-2.0*(*lightness));
1796 inline void ConvertHSLToRGB(
const float hue,
const float saturation,
const float lightness,
1797 CLQuantum *red,CLQuantum *green,CLQuantum *blue)
1812 if (lightness <= 0.5)
1813 c=2.0*lightness*saturation;
1815 c=(2.0-2.0*lightness)*saturation;
1816 tmin=lightness-0.5*c;
1817 h-=360.0*floor(h/360.0);
1819 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
1820 switch ((
int) floor(h))
1876 inline void ModulateHSL(
const float percent_hue,
const float percent_saturation,
const float percent_lightness,
1877 CLQuantum *red,CLQuantum *green,CLQuantum *blue)
1888 hue+=0.5*(0.01*percent_hue-1.0);
1893 saturation*=0.01*percent_saturation;
1894 lightness*=0.01*percent_lightness;
1898 __kernel
void Modulate(__global CLPixelType *im,
1899 const float percent_brightness,
1900 const float percent_hue,
1901 const float percent_saturation,
1902 const int colorspace)
1905 const int x = get_global_id(0);
1906 const int y = get_global_id(1);
1907 const int columns = get_global_size(0);
1908 const int c = x + y * columns;
1910 CLPixelType pixel = im[c];
1918 green=getGreen(pixel);
1919 blue=getBlue(pixel);
1926 ModulateHSL(percent_hue, percent_saturation, percent_brightness,
1927 &red, &green, &blue);
1932 CLPixelType filteredPixel;
1934 setRed(&filteredPixel, red);
1935 setGreen(&filteredPixel, green);
1936 setBlue(&filteredPixel, blue);
1937 filteredPixel.w = pixel.w;
1939 im[c] = filteredPixel;
1944 __kernel
void Grayscale(__global CLPixelType *im,
1945 const int method,
const int colorspace)
1948 const int x = get_global_id(0);
1949 const int y = get_global_id(1);
1950 const int columns = get_global_size(0);
1951 const int c = x + y * columns;
1953 CLPixelType pixel = im[c];
1961 red=(float)getRed(pixel);
1962 green=(float)getGreen(pixel);
1963 blue=(float)getBlue(pixel);
1967 CLPixelType filteredPixel;
1973 intensity=(red+green+blue)/3.0;
1978 intensity=max(max(red,green),blue);
1983 intensity=(min(min(red,green),blue)+
1984 max(max(red,green),blue))/2.0;
1989 intensity=(float) (((
float) red*red+green*green+
2003 intensity=0.298839*red+0.586811*green+0.114350*blue;
2016 intensity=0.298839*red+0.586811*green+0.114350*blue;
2030 intensity=0.212656*red+0.715158*green+0.072186*blue;
2043 intensity=0.212656*red+0.715158*green+0.072186*blue;
2048 intensity=(float) (sqrt((
float) red*red+green*green+
2049 blue*blue)/sqrt(3.0));
2057 filteredPixel.w = pixel.w;
2059 im[c] = filteredPixel;
2065 float BoxResizeFilter(
const float x)
2073 float CubicBC(
const float x,
const __global
float* resizeFilterCoefficients)
2105 return(resizeFilterCoefficients[0]+x*(x*
2106 (resizeFilterCoefficients[1]+x*resizeFilterCoefficients[2])));
2108 return(resizeFilterCoefficients[3]+x*(resizeFilterCoefficients[4]+x*
2109 (resizeFilterCoefficients[5]+x*resizeFilterCoefficients[6])));
2115 float Sinc(
const float x)
2119 const float alpha=(float) (
MagickPI*x);
2120 return sinpi(x)/alpha;
2134 return ((x<1.0f)?(1.0f-x):0.0f);
2146 const float cosine=cos((
MagickPI*x));
2147 return(0.5f+0.5f*cosine);
2158 const float cosine=cos((
MagickPI*x));
2159 return(0.54f+0.46f*cosine);
2173 const float cosine=cos((
MagickPI*x));
2174 return(0.34f+cosine*(0.5f+cosine*0.16f));
2201 inline float applyResizeFilter(
const float x,
const ResizeWeightingFunctionType filterType,
const __global
float* filterCoefficients)
2211 return CubicBC(x,filterCoefficients);
2213 return BoxResizeFilter(x);
2231 inline float getResizeFilterWeight(
const __global
float* resizeFilterCubicCoefficients,
const ResizeWeightingFunctionType resizeFilterType
2232 ,
const ResizeWeightingFunctionType resizeWindowType
2233 ,
const float resizeFilterScale,
const float resizeWindowSupport,
const float resizeFilterBlur,
const float x)
2236 float xBlur = fabs(x/resizeFilterBlur);
2244 scale = resizeFilterScale;
2245 scale = applyResizeFilter(xBlur*scale, resizeWindowType, resizeFilterCubicCoefficients);
2247 float weight = scale * applyResizeFilter(xBlur, resizeFilterType, resizeFilterCubicCoefficients);
2254 const char* accelerateKernels2 =
2258 inline unsigned int getNumWorkItemsPerPixel(
const unsigned int pixelPerWorkgroup,
const unsigned int numWorkItems) {
2259 return (numWorkItems/pixelPerWorkgroup);
2264 inline int pixelToCompute(
const unsigned itemID,
const unsigned int pixelPerWorkgroup,
const unsigned int numWorkItems) {
2265 const unsigned int numWorkItemsPerPixel = getNumWorkItemsPerPixel(pixelPerWorkgroup, numWorkItems);
2266 int pixelIndex = itemID/numWorkItemsPerPixel;
2267 pixelIndex = (pixelIndex<pixelPerWorkgroup)?pixelIndex:-1;
2274 __kernel __attribute__((reqd_work_group_size(256, 1, 1)))
2275 void ResizeHorizontalFilter(
const __global CLPixelType* inputImage,
const unsigned int inputColumns,
const unsigned int inputRows,
const unsigned int matte
2276 ,
const float xFactor, __global CLPixelType* filteredImage,
const unsigned int filteredColumns,
const unsigned int filteredRows
2277 ,
const int resizeFilterType,
const int resizeWindowType
2278 ,
const __global
float* resizeFilterCubicCoefficients
2279 ,
const float resizeFilterScale,
const float resizeFilterSupport,
const float resizeFilterWindowSupport,
const float resizeFilterBlur
2280 , __local CLPixelType* inputImageCache,
const int numCachedPixels,
const unsigned int pixelPerWorkgroup,
const unsigned int pixelChunkSize
2281 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2285 const unsigned int startX = get_group_id(0)*pixelPerWorkgroup;
2286 const unsigned int stopX = min(startX + pixelPerWorkgroup,filteredColumns);
2287 const unsigned int actualNumPixelToCompute = stopX - startX;
2291 const float support = max(scale*resizeFilterSupport,0.5f);
2294 const int cacheRangeStartX = max((
int)((startX+0.5f)/xFactor+
MagickEpsilon-support+0.5f),(
int)(0));
2295 const int cacheRangeEndX = min((
int)(cacheRangeStartX + numCachedPixels), (
int)inputColumns);
2298 const unsigned int y = get_global_id(1);
2299 event_t e = async_work_group_copy(inputImageCache,inputImage+y*inputColumns+cacheRangeStartX,cacheRangeEndX-cacheRangeStartX,0);
2300 wait_group_events(1,&e);
2302 unsigned int totalNumChunks = (actualNumPixelToCompute+pixelChunkSize-1)/pixelChunkSize;
2303 for (
unsigned int chunk = 0; chunk < totalNumChunks; chunk++)
2306 const unsigned int chunkStartX = startX + chunk*pixelChunkSize;
2307 const unsigned int chunkStopX = min(chunkStartX + pixelChunkSize, stopX);
2308 const unsigned int actualNumPixelInThisChunk = chunkStopX - chunkStartX;
2311 const unsigned int itemID = get_local_id(0);
2312 const unsigned int numItems = getNumWorkItemsPerPixel(actualNumPixelInThisChunk, get_local_size(0));
2314 const int pixelIndex = pixelToCompute(itemID, actualNumPixelInThisChunk, get_local_size(0));
2316 float4 filteredPixel = (float4)0.0f;
2317 float density = 0.0f;
2320 if (pixelIndex != -1) {
2323 const int x = chunkStartX + pixelIndex;
2327 const unsigned int start = (
unsigned int)max(bisect-support+0.5f,0.0f);
2328 const unsigned int stop = (
unsigned int)min(bisect+support+0.5f,(
float)inputColumns);
2329 const unsigned int n = stop - start;
2332 unsigned int numStepsPerWorkItem = n / numItems;
2333 numStepsPerWorkItem += ((numItems*numStepsPerWorkItem)==n?0:1);
2335 const unsigned int startStep = (itemID%numItems)*numStepsPerWorkItem;
2336 if (startStep < n) {
2337 const unsigned int stopStep = min(startStep+numStepsPerWorkItem, n);
2339 unsigned int cacheIndex = start+startStep-cacheRangeStartX;
2342 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2343 float4 cp = convert_float4(inputImageCache[cacheIndex]);
2345 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2346 , (ResizeWeightingFunctionType)resizeWindowType
2347 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2349 filteredPixel += ((float4)weight)*cp;
2356 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2357 CLPixelType p = inputImageCache[cacheIndex];
2359 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2360 , (ResizeWeightingFunctionType)resizeWindowType
2361 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2364 float4 cp = convert_float4(p);
2366 filteredPixel.x += alpha * cp.x;
2367 filteredPixel.y += alpha * cp.y;
2368 filteredPixel.z += alpha * cp.z;
2369 filteredPixel.w += weight * cp.w;
2379 if (itemID < actualNumPixelInThisChunk) {
2380 outputPixelCache[itemID] = (float4)0.0f;
2381 densityCache[itemID] = 0.0f;
2383 gammaCache[itemID] = 0.0f;
2385 barrier(CLK_LOCAL_MEM_FENCE);
2388 for (
unsigned int i = 0; i < numItems; i++) {
2389 if (pixelIndex != -1) {
2390 if (itemID%numItems == i) {
2391 outputPixelCache[pixelIndex]+=filteredPixel;
2392 densityCache[pixelIndex]+=density;
2394 gammaCache[pixelIndex]+=gamma;
2398 barrier(CLK_LOCAL_MEM_FENCE);
2401 if (itemID < actualNumPixelInThisChunk) {
2403 float density = densityCache[itemID];
2404 float4 filteredPixel = outputPixelCache[itemID];
2405 if (density!= 0.0f && density != 1.0)
2408 filteredPixel *= (float4)density;
2410 filteredImage[y*filteredColumns+chunkStartX+itemID] = (CLPixelType) (
ClampToQuantum(filteredPixel.x)
2416 float density = densityCache[itemID];
2417 float gamma = gammaCache[itemID];
2418 float4 filteredPixel = outputPixelCache[itemID];
2420 if (density!= 0.0f && density != 1.0) {
2422 filteredPixel *= (float4)density;
2433 filteredImage[y*filteredColumns+chunkStartX+itemID] = fp;
2445 __kernel __attribute__((reqd_work_group_size(256, 1, 1)))
2446 void ResizeHorizontalFilterSinc(
const __global CLPixelType* inputImage,
const unsigned int inputColumns,
const unsigned int inputRows,
const unsigned int matte
2447 ,
const float xFactor, __global CLPixelType* filteredImage,
const unsigned int filteredColumns,
const unsigned int filteredRows
2448 ,
const int resizeFilterType,
const int resizeWindowType
2449 ,
const __global
float* resizeFilterCubicCoefficients
2450 ,
const float resizeFilterScale,
const float resizeFilterSupport,
const float resizeFilterWindowSupport,
const float resizeFilterBlur
2451 , __local CLPixelType* inputImageCache,
const int numCachedPixels,
const unsigned int pixelPerWorkgroup,
const unsigned int pixelChunkSize
2452 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2454 ResizeHorizontalFilter(inputImage,inputColumns,inputRows,matte
2455 ,xFactor, filteredImage, filteredColumns, filteredRows
2457 ,resizeFilterCubicCoefficients
2458 ,resizeFilterScale, resizeFilterSupport, resizeFilterWindowSupport, resizeFilterBlur
2459 ,inputImageCache, numCachedPixels, pixelPerWorkgroup, pixelChunkSize
2460 ,outputPixelCache, densityCache, gammaCache);
2467 __kernel __attribute__((reqd_work_group_size(1, 256, 1)))
2468 void ResizeVerticalFilter(const __global CLPixelType* inputImage, const
unsigned int inputColumns, const
unsigned int inputRows, const
unsigned int matte
2469 , const
float yFactor, __global CLPixelType* filteredImage, const
unsigned int filteredColumns, const
unsigned int filteredRows
2470 , const
int resizeFilterType, const
int resizeWindowType
2471 , const __global
float* resizeFilterCubicCoefficients
2472 , const
float resizeFilterScale, const
float resizeFilterSupport, const
float resizeFilterWindowSupport, const
float resizeFilterBlur
2473 , __local CLPixelType* inputImageCache, const
int numCachedPixels, const
unsigned int pixelPerWorkgroup, const
unsigned int pixelChunkSize
2474 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2478 const unsigned int startY = get_group_id(1)*pixelPerWorkgroup;
2479 const unsigned int stopY = min(startY + pixelPerWorkgroup,filteredRows);
2480 const unsigned int actualNumPixelToCompute = stopY - startY;
2483 float scale = max(1.0f/yFactor+MagickEpsilon ,1.0f);
2484 const float support = max(scale*resizeFilterSupport,0.5f);
2487 const int cacheRangeStartY = max((
int)((startY+0.5f)/yFactor+MagickEpsilon-support+0.5f),(
int)(0));
2488 const int cacheRangeEndY = min((
int)(cacheRangeStartY + numCachedPixels), (
int)inputRows);
2491 const unsigned int x = get_global_id(0);
2492 event_t e = async_work_group_strided_copy(inputImageCache, inputImage+cacheRangeStartY*inputColumns+x, cacheRangeEndY-cacheRangeStartY, inputColumns, 0);
2493 wait_group_events(1,&e);
2495 unsigned int totalNumChunks = (actualNumPixelToCompute+pixelChunkSize-1)/pixelChunkSize;
2496 for (
unsigned int chunk = 0; chunk < totalNumChunks; chunk++)
2499 const unsigned int chunkStartY = startY + chunk*pixelChunkSize;
2500 const unsigned int chunkStopY = min(chunkStartY + pixelChunkSize, stopY);
2501 const unsigned int actualNumPixelInThisChunk = chunkStopY - chunkStartY;
2504 const unsigned int itemID = get_local_id(1);
2505 const unsigned int numItems = getNumWorkItemsPerPixel(actualNumPixelInThisChunk, get_local_size(1));
2507 const int pixelIndex = pixelToCompute(itemID, actualNumPixelInThisChunk, get_local_size(1));
2509 float4 filteredPixel = (float4)0.0f;
2510 float density = 0.0f;
2513 if (pixelIndex != -1) {
2516 const int y = chunkStartY + pixelIndex;
2520 const unsigned int start = (
unsigned int)max(bisect-support+0.5f,0.0f);
2521 const unsigned int stop = (
unsigned int)min(bisect+support+0.5f,(
float)inputRows);
2522 const unsigned int n = stop - start;
2525 unsigned int numStepsPerWorkItem = n / numItems;
2526 numStepsPerWorkItem += ((numItems*numStepsPerWorkItem)==n?0:1);
2528 const unsigned int startStep = (itemID%numItems)*numStepsPerWorkItem;
2529 if (startStep < n) {
2530 const unsigned int stopStep = min(startStep+numStepsPerWorkItem, n);
2532 unsigned int cacheIndex = start+startStep-cacheRangeStartY;
2535 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2536 float4 cp = convert_float4(inputImageCache[cacheIndex]);
2538 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2539 , (ResizeWeightingFunctionType)resizeWindowType
2540 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2542 filteredPixel += ((float4)weight)*cp;
2549 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2550 CLPixelType p = inputImageCache[cacheIndex];
2552 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2553 , (ResizeWeightingFunctionType)resizeWindowType
2554 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2557 float4 cp = convert_float4(p);
2559 filteredPixel.x += alpha * cp.x;
2560 filteredPixel.y += alpha * cp.y;
2561 filteredPixel.z += alpha * cp.z;
2562 filteredPixel.w += weight * cp.w;
2572 if (itemID < actualNumPixelInThisChunk) {
2573 outputPixelCache[itemID] = (float4)0.0f;
2574 densityCache[itemID] = 0.0f;
2576 gammaCache[itemID] = 0.0f;
2578 barrier(CLK_LOCAL_MEM_FENCE);
2581 for (
unsigned int i = 0; i < numItems; i++) {
2582 if (pixelIndex != -1) {
2583 if (itemID%numItems == i) {
2584 outputPixelCache[pixelIndex]+=filteredPixel;
2585 densityCache[pixelIndex]+=density;
2587 gammaCache[pixelIndex]+=gamma;
2591 barrier(CLK_LOCAL_MEM_FENCE);
2594 if (itemID < actualNumPixelInThisChunk) {
2596 float density = densityCache[itemID];
2597 float4 filteredPixel = outputPixelCache[itemID];
2598 if (density!= 0.0f && density != 1.0)
2601 filteredPixel *= (float4)density;
2603 filteredImage[(chunkStartY+itemID)*filteredColumns+x] = (CLPixelType) (
ClampToQuantum(filteredPixel.x)
2609 float density = densityCache[itemID];
2610 float gamma = gammaCache[itemID];
2611 float4 filteredPixel = outputPixelCache[itemID];
2613 if (density!= 0.0f && density != 1.0) {
2615 filteredPixel *= (float4)density;
2626 filteredImage[(chunkStartY+itemID)*filteredColumns+x] = fp;
2638 __kernel __attribute__((reqd_work_group_size(1, 256, 1)))
2639 void ResizeVerticalFilterSinc(const __global CLPixelType* inputImage, const
unsigned int inputColumns, const
unsigned int inputRows, const
unsigned int matte
2640 , const
float yFactor, __global CLPixelType* filteredImage, const
unsigned int filteredColumns, const
unsigned int filteredRows
2641 , const
int resizeFilterType, const
int resizeWindowType
2642 , const __global
float* resizeFilterCubicCoefficients
2643 , const
float resizeFilterScale, const
float resizeFilterSupport, const
float resizeFilterWindowSupport, const
float resizeFilterBlur
2644 , __local CLPixelType* inputImageCache, const
int numCachedPixels, const
unsigned int pixelPerWorkgroup, const
unsigned int pixelChunkSize
2645 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2646 ResizeVerticalFilter(inputImage,inputColumns,inputRows,matte
2647 ,yFactor,filteredImage,filteredColumns,filteredRows
2649 ,resizeFilterCubicCoefficients
2650 ,resizeFilterScale,resizeFilterSupport,resizeFilterWindowSupport,resizeFilterBlur
2651 ,inputImageCache,numCachedPixels,pixelPerWorkgroup,pixelChunkSize
2652 ,outputPixelCache,densityCache,gammaCache);
2676 ulong MWC_AddMod64(ulong a, ulong b, ulong M)
2680 if( (v>=M) || (convert_float(v) < convert_float(a)) )
2691 ulong MWC_MulMod64(ulong a, ulong b, ulong M)
2696 r=MWC_AddMod64(r,b,M);
2697 b=MWC_AddMod64(b,b,M);
2708 ulong MWC_PowMod64(ulong a, ulong e, ulong M)
2713 acc=MWC_MulMod64(acc,sqr,M);
2714 sqr=MWC_MulMod64(sqr,sqr,M);
2720 uint2 MWC_SkipImpl_Mod64(uint2 curr, ulong A, ulong M, ulong distance)
2722 ulong m=MWC_PowMod64(A, distance, M);
2723 ulong x=curr.x*(ulong)A+curr.y;
2724 x=MWC_MulMod64(x, m, M);
2725 return (uint2)((uint)(x/A), (uint)(x%A));
2728 uint2 MWC_SeedImpl_Mod64(ulong A, ulong M, uint vecSize, uint vecOffset, ulong streamBase, ulong streamGap)
2735 enum{ MWC_BASEID = 4077358422479273989UL };
2737 ulong dist=streamBase + (get_global_id(0)*vecSize+vecOffset)*streamGap;
2738 ulong m=MWC_PowMod64(A, dist, M);
2740 ulong x=MWC_MulMod64(MWC_BASEID, m, M);
2741 return (uint2)((uint)(x/A), (uint)(x%A));
2745 typedef struct{ uint x; uint c; } mwc64x_state_t;
2747 enum{ MWC64X_A = 4294883355U };
2748 enum{ MWC64X_M = 18446383549859758079UL };
2750 void MWC64X_Step(mwc64x_state_t *s)
2752 uint X=s->x, C=s->c;
2754 uint Xn=MWC64X_A*X+C;
2755 uint carry=(uint)(Xn<C);
2756 uint Cn=mad_hi(MWC64X_A,X,carry);
2762 void MWC64X_Skip(mwc64x_state_t *s, ulong distance)
2764 uint2 tmp=MWC_SkipImpl_Mod64((uint2)(s->x,s->c), MWC64X_A, MWC64X_M, distance);
2769 void MWC64X_SeedStreams(mwc64x_state_t *s, ulong baseOffset, ulong perStreamOffset)
2771 uint2 tmp=MWC_SeedImpl_Mod64(MWC64X_A, MWC64X_M, 1, 0, baseOffset, perStreamOffset);
2777 uint MWC64X_NextUint(mwc64x_state_t *s)
2779 uint res=s->x ^ s->c;
2802 float mwcReadPseudoRandomValue(mwc64x_state_t* rng) {
2803 return (1.0f * MWC64X_NextUint(rng)) / (float)(0xffffffff);
2807 float mwcGenerateDifferentialNoise(mwc64x_state_t* r, CLQuantum pixel, NoiseType noise_type,
float attenuate) {
2816 alpha=mwcReadPseudoRandomValue(r);
2817 switch(noise_type) {
2832 beta=mwcReadPseudoRandomValue(r);
2833 gamma=sqrt(-2.0f*log(alpha));
2834 sigma=gamma*cospi((2.0f*beta));
2835 tau=gamma*sinpi((2.0f*beta));
2836 noise=(float)(pixel+sqrt((
float) pixel)*
SigmaGaussian*sigma+
2857 if (alpha <= MagickEpsilon)
2865 if (beta <= (0.5f*MagickEpsilon))
2874 if (alpha > MagickEpsilon)
2875 sigma=sqrt(-2.0f*log(alpha));
2876 beta=mwcReadPseudoRandomValue(r);
2878 cospi((
float) (2.0f*beta))/2.0f);
2887 for (i=0; alpha > poisson; i++)
2889 beta=mwcReadPseudoRandomValue(r);
2910 void GenerateNoiseImage(
const __global CLPixelType* inputImage, __global CLPixelType* filteredImage
2911 ,
const unsigned int inputPixelCount,
const unsigned int pixelsPerWorkItem
2913 ,
const NoiseType noise_type,
const float attenuate
2914 ,
const unsigned int seed0,
const unsigned int seed1
2915 ,
const unsigned int numRandomNumbersPerPixel) {
2921 uint span = pixelsPerWorkItem * numRandomNumbersPerPixel;
2922 uint offset = span * get_local_size(0) * get_group_id(0);
2924 MWC64X_SeedStreams(&rng, offset, span);
2926 uint pos = get_local_size(0) * get_group_id(0) * pixelsPerWorkItem + get_local_id(0);
2928 uint count = pixelsPerWorkItem;
2931 if (pos < inputPixelCount) {
2932 CLPixelType p = inputImage[pos];
2934 if ((channel&RedChannel)!=0) {
2935 setRed(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getRed(p),noise_type,attenuate)));
2938 if ((channel&GreenChannel)!=0) {
2939 setGreen(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getGreen(p),noise_type,attenuate)));
2942 if ((channel&BlueChannel)!=0) {
2943 setBlue(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getBlue(p),noise_type,attenuate)));
2946 if ((channel & OpacityChannel) != 0) {
2947 setOpacity(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getOpacity(p),noise_type,attenuate)));
2950 filteredImage[pos] = p;
2953 pos += get_local_size(0);
2962 void MotionBlur(
const __global CLPixelType *input, __global CLPixelType *output,
2963 const unsigned int imageWidth,
const unsigned int imageHeight,
2964 const __global
float *filter,
const unsigned int width,
const __global int2* offset,
2966 const ChannelType channel,
const unsigned int matte) {
2969 currentPixel.x = get_global_id(0);
2970 currentPixel.y = get_global_id(1);
2972 if (currentPixel.x >= imageWidth
2973 || currentPixel.y >= imageHeight)
2977 pixel.x = (float)bias.x;
2978 pixel.y = (
float)bias.y;
2979 pixel.z = (float)bias.z;
2980 pixel.w = (
float)bias.w;
2982 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
2984 for (
int i = 0; i < width; i++) {
2987 int2 samplePixel = currentPixel + offset[i];
2988 samplePixel.x = ClampToCanvas(samplePixel.x, imageWidth);
2989 samplePixel.y = ClampToCanvas(samplePixel.y, imageHeight);
2990 CLPixelType samplePixelValue = input[ samplePixel.y * imageWidth + samplePixel.x];
2992 pixel.x += (filter[i] * (float)samplePixelValue.x);
2993 pixel.y += (filter[i] * (float)samplePixelValue.y);
2994 pixel.z += (filter[i] * (float)samplePixelValue.z);
2995 pixel.w += (filter[i] * (float)samplePixelValue.w);
2998 CLPixelType outputPixel;
3003 output[currentPixel.y * imageWidth + currentPixel.x] = outputPixel;
3008 for (
int i = 0; i < width; i++) {
3011 int2 samplePixel = currentPixel + offset[i];
3012 samplePixel.x = ClampToCanvas(samplePixel.x, imageWidth);
3013 samplePixel.y = ClampToCanvas(samplePixel.y, imageHeight);
3015 CLPixelType samplePixelValue = input[ samplePixel.y * imageWidth + samplePixel.x];
3018 float k = filter[i];
3019 pixel.x = pixel.x + k * alpha * samplePixelValue.x;
3020 pixel.y = pixel.y + k * alpha * samplePixelValue.y;
3021 pixel.z = pixel.z + k * alpha * samplePixelValue.z;
3023 pixel.w += k * alpha * samplePixelValue.w;
3028 pixel.xyz = gamma*pixel.xyz;
3030 CLPixelType outputPixel;
3035 output[currentPixel.y * imageWidth + currentPixel.x] = outputPixel;
3120 const float Sa,
const float Dca,
const float Da)
3125 if ((Sca*Da+Dca*Sa) >= Sa*Da)
3126 return(Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa));
3127 return(Dca*Sa*Sa/(Sa-Sca)+Sca*(1.0-Da)+Dca*(1.0-Sa));
3161 const float4 *q,float4 *composite) {
3172 gamma=
QuantumRange/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
3174 getRedF4(*q)*Da,Da));
3176 getGreenF4(*q)*Da,Da));
3178 getBlueF4(*q)*Da,Da));
3184 const float alpha,
const float4 *q,
3185 const float beta,float4 *composite)
3199 setOpacityF4(composite,(
float)
QuantumRange*(1.0-gamma));
3201 setRedF4(composite,gamma*(Sa*getRedF4(*p)+Da*getRedF4(*q)));
3202 setGreenF4(composite,gamma*(Sa*getGreenF4(*p)+Da*getGreenF4(*q)));
3203 setBlueF4(composite,gamma*(Sa*getBlueF4(*p)+Da*getBlueF4(*q)));
3209 const float alpha,
const float4 *q,
3210 const float beta,float4 *composite)
3220 void Composite(__global CLPixelType *image,
3221 const unsigned int imageWidth,
3222 const unsigned int imageHeight,
3223 const __global CLPixelType *compositeImage,
3224 const unsigned int compositeWidth,
3225 const unsigned int compositeHeight,
3226 const unsigned int compose,
3228 const unsigned int matte,
3229 const float destination_dissolve,
3230 const float source_dissolve) {
3233 index.x = get_global_id(0);
3234 index.y = get_global_id(1);
3237 if (index.x >= imageWidth
3238 || index.y >= imageHeight) {
3241 const CLPixelType inputPixel = image[index.y*imageWidth+index.x];
3243 setRedF4(&destination,getRed(inputPixel));
3244 setGreenF4(&destination,getGreen(inputPixel));
3245 setBlueF4(&destination,getBlue(inputPixel));
3248 const CLPixelType compositePixel
3249 = compositeImage[index.y*imageWidth+index.x];
3251 setRedF4(&source,getRed(compositePixel));
3252 setGreenF4(&source,getGreen(compositePixel));
3253 setBlueF4(&source,getBlue(compositePixel));
3256 setOpacityF4(&destination,getOpacity(inputPixel));
3257 setOpacityF4(&source,getOpacity(compositePixel));
3260 setOpacityF4(&destination,0.0f);
3261 setOpacityF4(&source,0.0f);
3264 float4 composite=destination;
3273 destination_dissolve,&composite);
3280 CLPixelType outputPixel;
3284 setOpacity(&outputPixel,
ClampToQuantum(getOpacityF4(composite)));
3285 image[index.y*imageWidth+index.x] = outputPixel;
3291 #endif // MAGICKCORE_OPENCL_SUPPORT 3293 #if defined(__cplusplus) || defined(c_plusplus) 3297 #endif // _MAGICKCORE_ACCELERATE_PRIVATE_H Definition: composite.h:91
Definition: composite.h:94
Definition: composite.h:65
Definition: colorspace.h:44
Definition: resize-private.h:31
Definition: colorspace.h:36
Definition: resize-private.h:37
Definition: statistic.h:115
Definition: resize-private.h:33
Definition: magick-type.h:201
Definition: composite.h:75
Definition: colorspace.h:40
static void MagickPixelCompositeBlend(const MagickPixelPacket *p, const MagickRealType alpha, const MagickPixelPacket *q, const MagickRealType beta, MagickPixelPacket *composite)
Definition: composite-private.h:137
Definition: composite.h:31
Definition: composite.h:93
MagickExport MagickBooleanType FunctionImage(Image *image, const MagickFunction function, const size_t number_parameters, const double *parameters, ExceptionInfo *exception)
Definition: statistic.c:1029
Definition: colorspace.h:45
Definition: colorspace.h:33
Definition: composite.h:80
Definition: composite.h:33
Definition: resize-private.h:40
Definition: composite.h:90
Definition: resize-private.h:29
static MagickRealType ColorDodge(const MagickRealType Sca, const MagickRealType Sa, const MagickRealType Dca, const MagickRealType Da)
Definition: composite.c:306
PixelIntensityMethod
Definition: pixel.h:67
Definition: magick-type.h:190
Definition: composite.h:95
Definition: colorspace.h:59
Definition: magick-type.h:196
Definition: composite.h:59
Definition: composite.h:89
Definition: magick-type.h:185
Definition: composite.h:27
Definition: colorspace.h:41
Definition: colorspace.h:37
static MagickRealType RoundToUnity(const MagickRealType value)
Definition: composite-private.h:33
Definition: composite.h:35
Definition: composite.h:87
#define MagickPI
Definition: image-private.h:26
Definition: colorspace.h:58
Definition: colorspace.h:50
static MagickRealType Hanning(const MagickRealType x, const ResizeFilter *magick_unused(resize_filter))
Definition: resize.c:287
Definition: colorspace.h:47
float MagickRealType
Definition: magick-type.h:79
Definition: statistic.h:114
Definition: colorspace.h:31
#define MAGICKCORE_QUANTUM_DEPTH
Definition: magick-type.h:28
Definition: composite.h:53
Definition: colorspace.h:35
Definition: resize-private.h:38
#define MagickEpsilon
Definition: magick-type.h:142
MagickExport void ConvertRGBToHSL(const Quantum red, const Quantum green, const Quantum blue, double *hue, double *saturation, double *lightness)
Definition: gem.c:1142
Definition: magick-type.h:191
Definition: colorspace.h:48
Definition: statistic.h:116
Definition: magick-type.h:203
NoiseType
Definition: fx.h:27
Definition: colorspace.h:52
Definition: composite.h:47
static MagickRealType Hamming(const MagickRealType x, const ResizeFilter *magick_unused(resize_filter))
Definition: resize.c:301
Definition: resize-private.h:41
Definition: composite.h:73
Definition: composite.h:29
Definition: composite.h:72
Definition: composite.h:42
Definition: colorspace.h:43
Definition: composite.h:97
static void ModulateHSL(const double percent_hue, const double percent_saturation, const double percent_lightness, Quantum *red, Quantum *green, Quantum *blue)
Definition: enhance.c:3552
Definition: colorspace.h:34
Definition: colorspace.h:57
Definition: resize-private.h:30
Definition: composite.h:54
#define GetPixelAlpha(pixel)
Definition: pixel-accessor.h:36
Definition: composite.h:38
Definition: composite.h:68
Definition: composite.h:96
Definition: magick-type.h:187
Definition: composite.h:71
Definition: resize-private.h:32
Definition: composite.h:55
Definition: composite.h:56
Definition: composite.h:69
static Quantum ApplyFunction(Quantum pixel, const MagickFunction function, const size_t number_parameters, const double *parameters, ExceptionInfo *exception)
Definition: statistic.c:947
Definition: colorspace.h:38
Definition: composite.h:86
Definition: resize-private.h:36
Definition: colorspace.h:30
#define SigmaMultiplicativeGaussian
Definition: composite.h:49
Definition: composite.h:44
MagickExport void ConvertRGBToHSB(const Quantum red, const Quantum green, const Quantum blue, double *hue, double *saturation, double *brightness)
Definition: gem.c:1009
Definition: magick-type.h:189
static void Contrast(const int sign, Quantum *red, Quantum *green, Quantum *blue)
Definition: enhance.c:913
Definition: magick-type.h:204
Definition: composite.h:46
Definition: statistic.h:112
Definition: composite.h:28
Definition: magick-type.h:184
Definition: magick-type.h:193
Definition: colorspace.h:54
Definition: magick-type.h:192
Definition: resize-private.h:39
Definition: composite.h:78
Definition: resize-private.h:34
#define QuantumScale
Definition: magick-type.h:145
Definition: colorspace.h:55
Definition: composite.h:62
MagickExport MagickRealType GetPixelIntensity(const Image *image, const PixelPacket *restrict pixel)
Definition: pixel.c:2106
Definition: colorspace.h:39
#define MaxMap
Definition: magick-type.h:73
Definition: magick-type.h:200
Definition: composite.h:98
Definition: composite.h:39
static void CompositeColorDodge(const MagickPixelPacket *p, const MagickPixelPacket *q, MagickPixelPacket *composite)
Definition: composite.c:343
MagickExport void ConvertHSBToRGB(const double hue, const double saturation, const double brightness, Quantum *red, Quantum *green, Quantum *blue)
Definition: gem.c:284
Definition: composite.h:45
ChannelType
Definition: magick-type.h:180
Definition: composite.h:70
Definition: colorspace.h:46
Definition: resize-private.h:28
Definition: composite.h:81
Definition: composite.h:41
Definition: composite.h:52
Definition: colorspace.h:49
MagickExport void ConvertHSLToRGB(const double hue, const double saturation, const double lightness, Quantum *red, Quantum *green, Quantum *blue)
Definition: gem.c:460
Definition: composite.h:77
static Quantum ClampToQuantum(const MagickRealType value)
Definition: quantum.h:87
Definition: colorspace.h:53
Definition: composite.h:61
Definition: magick-type.h:186
static void MagickPixelCompositePlus(const MagickPixelPacket *p, const MagickRealType alpha, const MagickPixelPacket *q, const MagickRealType beta, MagickPixelPacket *composite)
Definition: composite-private.h:108
Definition: composite.h:76
Definition: magick-type.h:182
Definition: colorspace.h:28
Definition: resize-private.h:42
Definition: composite.h:50
Definition: composite.h:36
Definition: composite.h:43
Definition: composite.h:37
static MagickRealType Sinc(const MagickRealType, const ResizeFilter *)
Definition: composite.h:60
Definition: statistic.h:113
ResizeWeightingFunctionType
Definition: resize-private.h:25
static MagickRealType Blackman(const MagickRealType x, const ResizeFilter *magick_unused(resize_filter))
Definition: resize.c:148
Definition: colorspace.h:56
ColorspaceType
Definition: colorspace.h:25
Definition: composite.h:32
Definition: colorspace.h:29
Definition: composite.h:88
Definition: colorspace.h:42
Definition: composite.h:48
Definition: composite.h:64
Definition: magick-type.h:188
Definition: colorspace.h:51
CompositeOperator
Definition: composite.h:25
Definition: composite.h:79
Definition: magick-type.h:195
Definition: colorspace.h:32
Definition: composite.h:66
Definition: composite.h:30
Definition: colorspace.h:60
Definition: magick-type.h:183
Definition: composite.h:63
Definition: composite.h:58
Definition: composite.h:92
Definition: magick-type.h:202
Definition: composite.h:34
static double PerceptibleReciprocal(const double x)
Definition: pixel-private.h:78
static MagickRealType CubicBC(const MagickRealType x, const ResizeFilter *resize_filter)
Definition: resize.c:210
Definition: resize-private.h:27
Definition: composite.h:74
Definition: colorspace.h:27
MagickFunction
Definition: statistic.h:110
Definition: composite.h:40
Definition: composite.h:67
Definition: resize-private.h:35
#define QuantumRange
Definition: magick-type.h:97
static MagickRealType Triangle(const MagickRealType x, const ResizeFilter *magick_unused(resize_filter))
Definition: resize.c:514
Definition: composite.h:51
Definition: magick-type.h:194
Definition: composite.h:57