1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4 #include <magick/MagickCore.h>
5
SigmoidalContrast(ImageView * contrast_view,const ssize_t y,const int id,void * context)6 static MagickBooleanType SigmoidalContrast(ImageView *contrast_view,
7 const ssize_t y,const int id,void *context)
8 {
9 #define QuantumScale ((MagickRealType) 1.0/(MagickRealType) QuantumRange)
10 #define SigmoidalContrast(x) \
11 (QuantumRange*(1.0/(1+exp(10.0*(0.5-QuantumScale*x)))-0.0066928509)*1.0092503)
12
13 RectangleInfo
14 extent;
15
16 register IndexPacket
17 *indexes;
18
19 register PixelPacket
20 *pixels;
21
22 register ssize_t
23 x;
24
25 extent=GetImageViewExtent(contrast_view);
26 pixels=GetImageViewAuthenticPixels(contrast_view);
27 for (x=0; x < (ssize_t) (extent.width-extent.height); x++)
28 {
29 pixels[x].red=RoundToQuantum(SigmoidalContrast(pixels[x].red));
30 pixels[x].green=RoundToQuantum(SigmoidalContrast(pixels[x].green));
31 pixels[x].blue=RoundToQuantum(SigmoidalContrast(pixels[x].blue));
32 pixels[x].opacity=RoundToQuantum(SigmoidalContrast(pixels[x].opacity));
33 }
34 indexes=GetImageViewAuthenticIndexes(contrast_view);
35 if (indexes != (IndexPacket *) NULL)
36 for (x=0; x < (ssize_t) (extent.width-extent.height); x++)
37 indexes[x]=(IndexPacket) RoundToQuantum(SigmoidalContrast(indexes[x]));
38 return(MagickTrue);
39 }
40
main(int argc,char ** argv)41 int main(int argc,char **argv)
42 {
43 #define ThrowImageException(image) \
44 { \
45 \
46 CatchException(exception); \
47 if (contrast_image != (Image *) NULL) \
48 contrast_image=DestroyImage(contrast_image); \
49 exit(-1); \
50 }
51 #define ThrowViewException(view) \
52 { \
53 char \
54 *description; \
55 \
56 ExceptionType \
57 severity; \
58 \
59 description=GetImageViewException(view,&severity); \
60 (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
61 description=(char *) MagickRelinquishMemory(description); \
62 exit(-1); \
63 }
64
65 ExceptionInfo
66 *exception;
67
68 Image
69 *contrast_image;
70
71 ImageInfo
72 *image_info;
73
74 ImageView
75 *contrast_view;
76
77 MagickBooleanType
78 status;
79
80 if (argc != 3)
81 {
82 (void) fprintf(stdout,"Usage: %s image sigmoidal-image\n",argv[0]);
83 exit(0);
84 }
85 /*
86 Read an image.
87 */
88 MagickCoreGenesis(*argv,MagickTrue);
89 image_info=AcquireImageInfo();
90 (void) CopyMagickString(image_info->filename,argv[1],MaxTextExtent);
91 exception=AcquireExceptionInfo();
92 contrast_image=ReadImage(image_info,exception);
93 if (contrast_image == (Image *) NULL)
94 ThrowImageException(contrast_image);
95 /*
96 Sigmoidal non-linearity contrast control.
97 */
98 contrast_view=NewImageView(contrast_image);
99 if (contrast_view == (ImageView *) NULL)
100 ThrowImageException(contrast_image);
101 status=UpdateImageViewIterator(contrast_view,SigmoidalContrast,(void *) NULL);
102 if (status == MagickFalse)
103 ThrowImageException(contrast_image);
104 contrast_view=DestroyImageView(contrast_view);
105 /*
106 Write the image then destroy it.
107 */
108 status=WriteImages(image_info,contrast_image,argv[2],exception);
109 if (status == MagickFalse)
110 ThrowImageException(contrast_image);
111 contrast_image=DestroyImage(contrast_image);
112 exception=DestroyExceptionInfo(exception);
113 image_info=DestroyImageInfo(image_info);
114 MagickCoreTerminus();
115 return(0);
116 }
117