19 #ifndef MAGICKCORE_ACCELERATE_PRIVATE_H 20 #define MAGICKCORE_ACCELERATE_PRIVATE_H 22 #if defined(__cplusplus) || defined(c_plusplus) 26 #if defined(MAGICKCORE_OPENCL_SUPPORT) 31 #define OPENCL_DEFINE(VAR,...) "\n #""define " #VAR " " #__VA_ARGS__ " \n" 32 #define OPENCL_ELIF(...) "\n #""elif " #__VA_ARGS__ " \n" 33 #define OPENCL_ELSE() "\n #""else " " \n" 34 #define OPENCL_ENDIF() "\n #""endif " " \n" 35 #define OPENCL_IF(...) "\n #""if " #__VA_ARGS__ " \n" 36 #define STRINGIFY(...) #__VA_ARGS__ "\n" 42 typedef struct _FloatPixelPacket
44 #ifdef MAGICK_PIXEL_RGBA 51 #ifdef MAGICK_PIXEL_BGRA 60 const char* accelerateKernels =
74 OPENCL_DEFINE(
MagickMax(x, y), (((x) > (y)) ? (x) : (y)))
75 OPENCL_DEFINE(
MagickMin(x, y), (((x) < (y)) ? (x) : (y)))
296 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
298 return((CLQuantum) value);
305 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
307 return((CLQuantum) (257.0f*value));
314 inline CLQuantum ScaleCharToQuantum(
const unsigned char value)
316 return((CLQuantum) (16843009.0*value));
323 inline
int ClampToCanvas(const
int offset, const
int range)
325 return clamp(offset, (
int)0, range - 1);
330 inline int ClampToCanvasWithHalo(
const int offset,
const int range,
const int edge,
const int section)
332 return clamp(offset, section ? (
int)(0 - edge) : (
int)0, section ? (range - 1) : (range - 1 + edge));
339 return (CLQuantum)(clamp(value, 0.0f, (
float)
QuantumRange) + 0.5f);
344 inline uint ScaleQuantumToMap(CLQuantum value)
346 if (value >= (CLQuantum)
MaxMap)
349 return ((uint)value);
356 float sign = x < (float) 0.0 ? (
float)-1.0 : (float) 1.0;
364 return clamp(value, 0.0f, 1.0f);
370 inline CLQuantum getBlue(CLPixelType p) {
return p.x; }
371 inline void setBlue(CLPixelType* p, CLQuantum value) { (*p).x = value; }
372 inline float getBlueF4(float4 p) {
return p.x; }
373 inline void setBlueF4(float4* p,
float value) { (*p).x = value; }
375 inline CLQuantum getGreen(CLPixelType p) {
return p.y; }
376 inline void setGreen(CLPixelType* p, CLQuantum value) { (*p).y = value; }
377 inline float getGreenF4(float4 p) {
return p.y; }
378 inline void setGreenF4(float4* p,
float value) { (*p).y = value; }
380 inline CLQuantum getRed(CLPixelType p) {
return p.z; }
381 inline void setRed(CLPixelType* p, CLQuantum value) { (*p).z = value; }
382 inline float getRedF4(float4 p) {
return p.z; }
383 inline void setRedF4(float4* p,
float value) { (*p).z = value; }
385 inline CLQuantum getOpacity(CLPixelType p) {
return p.w; }
386 inline void setOpacity(CLPixelType* p, CLQuantum value) { (*p).w = value; }
387 inline float getOpacityF4(float4 p) {
return p.w; }
388 inline void setOpacityF4(float4* p,
float value) { (*p).w = value; }
390 inline void setGray(CLPixelType* p, CLQuantum value) { (*p).z = value; (*p).y = value; (*p).x = value; }
392 inline float GetPixelIntensity(
const int method,
const int colorspace, CLPixelType p)
394 float red = getRed(p);
395 float green = getGreen(p);
396 float blue = getBlue(p);
407 intensity = (red + green + blue) / 3.0;
423 intensity = (float)(((
float)red*red + green*green + blue*blue) /
437 intensity = 0.298839*red + 0.586811*green + 0.114350*blue;
450 intensity = 0.298839*red + 0.586811*green + 0.114350*blue;
464 intensity = 0.212656*red + 0.715158*green + 0.072186*blue;
477 intensity = 0.212656*red + 0.715158*green + 0.072186*blue;
482 intensity = (float)(sqrt((
float)red*red + green*green + blue*blue) /
515 ulong MWC_AddMod64(ulong a, ulong b, ulong M)
519 if( (v>=M) || (convert_float(v) < convert_float(a)) )
530 ulong MWC_MulMod64(ulong a, ulong b, ulong M)
535 r=MWC_AddMod64(r,b,M);
536 b=MWC_AddMod64(b,b,M);
547 ulong MWC_PowMod64(ulong a, ulong e, ulong M)
552 acc=MWC_MulMod64(acc,sqr,M);
553 sqr=MWC_MulMod64(sqr,sqr,M);
559 uint2 MWC_SkipImpl_Mod64(uint2 curr, ulong A, ulong M, ulong distance)
561 ulong m=MWC_PowMod64(A, distance, M);
562 ulong x=curr.x*(ulong)A+curr.y;
563 x=MWC_MulMod64(x, m, M);
564 return (uint2)((uint)(x/A), (uint)(x%A));
567 uint2 MWC_SeedImpl_Mod64(ulong A, ulong M, uint vecSize, uint vecOffset, ulong streamBase, ulong streamGap)
574 enum{ MWC_BASEID = 4077358422479273989UL };
576 ulong dist=streamBase + (get_global_id(0)*vecSize+vecOffset)*streamGap;
577 ulong m=MWC_PowMod64(A, dist, M);
579 ulong x=MWC_MulMod64(MWC_BASEID, m, M);
580 return (uint2)((uint)(x/A), (uint)(x%A));
584 typedef struct{ uint x; uint c; } mwc64x_state_t;
586 enum{ MWC64X_A = 4294883355U };
587 enum{ MWC64X_M = 18446383549859758079UL };
589 void MWC64X_Step(mwc64x_state_t *s)
593 uint Xn=MWC64X_A*X+C;
594 uint carry=(uint)(Xn<C);
595 uint Cn=mad_hi(MWC64X_A,X,carry);
601 void MWC64X_Skip(mwc64x_state_t *s, ulong distance)
603 uint2 tmp=MWC_SkipImpl_Mod64((uint2)(s->x,s->c), MWC64X_A, MWC64X_M, distance);
608 void MWC64X_SeedStreams(mwc64x_state_t *s, ulong baseOffset, ulong perStreamOffset)
610 uint2 tmp=MWC_SeedImpl_Mod64(MWC64X_A, MWC64X_M, 1, 0, baseOffset, perStreamOffset);
616 uint MWC64X_NextUint(mwc64x_state_t *s)
618 uint res=s->x ^ s->c;
627 float mwcReadPseudoRandomValue(mwc64x_state_t* rng) {
628 return (1.0f * MWC64X_NextUint(rng)) / (float)(0xffffffff);
632 float mwcGenerateDifferentialNoise(mwc64x_state_t* r, CLQuantum pixel, NoiseType noise_type,
float attenuate) {
641 alpha=mwcReadPseudoRandomValue(r);
657 beta=mwcReadPseudoRandomValue(r);
658 gamma=sqrt(-2.0f*log(alpha));
659 sigma=gamma*cospi((2.0f*beta));
660 tau=gamma*sinpi((2.0f*beta));
699 if (alpha > MagickEpsilon)
700 sigma=sqrt(-2.0f*log(alpha));
701 beta=mwcReadPseudoRandomValue(r);
703 cospi((
float) (2.0f*beta))/2.0f);
712 for (i=0; alpha > poisson; i++)
714 beta=mwcReadPseudoRandomValue(r);
731 void AddNoise(
const __global CLPixelType* inputImage, __global CLPixelType* filteredImage
732 ,
const unsigned int inputPixelCount,
const unsigned int pixelsPerWorkItem
734 ,
const NoiseType noise_type,
const float attenuate
735 ,
const unsigned int seed0,
const unsigned int seed1
736 ,
const unsigned int numRandomNumbersPerPixel) {
742 uint span = pixelsPerWorkItem * numRandomNumbersPerPixel;
743 uint offset = span * get_local_size(0) * get_group_id(0);
745 MWC64X_SeedStreams(&rng, offset, span);
747 uint pos = get_local_size(0) * get_group_id(0) * pixelsPerWorkItem + get_local_id(0);
749 uint count = pixelsPerWorkItem;
752 if (pos < inputPixelCount) {
753 CLPixelType p = inputImage[pos];
756 setRed(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getRed(p),noise_type,attenuate)));
760 setGreen(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getGreen(p),noise_type,attenuate)));
764 setBlue(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getBlue(p),noise_type,attenuate)));
768 setOpacity(&p,
ClampToQuantum(mwcGenerateDifferentialNoise(&rng,getOpacity(p),noise_type,attenuate)));
771 filteredImage[pos] = p;
774 pos += get_local_size(0);
800 __kernel
void BlurRow(__global CLPixelType *im, __global float4 *filtered_im,
801 const ChannelType channel, __constant
float *filter,
802 const unsigned int width,
803 const unsigned int imageColumns,
const unsigned int imageRows,
804 __local CLPixelType *temp)
806 const int x = get_global_id(0);
807 const int y = get_global_id(1);
809 const int columns = imageColumns;
811 const unsigned int radius = (width-1)/2;
812 const int wsize = get_local_size(0);
813 const unsigned int loadSize = wsize+width;
841 const int groupX=get_local_size(0)*get_group_id(0);
842 const int groupY=get_local_size(1)*get_group_id(1);
845 for (
int i=get_local_id(0); i < loadSize; i=i+get_local_size(0))
848 temp[i] = im[y * columns + ClampToCanvas(i+groupX-radius, columns)];
857 barrier(CLK_LOCAL_MEM_FENCE);
860 if (get_global_id(0) < columns)
863 float4 result = (float4) 0;
867 \n #ifndef UFACTOR \n
868 \n #define UFACTOR 8 \n
871 for ( ; i+UFACTOR < width; )
873 \n #pragma unroll UFACTOR\n
874 for (
int j=0; j < UFACTOR; j++, i++)
876 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
880 for ( ; i < width; i++)
882 result+=filter[i]*convert_float4(temp[i+get_local_id(0)]);
891 filtered_im[y*columns+x] = result;
904 __kernel
void BlurColumn(
const __global float4 *blurRowData, __global CLPixelType *filtered_im,
905 const ChannelType channel, __constant
float *filter,
906 const unsigned int width,
907 const unsigned int imageColumns,
const unsigned int imageRows,
908 __local float4 *temp)
910 const int x = get_global_id(0);
911 const int y = get_global_id(1);
915 const int columns = imageColumns;
916 const int rows = imageRows;
918 unsigned int radius = (width-1)/2;
919 const int wsize = get_local_size(1);
920 const unsigned int loadSize = wsize+width;
923 const int groupX=get_local_size(0)*get_group_id(0);
924 const int groupY=get_local_size(1)*get_group_id(1);
929 for (
int i = get_local_id(1); i < loadSize; i=i+get_local_size(1))
931 temp[i] = blurRowData[ClampToCanvas(i+groupY-radius, rows) * columns + groupX];
935 barrier(CLK_LOCAL_MEM_FENCE);
938 if (get_global_id(1) < rows)
941 float4 result = (float4) 0;
945 \n #ifndef UFACTOR \n
946 \n #define UFACTOR 8 \n
949 for ( ; i+UFACTOR < width; )
951 \n #pragma unroll UFACTOR \n
952 for (
int j=0; j < UFACTOR; j++, i++)
954 result+=filter[i]*temp[i+get_local_id(1)];
958 for ( ; i < width; i++)
960 result+=filter[i]*temp[i+get_local_id(1)];
969 filtered_im[y*columns+x] = (CLPixelType) (result.x,result.y,result.z,result.w);
989 const float Sa,
const float Dca,
const float Da)
994 if ((Sca*Da+Dca*Sa) >= Sa*Da)
995 return(Sa*Da+Sca*(1.0-Da)+Dca*(1.0-Sa));
996 return(Dca*Sa*Sa/(Sa-Sca)+Sca*(1.0-Da)+Dca*(1.0-Sa));
1030 const float4 *q,float4 *composite) {
1041 gamma=
QuantumRange/(fabs(gamma) < MagickEpsilon ? MagickEpsilon : gamma);
1043 getRedF4(*q)*Da,Da));
1045 getGreenF4(*q)*Da,Da));
1047 getBlueF4(*q)*Da,Da));
1053 const float alpha,
const float4 *q,
1054 const float beta,float4 *composite)
1068 setOpacityF4(composite,(
float)
QuantumRange*(1.0-gamma));
1070 setRedF4(composite,gamma*(Sa*getRedF4(*p)+Da*getRedF4(*q)));
1071 setGreenF4(composite,gamma*(Sa*getGreenF4(*p)+Da*getGreenF4(*q)));
1072 setBlueF4(composite,gamma*(Sa*getBlueF4(*p)+Da*getBlueF4(*q)));
1078 const float alpha,
const float4 *q,
1079 const float beta,float4 *composite)
1089 void Composite(__global CLPixelType *image,
1090 const unsigned int imageWidth,
1091 const unsigned int imageHeight,
1092 const unsigned int imageMatte,
1093 const __global CLPixelType *compositeImage,
1094 const unsigned int compositeWidth,
1095 const unsigned int compositeHeight,
1096 const unsigned int compositeMatte,
1097 const unsigned int compose,
1099 const float destination_dissolve,
1100 const float source_dissolve) {
1103 index.x = get_global_id(0);
1104 index.y = get_global_id(1);
1107 if (index.x >= imageWidth
1108 || index.y >= imageHeight) {
1111 const CLPixelType inputPixel = image[index.y*imageWidth+index.x];
1113 setRedF4(&destination,getRed(inputPixel));
1114 setGreenF4(&destination,getGreen(inputPixel));
1115 setBlueF4(&destination,getBlue(inputPixel));
1118 const CLPixelType compositePixel
1119 = compositeImage[index.y*imageWidth+index.x];
1121 setRedF4(&source,getRed(compositePixel));
1122 setGreenF4(&source,getGreen(compositePixel));
1123 setBlueF4(&source,getBlue(compositePixel));
1125 if (imageMatte != 0) {
1126 setOpacityF4(&destination,getOpacity(inputPixel));
1129 setOpacityF4(&destination,0.0f);
1132 if (compositeMatte != 0) {
1133 setOpacityF4(&source,getOpacity(compositePixel));
1136 setOpacityF4(&source,0.0f);
1139 float4 composite=destination;
1148 destination_dissolve,&composite);
1155 CLPixelType outputPixel;
1159 setOpacity(&outputPixel,
ClampToQuantum(getOpacityF4(composite)));
1160 image[index.y*imageWidth+index.x] = outputPixel;
1179 float3 HueSaturationBrightness;
1180 HueSaturationBrightness.x = 0.0f;
1181 HueSaturationBrightness.y = 0.0f;
1182 HueSaturationBrightness.z = 0.0f;
1184 float r=(float) getRed(pixel);
1185 float g=(float) getGreen(pixel);
1186 float b=(float) getBlue(pixel);
1192 float delta=tmax-tmin;
1193 HueSaturationBrightness.y=delta/tmax;
1196 if (delta != 0.0f) {
1197 HueSaturationBrightness.x = ((r == tmax)?0.0f:((g == tmax)?2.0f:4.0f));
1198 HueSaturationBrightness.x += ((r == tmax)?(g-b):((g == tmax)?(b-r):(r-g)))/delta;
1199 HueSaturationBrightness.x/=6.0f;
1200 HueSaturationBrightness.x += (HueSaturationBrightness.x < 0.0f)?0.0f:1.0f;
1203 return HueSaturationBrightness;
1208 float hue = HueSaturationBrightness.x;
1209 float brightness = HueSaturationBrightness.z;
1210 float saturation = HueSaturationBrightness.y;
1214 if (saturation == 0.0f) {
1216 setGreen(&rgb,getRed(rgb));
1217 setBlue(&rgb,getRed(rgb));
1221 float h=6.0f*(hue-floor(hue));
1223 float p=brightness*(1.0f-saturation);
1224 float q=brightness*(1.0f-saturation*f);
1225 float t=brightness*(1.0f-(saturation*(1.0f-f)));
1232 setRed(&rgb, (ih == 1)?clamped_q:
1233 (ih == 2 || ih == 3)?clamped_p:
1234 (ih == 4)?clamped_t:
1237 setGreen(&rgb, (ih == 1 || ih == 2)?clampedBrightness:
1238 (ih == 3)?clamped_q:
1239 (ih == 4 || ih == 5)?clamped_p:
1242 setBlue(&rgb, (ih == 2)?clamped_t:
1243 (ih == 3 || ih == 4)?clampedBrightness:
1244 (ih == 5)?clamped_q:
1250 __kernel
void Contrast(__global CLPixelType *im,
const unsigned int sharpen)
1253 const int sign = sharpen!=0?1:-1;
1254 const int x = get_global_id(0);
1255 const int y = get_global_id(1);
1256 const int columns = get_global_size(0);
1257 const int c = x + y * columns;
1259 CLPixelType pixel = im[c];
1261 float brightness = HueSaturationBrightness.z;
1262 brightness+=0.5f*sign*(0.5f*(sinpi(brightness-0.5f)+1.0f)-brightness);
1263 brightness = clamp(brightness,0.0f,1.0f);
1264 HueSaturationBrightness.z = brightness;
1267 filteredPixel.w = pixel.w;
1268 im[c] = filteredPixel;
1287 __kernel
void Histogram(__global CLPixelType * restrict im,
1290 const int colorspace,
1291 __global uint4 * restrict histogram)
1293 const int x = get_global_id(0);
1294 const int y = get_global_id(1);
1295 const int columns = get_global_size(0);
1296 const int c = x + y * columns;
1301 atomic_inc((__global uint *)(&(histogram[pos]))+2);
1314 __kernel
void ContrastStretch(__global CLPixelType * restrict im,
1316 __global CLPixelType * restrict stretch_map,
1317 const float4 white,
const float4 black)
1319 const int x = get_global_id(0);
1320 const int y = get_global_id(1);
1321 const int columns = get_global_size(0);
1322 const int c = x + y * columns;
1325 CLPixelType oValue, eValue;
1326 CLQuantum red, green, blue, opacity;
1331 if ((channel & RedChannel) != 0)
1333 if (getRedF4(white) != getRedF4(black))
1335 ePos = ScaleQuantumToMap(getRed(oValue));
1336 eValue = stretch_map[ePos];
1337 red = getRed(eValue);
1341 if ((channel & GreenChannel) != 0)
1343 if (getGreenF4(white) != getGreenF4(black))
1345 ePos = ScaleQuantumToMap(getGreen(oValue));
1346 eValue = stretch_map[ePos];
1347 green = getGreen(eValue);
1351 if ((channel & BlueChannel) != 0)
1353 if (getBlueF4(white) != getBlueF4(black))
1355 ePos = ScaleQuantumToMap(getBlue(oValue));
1356 eValue = stretch_map[ePos];
1357 blue = getBlue(eValue);
1361 if ((channel & OpacityChannel) != 0)
1363 if (getOpacityF4(white) != getOpacityF4(black))
1365 ePos = ScaleQuantumToMap(getOpacity(oValue));
1366 eValue = stretch_map[ePos];
1367 opacity = getOpacity(eValue);
1372 im[c]=(CLPixelType)(blue, green, red, opacity);
1391 void ConvolveOptimized(
const __global CLPixelType *input, __global CLPixelType *output,
1392 const unsigned int imageWidth,
const unsigned int imageHeight,
1393 __constant
float *filter,
const unsigned int filterWidth,
const unsigned int filterHeight,
1394 const uint matte,
const ChannelType channel, __local CLPixelType *pixelLocalCache, __local
float* filterCache) {
1397 blockID.x = get_group_id(0);
1398 blockID.y = get_group_id(1);
1402 imageAreaOrg.x = blockID.x * get_local_size(0);
1403 imageAreaOrg.y = blockID.y * get_local_size(1);
1405 int2 midFilterDimen;
1406 midFilterDimen.x = (filterWidth-1)/2;
1407 midFilterDimen.y = (filterHeight-1)/2;
1409 int2 cachedAreaOrg = imageAreaOrg - midFilterDimen;
1412 int2 cachedAreaDimen;
1413 cachedAreaDimen.x = get_local_size(0) + filterWidth - 1;
1414 cachedAreaDimen.y = get_local_size(1) + filterHeight - 1;
1417 int localID = get_local_id(1)*get_local_size(0)+get_local_id(0);
1418 int cachedAreaNumPixels = cachedAreaDimen.x * cachedAreaDimen.y;
1419 int groupSize = get_local_size(0) * get_local_size(1);
1420 for (
int i = localID; i < cachedAreaNumPixels; i+=groupSize) {
1422 int2 cachedAreaIndex;
1423 cachedAreaIndex.x = i % cachedAreaDimen.x;
1424 cachedAreaIndex.y = i / cachedAreaDimen.x;
1426 int2 imagePixelIndex;
1427 imagePixelIndex = cachedAreaOrg + cachedAreaIndex;
1431 imagePixelIndex.x = ClampToCanvas(imagePixelIndex.x, imageWidth);
1432 imagePixelIndex.y = ClampToCanvas(imagePixelIndex.y, imageHeight);
1434 pixelLocalCache[i] = input[imagePixelIndex.y * imageWidth + imagePixelIndex.x];
1438 for (
int i = localID; i < filterHeight*filterWidth; i+=groupSize) {
1439 filterCache[i] = filter[i];
1441 barrier(CLK_LOCAL_MEM_FENCE);
1445 imageIndex.x = imageAreaOrg.x + get_local_id(0);
1446 imageIndex.y = imageAreaOrg.y + get_local_id(1);
1449 if (imageIndex.x >= imageWidth
1450 || imageIndex.y >= imageHeight) {
1454 int filterIndex = 0;
1455 float4 sum = (float4)0.0f;
1457 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
1458 int cacheIndexY = get_local_id(1);
1459 for (
int j = 0; j < filterHeight; j++) {
1460 int cacheIndexX = get_local_id(0);
1461 for (
int i = 0; i < filterWidth; i++) {
1462 CLPixelType p = pixelLocalCache[cacheIndexY*cachedAreaDimen.x + cacheIndexX];
1463 float f = filterCache[filterIndex];
1478 int cacheIndexY = get_local_id(1);
1479 for (
int j = 0; j < filterHeight; j++) {
1480 int cacheIndexX = get_local_id(0);
1481 for (
int i = 0; i < filterWidth; i++) {
1483 CLPixelType p = pixelLocalCache[cacheIndexY*cachedAreaDimen.x + cacheIndexX];
1485 float f = filterCache[filterIndex];
1486 float g = alpha * f;
1500 sum.xyz = gamma*sum.xyz;
1502 CLPixelType outputPixel;
1508 output[imageIndex.y * imageWidth + imageIndex.x] = outputPixel;
1514 void Convolve(
const __global CLPixelType *input, __global CLPixelType *output,
1515 const uint imageWidth,
const uint imageHeight,
1516 __constant
float *filter,
const unsigned int filterWidth,
const unsigned int filterHeight,
1520 imageIndex.x = get_global_id(0);
1521 imageIndex.y = get_global_id(1);
1527 if (imageIndex.x >= imageWidth
1528 || imageIndex.y >= imageHeight)
1531 int2 midFilterDimen;
1532 midFilterDimen.x = (filterWidth-1)/2;
1533 midFilterDimen.y = (filterHeight-1)/2;
1535 int filterIndex = 0;
1536 float4 sum = (float4)0.0f;
1538 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
1539 for (
int j = 0; j < filterHeight; j++) {
1540 int2 inputPixelIndex;
1541 inputPixelIndex.y = imageIndex.y - midFilterDimen.y + j;
1542 inputPixelIndex.y = ClampToCanvas(inputPixelIndex.y, imageHeight);
1543 for (
int i = 0; i < filterWidth; i++) {
1544 inputPixelIndex.x = imageIndex.x - midFilterDimen.x + i;
1545 inputPixelIndex.x = ClampToCanvas(inputPixelIndex.x, imageWidth);
1547 CLPixelType p = input[inputPixelIndex.y * imageWidth + inputPixelIndex.x];
1548 float f = filter[filterIndex];
1563 for (
int j = 0; j < filterHeight; j++) {
1564 int2 inputPixelIndex;
1565 inputPixelIndex.y = imageIndex.y - midFilterDimen.y + j;
1566 inputPixelIndex.y = ClampToCanvas(inputPixelIndex.y, imageHeight);
1567 for (
int i = 0; i < filterWidth; i++) {
1568 inputPixelIndex.x = imageIndex.x - midFilterDimen.x + i;
1569 inputPixelIndex.x = ClampToCanvas(inputPixelIndex.x, imageWidth);
1571 CLPixelType p = input[inputPixelIndex.y * imageWidth + inputPixelIndex.x];
1573 float f = filter[filterIndex];
1574 float g = alpha * f;
1588 sum.xyz = gamma*sum.xyz;
1591 CLPixelType outputPixel;
1597 output[imageIndex.y * imageWidth + imageIndex.x] = outputPixel;
1615 __kernel
void HullPass1(
const __global CLPixelType *inputImage, __global CLPixelType *outputImage
1616 ,
const unsigned int imageWidth,
const unsigned int imageHeight
1617 ,
const int2 offset,
const int polarity,
const int matte) {
1619 int x = get_global_id(0);
1620 int y = get_global_id(1);
1622 CLPixelType v = inputImage[y*imageWidth+x];
1625 neighbor.y = y + offset.y;
1626 neighbor.x = x + offset.x;
1628 int2 clampedNeighbor;
1629 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1630 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1632 CLPixelType r = (clampedNeighbor.x == neighbor.x
1633 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1649 \n #pragma unroll 4\n
1650 for (
unsigned int i = 0; i < 4; i++) {
1651 sv[i] = (sr[i] >= (sv[i]+ScaleCharToQuantum(2)))?(sv[i]+ScaleCharToQuantum(1)):sv[i];
1655 \n #pragma unroll 4\n
1656 for (
unsigned int i = 0; i < 4; i++) {
1657 sv[i] = (sr[i] <= (sv[i]-ScaleCharToQuantum(2)))?(sv[i]-ScaleCharToQuantum(1)):sv[i];
1662 v.x = (CLQuantum)sv[0];
1663 v.y = (CLQuantum)sv[1];
1664 v.z = (CLQuantum)sv[2];
1667 v.w = (CLQuantum)sv[3];
1669 outputImage[y*imageWidth+x] = v;
1680 __kernel
void HullPass2(
const __global CLPixelType *inputImage, __global CLPixelType *outputImage
1681 ,
const unsigned int imageWidth,
const unsigned int imageHeight
1682 ,
const int2 offset,
const int polarity,
const int matte) {
1684 int x = get_global_id(0);
1685 int y = get_global_id(1);
1687 CLPixelType v = inputImage[y*imageWidth+x];
1689 int2 neighbor, clampedNeighbor;
1691 neighbor.y = y + offset.y;
1692 neighbor.x = x + offset.x;
1693 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1694 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1696 CLPixelType r = (clampedNeighbor.x == neighbor.x
1697 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1701 neighbor.y = y - offset.y;
1702 neighbor.x = x - offset.x;
1703 clampedNeighbor.x = ClampToCanvas(neighbor.x, imageWidth);
1704 clampedNeighbor.y = ClampToCanvas(neighbor.y, imageHeight);
1706 CLPixelType s = (clampedNeighbor.x == neighbor.x
1707 && clampedNeighbor.y == neighbor.y)?inputImage[clampedNeighbor.y*imageWidth+clampedNeighbor.x]
1730 \n #pragma unroll 4\n
1731 for (
unsigned int i = 0; i < 4; i++) {
1736 sv[i] =(( (int)( ss[i] < (sv[i]+ScaleCharToQuantum(2))) + (int) ( sr[i] <= sv[i] ) ) !=0) ? sv[i]:(sv[i]+ScaleCharToQuantum(1));
1740 \n #pragma unroll 4\n
1741 for (
unsigned int i = 0; i < 4; i++) {
1745 sv[i] = (( (int)(ss[i] > (sv[i]-ScaleCharToQuantum(2))) + (int)( sr[i] >= sv[i] )) !=0) ? sv[i]:(sv[i]-ScaleCharToQuantum(1));
1749 v.x = (CLQuantum)sv[0];
1750 v.y = (CLQuantum)sv[1];
1751 v.z = (CLQuantum)sv[2];
1754 v.w = (CLQuantum)sv[3];
1756 outputImage[y*imageWidth+x] = v;
1778 __kernel
void Equalize(__global CLPixelType * restrict im,
1780 __global CLPixelType * restrict equalize_map,
1781 const float4 white,
const float4 black)
1783 const int x = get_global_id(0);
1784 const int y = get_global_id(1);
1785 const int columns = get_global_size(0);
1786 const int c = x + y * columns;
1789 CLPixelType oValue, eValue;
1790 CLQuantum red, green, blue, opacity;
1795 if ((channel & SyncChannels) != 0)
1797 if (getRedF4(white) != getRedF4(black))
1799 ePos = ScaleQuantumToMap(getRed(oValue));
1800 eValue = equalize_map[ePos];
1801 red = getRed(eValue);
1802 ePos = ScaleQuantumToMap(getGreen(oValue));
1803 eValue = equalize_map[ePos];
1804 green = getRed(eValue);
1805 ePos = ScaleQuantumToMap(getBlue(oValue));
1806 eValue = equalize_map[ePos];
1807 blue = getRed(eValue);
1808 ePos = ScaleQuantumToMap(getOpacity(oValue));
1809 eValue = equalize_map[ePos];
1810 opacity = getRed(eValue);
1813 im[c]=(CLPixelType)(blue, green, red, opacity);
1841 CLPixelType
ApplyFunction(CLPixelType pixel,
const MagickFunction
function,
1842 const unsigned int number_parameters,
1843 __constant
float *parameters)
1845 float4 result = (float4) 0.0f;
1850 for (
unsigned int i=0; i < number_parameters; i++)
1851 result = result*(float4)
QuantumScale*convert_float4(pixel) + parameters[i];
1857 float freq,phase,ampl,bias;
1858 freq = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
1859 phase = ( number_parameters >= 2 ) ? parameters[1] : 0.0f;
1860 ampl = ( number_parameters >= 3 ) ? parameters[2] : 0.5f;
1861 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
1863 (freq*
QuantumScale*(
float)pixel.x + phase/360.0f)) + bias);
1865 (freq*
QuantumScale*(
float)pixel.y + phase/360.0f)) + bias);
1867 (freq*
QuantumScale*(
float)pixel.z + phase/360.0f)) + bias);
1869 (freq*
QuantumScale*(
float)pixel.w + phase/360.0f)) + bias);
1874 float width,range,center,bias;
1875 width = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
1876 center = ( number_parameters >= 2 ) ? parameters[1] : 0.5f;
1877 range = ( number_parameters >= 3 ) ? parameters[2] : 1.0f;
1878 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
1880 result.x = 2.0f/width*(
QuantumScale*(float)pixel.x - center);
1881 result.x = range/
MagickPI*asin(result.x)+bias;
1882 result.x = ( result.x <= -1.0f ) ? bias - range/2.0f : result.x;
1883 result.x = ( result.x >= 1.0f ) ? bias + range/2.0f : result.x;
1885 result.y = 2.0f/width*(
QuantumScale*(float)pixel.y - center);
1886 result.y = range/
MagickPI*asin(result.y)+bias;
1887 result.y = ( result.y <= -1.0f ) ? bias - range/2.0f : result.y;
1888 result.y = ( result.y >= 1.0f ) ? bias + range/2.0f : result.y;
1890 result.z = 2.0f/width*(
QuantumScale*(float)pixel.z - center);
1891 result.z = range/
MagickPI*asin(result.z)+bias;
1892 result.z = ( result.z <= -1.0f ) ? bias - range/2.0f : result.x;
1893 result.z = ( result.z >= 1.0f ) ? bias + range/2.0f : result.x;
1896 result.w = 2.0f/width*(
QuantumScale*(float)pixel.w - center);
1897 result.w = range/
MagickPI*asin(result.w)+bias;
1898 result.w = ( result.w <= -1.0f ) ? bias - range/2.0f : result.w;
1899 result.w = ( result.w >= 1.0f ) ? bias + range/2.0f : result.w;
1906 float slope,range,center,bias;
1907 slope = ( number_parameters >= 1 ) ? parameters[0] : 1.0f;
1908 center = ( number_parameters >= 2 ) ? parameters[1] : 0.5f;
1909 range = ( number_parameters >= 3 ) ? parameters[2] : 1.0f;
1910 bias = ( number_parameters >= 4 ) ? parameters[3] : 0.5f;
1911 result = (float4)
MagickPI*(float4)slope*((float4)
QuantumScale*convert_float4(pixel)-(float4)center);
1931 __kernel
void ComputeFunction(__global CLPixelType *im,
1932 const ChannelType channel,
const MagickFunction
function,
1933 const unsigned int number_parameters, __constant
float *parameters)
1935 const int x = get_global_id(0);
1936 const int y = get_global_id(1);
1937 const int columns = get_global_size(0);
1938 const int c = x + y * columns;
1939 im[c] =
ApplyFunction(im[c],
function, number_parameters, parameters);
1956 __kernel
void Grayscale(__global CLPixelType *im,
1957 const int method,
const int colorspace)
1960 const int x = get_global_id(0);
1961 const int y = get_global_id(1);
1962 const int columns = get_global_size(0);
1963 const int c = x + y * columns;
1965 CLPixelType pixel = im[c];
1973 red=(float)getRed(pixel);
1974 green=(float)getGreen(pixel);
1975 blue=(float)getBlue(pixel);
1979 CLPixelType filteredPixel;
1985 intensity=(red+green+blue)/3.0;
2001 intensity=(float) (((
float) red*red+green*green+
2015 intensity=0.298839*red+0.586811*green+0.114350*blue;
2028 intensity=0.298839*red+0.586811*green+0.114350*blue;
2042 intensity=0.212656*red+0.715158*green+0.072186*blue;
2055 intensity=0.212656*red+0.715158*green+0.072186*blue;
2060 intensity=(float) (sqrt((
float) red*red+green*green+
2061 blue*blue)/sqrt(3.0));
2069 filteredPixel.w = pixel.w;
2071 im[c] = filteredPixel;
2088 inline int mirrorBottom(
int value)
2090 return (value < 0) ? - (value) : value;
2092 inline int mirrorTop(
int value,
int width)
2094 return (value >= width) ? (2 * width - value - 1) : value;
2097 __kernel
void LocalContrastBlurRow(__global CLPixelType *srcImage, __global CLPixelType *dstImage, __global
float *tmpImage,
2099 const int imageWidth,
2100 const int imageHeight)
2102 const float4 RGB = ((float4)(0.2126f, 0.7152f, 0.0722f, 0.0f));
2104 int x = get_local_id(0);
2105 int y = get_global_id(1);
2107 if ((x >= imageWidth) || (y >= imageHeight))
2110 global CLPixelType *src = srcImage + y * imageWidth;
2112 for (
int i = x; i < imageWidth; i += get_local_size(0)) {
2114 float weight = 1.0f;
2117 while ((j + 7) < i) {
2118 for (
int k = 0; k < 8; ++k)
2119 sum += (weight + k) * dot(RGB, convert_float4(src[mirrorBottom(j+k)]));
2124 sum += weight * dot(RGB, convert_float4(src[mirrorBottom(j)]));
2129 while ((j + 7) < radius + i) {
2130 for (
int k = 0; k < 8; ++k)
2131 sum += (weight - k) * dot(RGB, convert_float4(src[mirrorTop(j + k, imageWidth)]));
2135 while (j < radius + i) {
2136 sum += weight * dot(RGB, convert_float4(src[mirrorTop(j, imageWidth)]));
2141 tmpImage[i + y * imageWidth] = sum / ((radius + 1) * (radius + 1));
2147 __kernel
void LocalContrastBlurApplyColumn(__global CLPixelType *srcImage, __global CLPixelType *dstImage, __global
float *blurImage,
2149 const float strength,
2150 const int imageWidth,
2151 const int imageHeight)
2153 const float4 RGB = (float4)(0.2126f, 0.7152f, 0.0722f, 0.0f);
2155 int x = get_global_id(0);
2156 int y = get_global_id(1);
2158 if ((x >= imageWidth) || (y >= imageHeight))
2161 global
float *src = blurImage + x;
2164 float weight = 1.0f;
2167 while ((j + 7) < y) {
2168 for (
int k = 0; k < 8; ++k)
2169 sum += (weight + k) * src[mirrorBottom(j+k) * imageWidth];
2174 sum += weight * src[mirrorBottom(j) * imageWidth];
2179 while ((j + 7) < radius + y) {
2180 for (
int k = 0; k < 8; ++k)
2181 sum += (weight - k) * src[mirrorTop(j + k, imageHeight) * imageWidth];
2185 while (j < radius + y) {
2186 sum += weight * src[mirrorTop(j, imageHeight) * imageWidth];
2191 CLPixelType pixel = srcImage[x + y * imageWidth];
2192 float srcVal = dot(RGB, convert_float4(pixel));
2193 float mult = (srcVal - (sum / ((radius + 1) * (radius + 1)))) * (strength / 100.0f);
2194 mult = (srcVal + mult) / srcVal;
2200 dstImage[x + y * imageWidth] = pixel;
2218 inline void ConvertRGBToHSL(
const CLQuantum red,
const CLQuantum green,
const CLQuantum blue,
2219 float *hue,
float *saturation,
float *lightness)
2234 *lightness=(tmax+tmin)/2.0;
2255 if (*lightness <= 0.5)
2256 *saturation=c/(2.0*(*lightness));
2258 *saturation=c/(2.0-2.0*(*lightness));
2261 inline void ConvertHSLToRGB(
const float hue,
const float saturation,
const float lightness,
2262 CLQuantum *red,CLQuantum *green,CLQuantum *blue)
2277 if (lightness <= 0.5)
2278 c=2.0*lightness*saturation;
2280 c=(2.0-2.0*lightness)*saturation;
2281 tmin=lightness-0.5*c;
2282 h-=360.0*floor(h/360.0);
2284 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
2285 switch ((
int) floor(h) % 6)
2341 inline void ModulateHSL(
const float percent_hue,
const float percent_saturation,
const float percent_lightness,
2342 CLQuantum *red,CLQuantum *green,CLQuantum *blue)
2353 hue+=0.5*(0.01*percent_hue-1.0);
2358 saturation*=0.01*percent_saturation;
2359 lightness*=0.01*percent_lightness;
2363 __kernel
void Modulate(__global CLPixelType *im,
2364 const float percent_brightness,
2365 const float percent_hue,
2366 const float percent_saturation,
2367 const int colorspace)
2370 const int x = get_global_id(0);
2371 const int y = get_global_id(1);
2372 const int columns = get_global_size(0);
2373 const int c = x + y * columns;
2375 CLPixelType pixel = im[c];
2383 green=getGreen(pixel);
2384 blue=getBlue(pixel);
2391 ModulateHSL(percent_hue, percent_saturation, percent_brightness,
2392 &red, &green, &blue);
2397 CLPixelType filteredPixel;
2399 setRed(&filteredPixel, red);
2400 setGreen(&filteredPixel, green);
2401 setBlue(&filteredPixel, blue);
2402 filteredPixel.w = pixel.w;
2404 im[c] = filteredPixel;
2422 void MotionBlur(
const __global CLPixelType *input, __global CLPixelType *output,
2423 const unsigned int imageWidth,
const unsigned int imageHeight,
2424 const __global
float *filter,
const unsigned int width,
const __global int2* offset,
2426 const ChannelType channel,
const unsigned int matte) {
2429 currentPixel.x = get_global_id(0);
2430 currentPixel.y = get_global_id(1);
2432 if (currentPixel.x >= imageWidth
2433 || currentPixel.y >= imageHeight)
2437 pixel.x = (float)bias.x;
2438 pixel.y = (
float)bias.y;
2439 pixel.z = (float)bias.z;
2440 pixel.w = (
float)bias.w;
2442 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
2444 for (
int i = 0; i < width; i++) {
2447 int2 samplePixel = currentPixel + offset[i];
2448 samplePixel.x = ClampToCanvas(samplePixel.x, imageWidth);
2449 samplePixel.y = ClampToCanvas(samplePixel.y, imageHeight);
2450 CLPixelType samplePixelValue = input[ samplePixel.y * imageWidth + samplePixel.x];
2452 pixel.x += (filter[i] * (float)samplePixelValue.x);
2453 pixel.y += (filter[i] * (float)samplePixelValue.y);
2454 pixel.z += (filter[i] * (float)samplePixelValue.z);
2455 pixel.w += (filter[i] * (float)samplePixelValue.w);
2458 CLPixelType outputPixel;
2463 output[currentPixel.y * imageWidth + currentPixel.x] = outputPixel;
2468 for (
int i = 0; i < width; i++) {
2471 int2 samplePixel = currentPixel + offset[i];
2472 samplePixel.x = ClampToCanvas(samplePixel.x, imageWidth);
2473 samplePixel.y = ClampToCanvas(samplePixel.y, imageHeight);
2475 CLPixelType samplePixelValue = input[ samplePixel.y * imageWidth + samplePixel.x];
2478 float k = filter[i];
2479 pixel.x = pixel.x + k * alpha * samplePixelValue.x;
2480 pixel.y = pixel.y + k * alpha * samplePixelValue.y;
2481 pixel.z = pixel.z + k * alpha * samplePixelValue.z;
2483 pixel.w += k * alpha * samplePixelValue.w;
2488 pixel.xyz = gamma*pixel.xyz;
2490 CLPixelType outputPixel;
2495 output[currentPixel.y * imageWidth + currentPixel.x] = outputPixel;
2513 __kernel
void RadialBlur(
const __global CLPixelType *im, __global CLPixelType *filtered_im,
2515 const unsigned int channel,
const unsigned int matte,
2516 const float2 blurCenter,
2517 __constant
float *cos_theta, __constant
float *sin_theta,
2518 const unsigned int cossin_theta_size)
2520 const int x = get_global_id(0);
2521 const int y = get_global_id(1);
2522 const int columns = get_global_size(0);
2523 const int rows = get_global_size(1);
2524 unsigned int step = 1;
2525 float center_x = (float) x - blurCenter.x;
2526 float center_y = (
float) y - blurCenter.y;
2527 float radius = hypot(center_x, center_y);
2530 float blur_radius = hypot(blurCenter.x, blurCenter.y);
2532 if (radius > MagickEpsilon)
2534 step = (
unsigned int) (blur_radius / radius);
2537 if (step >= cossin_theta_size)
2538 step = cossin_theta_size-1;
2542 result.x = (float)bias.x;
2543 result.y = (
float)bias.y;
2544 result.z = (float)bias.z;
2545 result.w = (
float)bias.w;
2546 float normalize = 0.0f;
2548 if (((channel & OpacityChannel) == 0) || (matte == 0)) {
2549 for (
unsigned int i=0; i<cossin_theta_size; i+=step)
2551 result += convert_float4(im[
2552 ClampToCanvas(blurCenter.x+center_x*cos_theta[i]-center_y*sin_theta[i]+0.5f,columns)+
2553 ClampToCanvas(blurCenter.y+center_x*sin_theta[i]+center_y*cos_theta[i]+0.5f, rows)*columns]);
2557 result = result * normalize;
2561 for (
unsigned int i=0; i<cossin_theta_size; i+=step)
2563 float4 p = convert_float4(im[
2564 ClampToCanvas(blurCenter.x+center_x*cos_theta[i]-center_y*sin_theta[i]+0.5f,columns)+
2565 ClampToCanvas(blurCenter.y+center_x*sin_theta[i]+center_y*cos_theta[i]+0.5f, rows)*columns]);
2568 result.x += alpha * p.x;
2569 result.y += alpha * p.y;
2570 result.z += alpha * p.z;
2577 result.x = gamma*result.x;
2578 result.y = gamma*result.y;
2579 result.z = gamma*result.z;
2580 result.w = normalize*result.w;
2601 float BoxResizeFilter(
const float x)
2609 float CubicBC(
const float x,
const __global
float* resizeFilterCoefficients)
2641 return(resizeFilterCoefficients[0]+x*(x*
2642 (resizeFilterCoefficients[1]+x*resizeFilterCoefficients[2])));
2644 return(resizeFilterCoefficients[3]+x*(resizeFilterCoefficients[4]+x*
2645 (resizeFilterCoefficients[5]+x*resizeFilterCoefficients[6])));
2651 float Sinc(
const float x)
2655 const float alpha=(float) (
MagickPI*x);
2656 return sinpi(x)/alpha;
2670 return ((x<1.0f)?(1.0f-x):0.0f);
2682 const float cosine=cos((
MagickPI*x));
2683 return(0.5f+0.5f*cosine);
2694 const float cosine=cos((
MagickPI*x));
2695 return(0.54f+0.46f*cosine);
2709 const float cosine=cos((
MagickPI*x));
2710 return(0.34f+cosine*(0.5f+cosine*0.16f));
2718 inline float applyResizeFilter(
const float x,
const ResizeWeightingFunctionType filterType,
const __global
float* filterCoefficients)
2728 return CubicBC(x,filterCoefficients);
2730 return BoxResizeFilter(x);
2748 inline float getResizeFilterWeight(
const __global
float* resizeFilterCubicCoefficients,
const ResizeWeightingFunctionType resizeFilterType
2749 ,
const ResizeWeightingFunctionType resizeWindowType
2750 ,
const float resizeFilterScale,
const float resizeWindowSupport,
const float resizeFilterBlur,
const float x)
2753 float xBlur = fabs(x/resizeFilterBlur);
2754 if (resizeWindowSupport < MagickEpsilon
2761 scale = resizeFilterScale;
2762 scale = applyResizeFilter(xBlur*scale, resizeWindowType, resizeFilterCubicCoefficients);
2764 float weight = scale * applyResizeFilter(xBlur, resizeFilterType, resizeFilterCubicCoefficients);
2771 const char* accelerateKernels2 =
2775 inline unsigned int getNumWorkItemsPerPixel(
const unsigned int pixelPerWorkgroup,
const unsigned int numWorkItems) {
2776 return (numWorkItems/pixelPerWorkgroup);
2781 inline int pixelToCompute(
const unsigned itemID,
const unsigned int pixelPerWorkgroup,
const unsigned int numWorkItems) {
2782 const unsigned int numWorkItemsPerPixel = getNumWorkItemsPerPixel(pixelPerWorkgroup, numWorkItems);
2783 int pixelIndex = itemID/numWorkItemsPerPixel;
2784 pixelIndex = (pixelIndex<pixelPerWorkgroup)?pixelIndex:-1;
2791 __kernel __attribute__((reqd_work_group_size(256, 1, 1)))
2792 void ResizeHorizontalFilter(
const __global CLPixelType* inputImage,
const unsigned int inputColumns,
const unsigned int inputRows,
const unsigned int matte
2793 ,
const float xFactor, __global CLPixelType* filteredImage,
const unsigned int filteredColumns,
const unsigned int filteredRows
2794 ,
const int resizeFilterType,
const int resizeWindowType
2795 ,
const __global
float* resizeFilterCubicCoefficients
2796 ,
const float resizeFilterScale,
const float resizeFilterSupport,
const float resizeFilterWindowSupport,
const float resizeFilterBlur
2797 , __local CLPixelType* inputImageCache,
const int numCachedPixels,
const unsigned int pixelPerWorkgroup,
const unsigned int pixelChunkSize
2798 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2802 const unsigned int startX = get_group_id(0)*pixelPerWorkgroup;
2803 const unsigned int stopX =
MagickMin(startX + pixelPerWorkgroup,filteredColumns);
2804 const unsigned int actualNumPixelToCompute = stopX - startX;
2807 float scale =
MagickMax(1.0f/xFactor+MagickEpsilon ,1.0f);
2808 const float support =
MagickMax(scale*resizeFilterSupport,0.5f);
2811 const int cacheRangeStartX =
MagickMax((
int)((startX+0.5f)/xFactor+MagickEpsilon-support+0.5f),(
int)(0));
2812 const int cacheRangeEndX =
MagickMin((
int)(cacheRangeStartX + numCachedPixels), (
int)inputColumns);
2815 const unsigned int y = get_global_id(1);
2816 event_t e = async_work_group_copy(inputImageCache,inputImage+y*inputColumns+cacheRangeStartX,cacheRangeEndX-cacheRangeStartX,0);
2817 wait_group_events(1,&e);
2819 unsigned int totalNumChunks = (actualNumPixelToCompute+pixelChunkSize-1)/pixelChunkSize;
2820 for (
unsigned int chunk = 0; chunk < totalNumChunks; chunk++)
2823 const unsigned int chunkStartX = startX + chunk*pixelChunkSize;
2824 const unsigned int chunkStopX =
MagickMin(chunkStartX + pixelChunkSize, stopX);
2825 const unsigned int actualNumPixelInThisChunk = chunkStopX - chunkStartX;
2828 const unsigned int itemID = get_local_id(0);
2829 const unsigned int numItems = getNumWorkItemsPerPixel(actualNumPixelInThisChunk, get_local_size(0));
2831 const int pixelIndex = pixelToCompute(itemID, actualNumPixelInThisChunk, get_local_size(0));
2833 float4 filteredPixel = (float4)0.0f;
2834 float density = 0.0f;
2837 if (pixelIndex != -1) {
2840 const int x = chunkStartX + pixelIndex;
2844 const unsigned int start = (
unsigned int)
MagickMax(bisect-support+0.5f,0.0f);
2845 const unsigned int stop = (
unsigned int)
MagickMin(bisect+support+0.5f,(
float)inputColumns);
2846 const unsigned int n = stop - start;
2849 unsigned int numStepsPerWorkItem = n / numItems;
2850 numStepsPerWorkItem += ((numItems*numStepsPerWorkItem)==n?0:1);
2852 const unsigned int startStep = (itemID%numItems)*numStepsPerWorkItem;
2853 if (startStep < n) {
2854 const unsigned int stopStep =
MagickMin(startStep+numStepsPerWorkItem, n);
2856 unsigned int cacheIndex = start+startStep-cacheRangeStartX;
2859 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2860 float4 cp = convert_float4(inputImageCache[cacheIndex]);
2862 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2863 , (ResizeWeightingFunctionType)resizeWindowType
2864 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2866 filteredPixel += ((float4)weight)*cp;
2873 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
2874 CLPixelType p = inputImageCache[cacheIndex];
2876 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
2877 , (ResizeWeightingFunctionType)resizeWindowType
2878 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
2881 float4 cp = convert_float4(p);
2883 filteredPixel.x += alpha * cp.x;
2884 filteredPixel.y += alpha * cp.y;
2885 filteredPixel.z += alpha * cp.z;
2886 filteredPixel.w += weight * cp.w;
2896 if (itemID < actualNumPixelInThisChunk) {
2897 outputPixelCache[itemID] = (float4)0.0f;
2898 densityCache[itemID] = 0.0f;
2900 gammaCache[itemID] = 0.0f;
2902 barrier(CLK_LOCAL_MEM_FENCE);
2905 for (
unsigned int i = 0; i < numItems; i++) {
2906 if (pixelIndex != -1) {
2907 if (itemID%numItems == i) {
2908 outputPixelCache[pixelIndex]+=filteredPixel;
2909 densityCache[pixelIndex]+=density;
2911 gammaCache[pixelIndex]+=gamma;
2915 barrier(CLK_LOCAL_MEM_FENCE);
2918 if (itemID < actualNumPixelInThisChunk) {
2920 float density = densityCache[itemID];
2921 float4 filteredPixel = outputPixelCache[itemID];
2922 if (density!= 0.0f && density != 1.0)
2925 filteredPixel *= (float4)density;
2927 filteredImage[y*filteredColumns+chunkStartX+itemID] = (CLPixelType) (
ClampToQuantum(filteredPixel.x)
2933 float density = densityCache[itemID];
2934 float gamma = gammaCache[itemID];
2935 float4 filteredPixel = outputPixelCache[itemID];
2937 if (density!= 0.0f && density != 1.0) {
2939 filteredPixel *= (float4)density;
2950 filteredImage[y*filteredColumns+chunkStartX+itemID] = fp;
2961 __kernel __attribute__((reqd_work_group_size(1, 256, 1)))
2962 void ResizeVerticalFilter(
const __global CLPixelType* inputImage,
const unsigned int inputColumns,
const unsigned int inputRows,
const unsigned int matte
2963 ,
const float yFactor, __global CLPixelType* filteredImage,
const unsigned int filteredColumns,
const unsigned int filteredRows
2964 ,
const int resizeFilterType,
const int resizeWindowType
2965 ,
const __global
float* resizeFilterCubicCoefficients
2966 ,
const float resizeFilterScale,
const float resizeFilterSupport,
const float resizeFilterWindowSupport,
const float resizeFilterBlur
2967 , __local CLPixelType* inputImageCache,
const int numCachedPixels,
const unsigned int pixelPerWorkgroup,
const unsigned int pixelChunkSize
2968 , __local float4* outputPixelCache, __local
float* densityCache, __local
float* gammaCache) {
2972 const unsigned int startY = get_group_id(1)*pixelPerWorkgroup;
2973 const unsigned int stopY =
MagickMin(startY + pixelPerWorkgroup,filteredRows);
2974 const unsigned int actualNumPixelToCompute = stopY - startY;
2977 float scale =
MagickMax(1.0f/yFactor+MagickEpsilon ,1.0f);
2978 const float support =
MagickMax(scale*resizeFilterSupport,0.5f);
2981 const int cacheRangeStartY =
MagickMax((
int)((startY+0.5f)/yFactor+MagickEpsilon-support+0.5f),(
int)(0));
2982 const int cacheRangeEndY =
MagickMin((
int)(cacheRangeStartY + numCachedPixels), (
int)inputRows);
2985 const unsigned int x = get_global_id(0);
2986 event_t e = async_work_group_strided_copy(inputImageCache, inputImage+cacheRangeStartY*inputColumns+x, cacheRangeEndY-cacheRangeStartY, inputColumns, 0);
2987 wait_group_events(1,&e);
2989 unsigned int totalNumChunks = (actualNumPixelToCompute+pixelChunkSize-1)/pixelChunkSize;
2990 for (
unsigned int chunk = 0; chunk < totalNumChunks; chunk++)
2993 const unsigned int chunkStartY = startY + chunk*pixelChunkSize;
2994 const unsigned int chunkStopY =
MagickMin(chunkStartY + pixelChunkSize, stopY);
2995 const unsigned int actualNumPixelInThisChunk = chunkStopY - chunkStartY;
2998 const unsigned int itemID = get_local_id(1);
2999 const unsigned int numItems = getNumWorkItemsPerPixel(actualNumPixelInThisChunk, get_local_size(1));
3001 const int pixelIndex = pixelToCompute(itemID, actualNumPixelInThisChunk, get_local_size(1));
3003 float4 filteredPixel = (float4)0.0f;
3004 float density = 0.0f;
3007 if (pixelIndex != -1) {
3010 const int y = chunkStartY + pixelIndex;
3014 const unsigned int start = (
unsigned int)
MagickMax(bisect-support+0.5f,0.0f);
3015 const unsigned int stop = (
unsigned int)
MagickMin(bisect+support+0.5f,(
float)inputRows);
3016 const unsigned int n = stop - start;
3019 unsigned int numStepsPerWorkItem = n / numItems;
3020 numStepsPerWorkItem += ((numItems*numStepsPerWorkItem)==n?0:1);
3022 const unsigned int startStep = (itemID%numItems)*numStepsPerWorkItem;
3023 if (startStep < n) {
3024 const unsigned int stopStep =
MagickMin(startStep+numStepsPerWorkItem, n);
3026 unsigned int cacheIndex = start+startStep-cacheRangeStartY;
3029 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
3030 float4 cp = convert_float4(inputImageCache[cacheIndex]);
3032 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
3033 , (ResizeWeightingFunctionType)resizeWindowType
3034 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
3036 filteredPixel += ((float4)weight)*cp;
3043 for (
unsigned int i = startStep; i < stopStep; i++,cacheIndex++) {
3044 CLPixelType p = inputImageCache[cacheIndex];
3046 float weight = getResizeFilterWeight(resizeFilterCubicCoefficients,(ResizeWeightingFunctionType)resizeFilterType
3047 , (ResizeWeightingFunctionType)resizeWindowType
3048 , resizeFilterScale, resizeFilterWindowSupport, resizeFilterBlur,scale*(start+i-bisect+0.5));
3051 float4 cp = convert_float4(p);
3053 filteredPixel.x += alpha * cp.x;
3054 filteredPixel.y += alpha * cp.y;
3055 filteredPixel.z += alpha * cp.z;
3056 filteredPixel.w += weight * cp.w;
3066 if (itemID < actualNumPixelInThisChunk) {
3067 outputPixelCache[itemID] = (float4)0.0f;
3068 densityCache[itemID] = 0.0f;
3070 gammaCache[itemID] = 0.0f;
3072 barrier(CLK_LOCAL_MEM_FENCE);
3075 for (
unsigned int i = 0; i < numItems; i++) {
3076 if (pixelIndex != -1) {
3077 if (itemID%numItems == i) {
3078 outputPixelCache[pixelIndex]+=filteredPixel;
3079 densityCache[pixelIndex]+=density;
3081 gammaCache[pixelIndex]+=gamma;
3085 barrier(CLK_LOCAL_MEM_FENCE);
3088 if (itemID < actualNumPixelInThisChunk) {
3090 float density = densityCache[itemID];
3091 float4 filteredPixel = outputPixelCache[itemID];
3092 if (density!= 0.0f && density != 1.0)
3095 filteredPixel *= (float4)density;
3097 filteredImage[(chunkStartY+itemID)*filteredColumns+x] = (CLPixelType) (
ClampToQuantum(filteredPixel.x)
3103 float density = densityCache[itemID];
3104 float gamma = gammaCache[itemID];
3105 float4 filteredPixel = outputPixelCache[itemID];
3107 if (density!= 0.0f && density != 1.0) {
3109 filteredPixel *= (float4)density;
3120 filteredImage[(chunkStartY+itemID)*filteredColumns+x] = fp;
3142 __kernel
void UnsharpMaskBlurColumn(
const __global CLPixelType* inputImage,
3143 const __global float4 *blurRowData, __global CLPixelType *filtered_im,
3144 const unsigned int imageColumns,
const unsigned int imageRows,
3145 __local float4* cachedData, __local
float* cachedFilter,
3146 const ChannelType channel,
const __global
float *filter,
const unsigned int width,
3147 const float gain,
const float threshold)
3149 const unsigned int radius = (width-1)/2;
3152 const int groupX = get_group_id(0);
3153 const int groupStartY = get_group_id(1)*get_local_size(1) - radius;
3154 const int groupStopY = (get_group_id(1)+1)*get_local_size(1) + radius;
3156 if (groupStartY >= 0
3157 && groupStopY < imageRows) {
3158 event_t e = async_work_group_strided_copy(cachedData
3159 ,blurRowData+groupStartY*imageColumns+groupX
3160 ,groupStopY-groupStartY,imageColumns,0);
3161 wait_group_events(1,&e);
3164 for (
int i = get_local_id(1); i < (groupStopY - groupStartY); i+=get_local_size(1)) {
3165 cachedData[i] = blurRowData[ClampToCanvas(groupStartY+i,imageRows)*imageColumns+ groupX];
3167 barrier(CLK_LOCAL_MEM_FENCE);
3170 event_t e = async_work_group_copy(cachedFilter,filter,width,0);
3171 wait_group_events(1,&e);
3175 const int cy = get_global_id(1);
3177 if (cy < imageRows) {
3178 float4 blurredPixel = (float4) 0.0f;
3182 \n #ifndef UFACTOR \n
3183 \n #define UFACTOR 8 \n
3186 for ( ; i+UFACTOR < width; )
3188 \n #pragma unroll UFACTOR \n
3189 for (
int j=0; j < UFACTOR; j++, i++)
3191 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
3195 for ( ; i < width; i++)
3197 blurredPixel+=cachedFilter[i]*cachedData[i+get_local_id(1)];
3203 float4 inputImagePixel = convert_float4(inputImage[cy*imageColumns+groupX]);
3204 float4 outputPixel = inputImagePixel - blurredPixel;
3208 int4 mask = isless(fabs(2.0f*outputPixel), (float4)quantumThreshold);
3209 outputPixel = select(inputImagePixel + outputPixel * gain, inputImagePixel, mask);
3222 __kernel
void UnsharpMask(__global CLPixelType *im, __global CLPixelType *filtered_im,
3223 __constant
float *filter,
3224 const unsigned int width,
3225 const unsigned int imageColumns,
const unsigned int imageRows,
3226 __local float4 *pixels,
3227 const float gain,
const float threshold,
const unsigned int justBlur)
3229 const int x = get_global_id(0);
3230 const int y = get_global_id(1);
3232 const unsigned int radius = (width - 1) / 2;
3234 int row = y - radius;
3235 int baseRow = get_group_id(1) * get_local_size(1) - radius;
3236 int endRow = (get_group_id(1) + 1) * get_local_size(1) + radius;
3238 while (row < endRow) {
3239 int srcy = (row < 0) ? -row : row;
3240 srcy = (srcy >= imageRows) ? (2 * imageRows - srcy - 1) : srcy;
3242 float4 value = 0.0f;
3244 int ix = x - radius;
3247 while (i + 7 < width) {
3248 for (
int j = 0; j < 8; ++j) {
3250 srcx = (srcx < 0) ? -srcx : srcx;
3251 srcx = (srcx >= imageColumns) ? (2 * imageColumns - srcx - 1) : srcx;
3252 value += filter[i + j] * convert_float4(im[srcx + srcy * imageColumns]);
3259 int srcx = (ix < 0) ? -ix : ix;
3260 srcx = (srcx >= imageColumns) ? (2 * imageColumns - srcx - 1) : srcx;
3261 value += filter[i] * convert_float4(im[srcx + srcy * imageColumns]);
3265 pixels[(row - baseRow) * get_local_size(0) + get_local_id(0)] = value;
3266 row += get_local_size(1);
3270 barrier(CLK_LOCAL_MEM_FENCE);
3273 const int px = get_local_id(0);
3274 const int py = get_local_id(1);
3275 const int prp = get_local_size(0);
3276 float4 value = (float4)(0.0f);
3279 while (i + 7 < width) {
3280 value += (float4)(filter[i]) * pixels[px + (py + i) * prp];
3281 value += (float4)(filter[i]) * pixels[px + (py + i + 1) * prp];
3282 value += (float4)(filter[i]) * pixels[px + (py + i + 2) * prp];
3283 value += (float4)(filter[i]) * pixels[px + (py + i + 3) * prp];
3284 value += (float4)(filter[i]) * pixels[px + (py + i + 4) * prp];
3285 value += (float4)(filter[i]) * pixels[px + (py + i + 5) * prp];
3286 value += (float4)(filter[i]) * pixels[px + (py + i + 6) * prp];
3287 value += (float4)(filter[i]) * pixels[px + (py + i + 7) * prp];
3291 value += (float4)(filter[i]) * pixels[px + (py + i) * prp];
3294 if ((x < imageColumns) && (y < imageRows)) {
3295 if (justBlur == 0) {
3296 float4 srcPixel = convert_float4(im[x + y * imageColumns]);
3297 float4 diff = srcPixel - value;
3301 int4 mask = isless(fabs(2.0f * diff), (float4)quantumThreshold);
3302 value = select(srcPixel + diff * gain, srcPixel, mask);
3310 __kernel __attribute__((reqd_work_group_size(64, 4, 1)))
void WaveletDenoise(__global CLPixelType *srcImage, __global CLPixelType *dstImage,
3311 const float threshold,
3313 const int imageWidth,
3314 const int imageHeight)
3316 const int pad = (1 << (passes - 1));
3317 const int tileSize = 64;
3318 const int tileRowPixels = 64;
3319 const float noise[] = { 0.8002, 0.2735, 0.1202, 0.0585, 0.0291, 0.0152, 0.0080, 0.0044 };
3321 CLPixelType stage[16];
3323 local
float buffer[64 * 64];
3325 int srcx = (get_group_id(0) + get_global_offset(0) / tileSize) * (tileSize - 2 * pad) - pad + get_local_id(0);
3326 int srcy = (get_group_id(1) + get_global_offset(1) / 4) * (tileSize - 2 * pad) - pad;
3328 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1)) {
3329 stage[i / 4] = srcImage[mirrorTop(mirrorBottom(srcx), imageWidth) + (mirrorTop(mirrorBottom(srcy + i) , imageHeight)) * imageWidth];
3333 for (
int channel = 0; channel < 3; ++channel) {
3337 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3338 buffer[get_local_id(0) + i * tileRowPixels] = convert_float(stage[i / 4].s0);
3341 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3342 buffer[get_local_id(0) + i * tileRowPixels] = convert_float(stage[i / 4].s1);
3345 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3346 buffer[get_local_id(0) + i * tileRowPixels] = convert_float(stage[i / 4].s2);
3357 for (
int pass = 0; pass < passes; ++pass) {
3358 const int radius = 1 << pass;
3359 const int x = get_local_id(0);
3360 const float thresh = threshold * noise[pass];
3363 accum[0] = accum[1] = accum[2] = accum[3] = accum[4] = accum[5] = accum[6] = accum[6] = accum[7] = accum[8] = accum[9] = accum[10] = accum[11] = accum[12] = accum[13] = accum[14] = accum[15] = 0.0f;
3368 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1)) {
3369 const int offset = i * tileRowPixels;
3371 tmp[i / 4] = buffer[x + offset];
3372 pixel = 0.5f * tmp[i / 4] + 0.25 * (buffer[mirrorBottom(x - radius) + offset] + buffer[mirrorTop(x + radius, tileSize) + offset]);
3373 barrier(CLK_LOCAL_MEM_FENCE);
3374 buffer[x + offset] = pixel;
3376 barrier(CLK_LOCAL_MEM_FENCE);
3378 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1)) {
3379 pixel = 0.5f * buffer[x + i * tileRowPixels] + 0.25 * (buffer[x + mirrorBottom(i - radius) * tileRowPixels] + buffer[x + mirrorTop(i + radius, tileRowPixels) * tileRowPixels]);
3380 float delta = tmp[i / 4] - pixel;
3382 if (delta < -thresh)
3384 else if (delta > thresh)
3388 accum[i / 4] += delta;
3391 barrier(CLK_LOCAL_MEM_FENCE);
3392 if (pass < passes - 1)
3393 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3394 buffer[x + i * tileRowPixels] = tmp[i / 4];
3396 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3397 accum[i / 4] += tmp[i / 4];
3398 barrier(CLK_LOCAL_MEM_FENCE);
3403 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3407 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3411 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1))
3416 barrier(CLK_LOCAL_MEM_FENCE);
3421 if ((get_local_id(0) >= pad) && (get_local_id(0) < tileSize - pad) && (srcx >= 0) && (srcx < imageWidth)) {
3423 for (
int i = get_local_id(1); i < tileSize; i += get_local_size(1)) {
3424 if ((i >= pad) && (i < tileSize - pad) && (srcy + i >= 0) && (srcy + i < imageHeight)) {
3425 dstImage[srcx + (srcy + i) * imageWidth] = stage[i / 4];
3433 #endif // MAGICKCORE_OPENCL_SUPPORT 3435 #if defined(__cplusplus) || defined(c_plusplus) 3439 #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:116
Definition: resize-private.h:33
Definition: magick-type.h:198
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:138
Definition: composite.h:31
Definition: composite.h:93
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:293
PixelIntensityMethod
Definition: pixel.h:67
Definition: magick-type.h:187
Definition: composite.h:95
Definition: colorspace.h:59
Definition: magick-type.h:193
Definition: composite.h:59
Definition: composite.h:89
Definition: magick-type.h:182
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:36
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:76
Definition: statistic.h:115
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:139
MagickExport void ConvertRGBToHSL(const Quantum red, const Quantum green, const Quantum blue, double *hue, double *saturation, double *lightness)
Definition: gem.c:1127
Definition: magick-type.h:188
Definition: colorspace.h:48
Definition: statistic.h:117
Definition: magick-type.h:200
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:3554
Definition: colorspace.h:34
Definition: colorspace.h:57
Definition: resize-private.h:30
static double PerceptibleReciprocal(const double x)
Definition: pixel-accessor.h:124
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:184
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:938
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:994
Definition: magick-type.h:186
static void Contrast(const int sign, Quantum *red, Quantum *green, Quantum *blue)
Definition: enhance.c:913
Definition: magick-type.h:201
Definition: composite.h:46
Definition: statistic.h:113
Definition: composite.h:28
Definition: magick-type.h:181
Definition: magick-type.h:190
Definition: colorspace.h:54
Definition: magick-type.h:189
Definition: resize-private.h:39
Definition: composite.h:78
Definition: resize-private.h:34
#define QuantumScale
Definition: magick-type.h:142
Definition: colorspace.h:55
Definition: composite.h:62
Definition: colorspace.h:39
#define MaxMap
Definition: magick-type.h:70
Definition: magick-type.h:197
#define MagickMax(x, y)
Definition: image-private.h:34
Definition: composite.h:98
Definition: composite.h:39
static void CompositeColorDodge(const MagickPixelPacket *p, const MagickPixelPacket *q, MagickPixelPacket *composite)
Definition: composite.c:330
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:177
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:183
static void MagickPixelCompositePlus(const MagickPixelPacket *p, const MagickRealType alpha, const MagickPixelPacket *q, const MagickRealType beta, MagickPixelPacket *composite)
Definition: composite-private.h:111
Definition: composite.h:76
Definition: magick-type.h:179
Definition: colorspace.h:28
Definition: resize-private.h:42
Definition: composite.h:50
Definition: composite.h:36
Definition: composite.h:43
MagickExport MagickRealType GetPixelIntensity(const Image *image, const PixelPacket *magick_restrict pixel)
Definition: pixel.c:2285
static MagickRealType Sinc(const MagickRealType, const ResizeFilter *)
Definition: composite.h:37
Definition: composite.h:60
Definition: statistic.h:114
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
#define MagickMin(x, y)
Definition: image-private.h:35
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:185
Definition: colorspace.h:51
CompositeOperator
Definition: composite.h:25
Definition: composite.h:79
Definition: magick-type.h:192
Definition: colorspace.h:32
Definition: composite.h:66
Definition: composite.h:30
Definition: colorspace.h:60
Definition: magick-type.h:180
Definition: composite.h:63
Definition: composite.h:58
Definition: composite.h:92
Definition: magick-type.h:199
Definition: composite.h:34
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:111
Definition: composite.h:40
Definition: composite.h:67
Definition: resize-private.h:35
#define QuantumRange
Definition: magick-type.h:94
static MagickRealType Triangle(const MagickRealType x, const ResizeFilter *magick_unused(resize_filter))
Definition: resize.c:514
Definition: composite.h:51
Definition: magick-type.h:191
Definition: composite.h:57