125247ae04ca6720329dae43dda55ff9c35564bbaanthony/*
225247ae04ca6720329dae43dda55ff9c35564bbaanthony   Implementation of a CLI command using a MagickWand API
325247ae04ca6720329dae43dda55ff9c35564bbaanthony
425247ae04ca6720329dae43dda55ff9c35564bbaanthony     magick -size 100x100 xc:red \
525247ae04ca6720329dae43dda55ff9c35564bbaanthony            \( rose: -rotate -90 \) \
625247ae04ca6720329dae43dda55ff9c35564bbaanthony            +append   show:
725247ae04ca6720329dae43dda55ff9c35564bbaanthony
825247ae04ca6720329dae43dda55ff9c35564bbaanthony
925247ae04ca6720329dae43dda55ff9c35564bbaanthony   Compile with ImageMagick-devlop installed...
1025247ae04ca6720329dae43dda55ff9c35564bbaanthony
1125247ae04ca6720329dae43dda55ff9c35564bbaanthony     gcc -lMagickWand -lMagickCore wand.c -o wand
1225247ae04ca6720329dae43dda55ff9c35564bbaanthony
1325247ae04ca6720329dae43dda55ff9c35564bbaanthony   Compile and run directly in Source Directory...
1425247ae04ca6720329dae43dda55ff9c35564bbaanthony
1525247ae04ca6720329dae43dda55ff9c35564bbaanthony     IM_PROG=api_examples/wand
1625247ae04ca6720329dae43dda55ff9c35564bbaanthony     gcc -I`pwd` -LMagickWand/.libs -LMagickCore/.libs \
1725247ae04ca6720329dae43dda55ff9c35564bbaanthony       -lMagickWand -lMagickCore  $IM_PROG.c -o $IM_PROG
1825247ae04ca6720329dae43dda55ff9c35564bbaanthony
1925247ae04ca6720329dae43dda55ff9c35564bbaanthony     sh magick.sh    $IM_PROG
2025247ae04ca6720329dae43dda55ff9c35564bbaanthony
2125247ae04ca6720329dae43dda55ff9c35564bbaanthony*/
2225247ae04ca6720329dae43dda55ff9c35564bbaanthony#include <stdio.h>
2325247ae04ca6720329dae43dda55ff9c35564bbaanthony#include "MagickWand/MagickWand.h"
2425247ae04ca6720329dae43dda55ff9c35564bbaanthony
2525247ae04ca6720329dae43dda55ff9c35564bbaanthony/* Simplify the exception handling
2625247ae04ca6720329dae43dda55ff9c35564bbaanthony * technically we should abort the program if
2725247ae04ca6720329dae43dda55ff9c35564bbaanthony *      severity >= ErrorException
2825247ae04ca6720329dae43dda55ff9c35564bbaanthony */
2925247ae04ca6720329dae43dda55ff9c35564bbaanthonyvoid ThrowWandException(MagickWand *wand)
3025247ae04ca6720329dae43dda55ff9c35564bbaanthony{ char
3125247ae04ca6720329dae43dda55ff9c35564bbaanthony  *description;
3225247ae04ca6720329dae43dda55ff9c35564bbaanthony
3325247ae04ca6720329dae43dda55ff9c35564bbaanthony  ExceptionType
3425247ae04ca6720329dae43dda55ff9c35564bbaanthony  severity;
3525247ae04ca6720329dae43dda55ff9c35564bbaanthony
3625247ae04ca6720329dae43dda55ff9c35564bbaanthony  description=MagickGetException(wand,&severity);
3725247ae04ca6720329dae43dda55ff9c35564bbaanthony  (void) fprintf(stderr,"%s %s %lu %s\n",GetMagickModule(),description);
3825247ae04ca6720329dae43dda55ff9c35564bbaanthony  description=(char *) MagickRelinquishMemory(description);
3925247ae04ca6720329dae43dda55ff9c35564bbaanthony}
4025247ae04ca6720329dae43dda55ff9c35564bbaanthony
4125247ae04ca6720329dae43dda55ff9c35564bbaanthony/* useful function especially after appending two wands together */
4225247ae04ca6720329dae43dda55ff9c35564bbaanthony#define SwapWands(a,b) { MagickWand *tmp=a; a=b; b=tmp; }
4325247ae04ca6720329dae43dda55ff9c35564bbaanthony
4425247ae04ca6720329dae43dda55ff9c35564bbaanthonyint main(int argc, char *argv[])
4525247ae04ca6720329dae43dda55ff9c35564bbaanthony{
4625247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickWand
4725247ae04ca6720329dae43dda55ff9c35564bbaanthony      *red,     /* red image wand */
4825247ae04ca6720329dae43dda55ff9c35564bbaanthony      *rose,    /* rose image wand */
4925247ae04ca6720329dae43dda55ff9c35564bbaanthony      *output;  /* the appended output image */
5025247ae04ca6720329dae43dda55ff9c35564bbaanthony
5125247ae04ca6720329dae43dda55ff9c35564bbaanthony    PixelWand
5225247ae04ca6720329dae43dda55ff9c35564bbaanthony      *color;
5325247ae04ca6720329dae43dda55ff9c35564bbaanthony
5425247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickBooleanType
5525247ae04ca6720329dae43dda55ff9c35564bbaanthony      status;
5625247ae04ca6720329dae43dda55ff9c35564bbaanthony
5725247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickWandGenesis();
5825247ae04ca6720329dae43dda55ff9c35564bbaanthony
5925247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* read in the red image */
6025247ae04ca6720329dae43dda55ff9c35564bbaanthony    red = NewMagickWand();
6125247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickSetSize(red,100,100);
6225247ae04ca6720329dae43dda55ff9c35564bbaanthony    status = MagickReadImage(red, "xc:red" );
6325247ae04ca6720329dae43dda55ff9c35564bbaanthony    if (status == MagickFalse)
6425247ae04ca6720329dae43dda55ff9c35564bbaanthony      ThrowWandException(red);
6525247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* NOTE ABOUT MagickReadImage()
6625247ae04ca6720329dae43dda55ff9c35564bbaanthony     * Unless the wand is empty set the first/last iterator to determine
6725247ae04ca6720329dae43dda55ff9c35564bbaanthony     * if the read image(s) are to be prepend/append into that wand image
6825247ae04ca6720329dae43dda55ff9c35564bbaanthony     * list.
6925247ae04ca6720329dae43dda55ff9c35564bbaanthony     *
7025247ae04ca6720329dae43dda55ff9c35564bbaanthony     * Setting a specific index always 'inserts' before that image.
7125247ae04ca6720329dae43dda55ff9c35564bbaanthony     */
7225247ae04ca6720329dae43dda55ff9c35564bbaanthony
7325247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* read in the rose image */
7425247ae04ca6720329dae43dda55ff9c35564bbaanthony    rose = NewMagickWand();
7525247ae04ca6720329dae43dda55ff9c35564bbaanthony    status = MagickReadImage(rose, "rose:" );
7625247ae04ca6720329dae43dda55ff9c35564bbaanthony    if (status == MagickFalse)
7725247ae04ca6720329dae43dda55ff9c35564bbaanthony      ThrowWandException(rose);
7825247ae04ca6720329dae43dda55ff9c35564bbaanthony
7925247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* rotate the rose image - one image only */
8025247ae04ca6720329dae43dda55ff9c35564bbaanthony    color=NewPixelWand();
8125247ae04ca6720329dae43dda55ff9c35564bbaanthony    PixelSetColor(color, "white");
8225247ae04ca6720329dae43dda55ff9c35564bbaanthony    status = MagickRotateImage(rose,color,-90.0);
8325247ae04ca6720329dae43dda55ff9c35564bbaanthony    if (status == MagickFalse)
8425247ae04ca6720329dae43dda55ff9c35564bbaanthony      ThrowWandException(rose);
8525247ae04ca6720329dae43dda55ff9c35564bbaanthony    color = DestroyPixelWand(color);
8625247ae04ca6720329dae43dda55ff9c35564bbaanthony
8725247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* append rose image into the red image wand */
8825247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickSetLastIterator(red);
8925247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickAddImage(red,rose);
9025247ae04ca6720329dae43dda55ff9c35564bbaanthony    rose = DestroyMagickWand(rose);  /* finished with 'rose' wand */
9125247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* NOTE ABOUT MagickAddImage()
9225247ae04ca6720329dae43dda55ff9c35564bbaanthony     *
9325247ae04ca6720329dae43dda55ff9c35564bbaanthony     * Always set the first/last image in the destination wand so that
9425247ae04ca6720329dae43dda55ff9c35564bbaanthony     * IM knows if you want to prepend/append the images into that wands
9525247ae04ca6720329dae43dda55ff9c35564bbaanthony     * image list.
9625247ae04ca6720329dae43dda55ff9c35564bbaanthony     *
9725247ae04ca6720329dae43dda55ff9c35564bbaanthony     * Setting a specific index always 'inserts' before that image.
9825247ae04ca6720329dae43dda55ff9c35564bbaanthony     */
9925247ae04ca6720329dae43dda55ff9c35564bbaanthony
10025247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* append all images together to create the output wand */
10125247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickSetFirstIterator(red);
10225247ae04ca6720329dae43dda55ff9c35564bbaanthony    output = MagickAppendImages(red,MagickFalse);
10325247ae04ca6720329dae43dda55ff9c35564bbaanthony    red = DestroyMagickWand(red);  /* finished with 'red' wand */
10425247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* NOTE ABOUT MagickAppendImages()
10525247ae04ca6720329dae43dda55ff9c35564bbaanthony     *
10625247ae04ca6720329dae43dda55ff9c35564bbaanthony     * It is important to either set first or reset the iterator before
10725247ae04ca6720329dae43dda55ff9c35564bbaanthony     * appending images, as only images from current image onward are
10825247ae04ca6720329dae43dda55ff9c35564bbaanthony     * appended together.
10925247ae04ca6720329dae43dda55ff9c35564bbaanthony     *
11025247ae04ca6720329dae43dda55ff9c35564bbaanthony     * Also note how a new wand is created by this operation, and that want
11125247ae04ca6720329dae43dda55ff9c35564bbaanthony     * does not inherit any settings from the previous wand (at least not at
11225247ae04ca6720329dae43dda55ff9c35564bbaanthony     * this time).
11325247ae04ca6720329dae43dda55ff9c35564bbaanthony     */
11425247ae04ca6720329dae43dda55ff9c35564bbaanthony
11525247ae04ca6720329dae43dda55ff9c35564bbaanthony    /* Final output */
11625247ae04ca6720329dae43dda55ff9c35564bbaanthony    status = MagickWriteImage(output,"show:");
11725247ae04ca6720329dae43dda55ff9c35564bbaanthony    if (status == MagickFalse)
11825247ae04ca6720329dae43dda55ff9c35564bbaanthony      ThrowWandException(output);
11925247ae04ca6720329dae43dda55ff9c35564bbaanthony
12025247ae04ca6720329dae43dda55ff9c35564bbaanthony    output = DestroyMagickWand(output);
12125247ae04ca6720329dae43dda55ff9c35564bbaanthony
12225247ae04ca6720329dae43dda55ff9c35564bbaanthony    MagickWandTerminus();
12325247ae04ca6720329dae43dda55ff9c35564bbaanthony}
12425247ae04ca6720329dae43dda55ff9c35564bbaanthony
12525247ae04ca6720329dae43dda55ff9c35564bbaanthony/*
12625247ae04ca6720329dae43dda55ff9c35564bbaanthony * The above can be simplified further.
12725247ae04ca6720329dae43dda55ff9c35564bbaanthony *
12825247ae04ca6720329dae43dda55ff9c35564bbaanthony * Specifically you can read the 'rose' image directly into the 'red' image
12925247ae04ca6720329dae43dda55ff9c35564bbaanthony * wand.  Then process just that rose image, even though it is sharing the
13025247ae04ca6720329dae43dda55ff9c35564bbaanthony * same wand as another image.
13125247ae04ca6720329dae43dda55ff9c35564bbaanthony *
13225247ae04ca6720329dae43dda55ff9c35564bbaanthony * Remember in MagickWand, simple image operators are only applied to the
13325247ae04ca6720329dae43dda55ff9c35564bbaanthony * current image in the wand an to no other image!  To apply a simple image
13425247ae04ca6720329dae43dda55ff9c35564bbaanthony * operator (like MagickRotateImage()) to all the images in a wand you must
13525247ae04ca6720329dae43dda55ff9c35564bbaanthony * iterate over all the images yourself.
13625247ae04ca6720329dae43dda55ff9c35564bbaanthony */
13725247ae04ca6720329dae43dda55ff9c35564bbaanthony
138