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