/*
   Implementation of a CLI command using a MagickWand API

     magick -size 100x100 xc:red \
            \( rose: -rotate -90 \) \
            +append   show:


   Compile with ImageMagick-devlop installed...

     gcc -lMagickWand -lMagickCore wand.c -o wand

   Compile and run directly in Source Directory...

     IM_PROG=api_examples/wand
     gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \
       -lMagickWand -lMagickCore  $IM_PROG.c -o $IM_PROG

     sh magick.sh    $IM_PROG

*/
#include <stdio.h>
#include "MagickWand/MagickWand.h"

/* Simplify the exception handling
 * technically we should abort the program if
 *      severity >= ErrorException
 */
void ThrowWandException(MagickWand *wand)
{ char
  *description;

  ExceptionType
  severity;

  description=MagickGetException(wand,&severity);
  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description);
  description=(char *) MagickRelinquishMemory(description);
}

/* useful function especially after appending two wands together */
#define SwapWands(a,b) { MagickWand *tmp=a; a=b; b=tmp; }

int main(int argc, char *argv[])
{
    MagickWand
      *red,     /* red image wand */
      *rose,    /* rose image wand */
      *output;  /* the appended output image */

    PixelWand
      *color;

    MagickBooleanType
      status;

    MagickWandGenesis();

    /* read in the red image */
    red = NewMagickWand();
    MagickSetSize(red,100,100);
    status = MagickReadImage(red, "xc:red" );
    if (status == MagickFalse)
      ThrowWandException(red);
    /* NOTE ABOUT MagickReadImage()
     * Unless the wand is empty set the first/last iterator to determine
     * if the read image(s) are to be prepend/append into that wand image
     * list.
     *
     * Setting a specific index always 'inserts' before that image.
     */

    /* read in the rose image */
    rose = NewMagickWand();
    status = MagickReadImage(rose, "rose:" );
    if (status == MagickFalse)
      ThrowWandException(rose);

    /* rotate the rose image - one image only */
    color=NewPixelWand();
    PixelSetColor(color, "white");
    status = MagickRotateImage(rose,color,-90.0);
    if (status == MagickFalse)
      ThrowWandException(rose);
    color = DestroyPixelWand(color);

    /* append rose image into the red image wand */
    MagickSetLastIterator(red);
    MagickAddImage(red,rose);
    rose = DestroyMagickWand(rose);  /* finished with 'rose' wand */
    /* NOTE ABOUT MagickAddImage()
     *
     * Always set the first/last image in the destination wand so that
     * IM knows if you want to prepend/append the images into that wands
     * image list.
     *
     * Setting a specific index always 'inserts' before that image.
     */

    /* append all images together to create the output wand */
    MagickSetFirstIterator(red);
    output = MagickAppendImages(red,MagickFalse);
    red = DestroyMagickWand(red);  /* finished with 'red' wand */
    /* NOTE ABOUT MagickAppendImages()
     *
     * It is important to either set first or reset the iterator before
     * appending images, as only images from current image onward are
     * appended together.
     *
     * Also note how a new wand is created by this operation, and that want
     * does not inherit any settings from the previous wand (at least not at
     * this time).
     */

    /* Final output */
    status = MagickWriteImage(output,"show:");
    if (status == MagickFalse)
      ThrowWandException(output);

    output = DestroyMagickWand(output);

    MagickWandTerminus();
}

/*
 * The above can be simplified further.
 *
 * Specifically you can read the 'rose' image directly into the 'red' image
 * wand.  Then process just that rose image, even though it is sharing the
 * same wand as another image.
 *
 * Remember in MagickWand, simple image operators are only applied to the
 * current image in the wand an to no other image!  To apply a simple image
 * operator (like MagickRotateImage()) to all the images in a wand you must
 * iterate over all the images yourself.
 */

