1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4#include <wand/MagickWand.h>
5
6static MagickBooleanType SigmoidalContrast(WandView *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  MagickPixelPacket
17    pixel;
18
19  PixelWand
20    **pixels;
21
22  register ssize_t
23    x;
24
25  extent=GetWandViewExtent(contrast_view);
26  pixels=GetWandViewPixels(contrast_view);
27  for (x=0; x < (ssize_t) (extent.width-extent.x); x++)
28  {
29    PixelGetMagickColor(pixels[x],&pixel);
30    pixel.red=SigmoidalContrast(pixel.red);
31    pixel.green=SigmoidalContrast(pixel.green);
32    pixel.blue=SigmoidalContrast(pixel.blue);
33    pixel.index=SigmoidalContrast(pixel.index);
34    PixelSetMagickColor(pixels[x],&pixel);
35  }
36  return(MagickTrue);
37}
38
39int main(int argc,char **argv)
40{
41#define ThrowViewException(view) \
42{ \
43  description=GetWandViewException(view,&severity); \
44  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
45  description=(char *) MagickRelinquishMemory(description); \
46  exit(-1); \
47}
48#define ThrowWandException(wand) \
49{ \
50  description=MagickGetException(wand,&severity); \
51  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description); \
52  description=(char *) MagickRelinquishMemory(description); \
53  exit(-1); \
54}
55
56  char
57    *description;
58
59  ExceptionType
60    severity;
61
62  MagickBooleanType
63    status;
64
65  MagickPixelPacket
66    pixel;
67
68  MagickWand
69    *contrast_wand;
70
71  WandView
72    *contrast_view;
73
74  if (argc != 3)
75    {
76      (void) fprintf(stdout,"Usage: %s image sigmoidal-image\n",argv[0]);
77      exit(0);
78    }
79  /*
80    Read an image.
81  */
82  MagickWandGenesis();
83  contrast_wand=NewMagickWand();
84  status=MagickReadImage(contrast_wand,argv[1]);
85  if (status == MagickFalse)
86    ThrowWandException(contrast_wand);
87  /*
88    Sigmoidal non-linearity contrast control.
89  */
90  contrast_view=NewWandView(contrast_wand);
91  if (contrast_view == (WandView *) NULL)
92    ThrowWandException(contrast_wand);
93  status=UpdateWandViewIterator(contrast_view,SigmoidalContrast,(void *) NULL);
94  if (status == MagickFalse)
95    ThrowWandException(contrast_wand);
96  contrast_view=DestroyWandView(contrast_view);
97  /*
98    Write the image then destroy it.
99  */
100  status=MagickWriteImages(contrast_wand,argv[2],MagickTrue);
101  if (status == MagickFalse)
102    ThrowWandException(contrast_wand);
103  contrast_wand=DestroyMagickWand(contrast_wand);
104  MagickWandTerminus();
105  return(0);
106}
107