/*
 * Interface of the image operations utilities
 * Author: Martin Dietze
 *
 * $Date$
 * $Revision$
 *
 */

#ifndef MAGICK_INTER_H_INCLUDED
#define MAGICK_INTER_H_INCLUDED

#include <memory>
#include <string>

#include <WImage/ColorImage.hh>

namespace Magick {
  class Image;
}

/**
 * Helper functions for extended read/write support using the Magick++ classes.
 * This is motivated by the fact that we want to support many, many file formats
 * but don't want to spend our time writing import and export filters.
 * The implementation is quite rudimentary. All conversion is done by saving
 * and loading temporary files. Also, naturally (as the Wavelet lib does not
 * have support for this), all meta-information like e.g. transparency is lost.
 */
namespace MagickInter
{
  typedef enum {
    NONE,
    WHITE,
    BLACK
  } TransparencyBackground;

  /**
   * Converts a ColorImage to a Magick::Image.
   * @param img the ColorImage object
   * @param withTransparency if set to true, the returned image will contain
   * transparency information according to the original image's colors.
   * NOTE: this will only work with 3-color images using RGB color model.
   * @param transparentColors an array of as many members as the image has
   * color channels. If at a given position the original image's pixel n-tuple
   * has identical values, the pixel will be considered transparent. The default
   * value NULL stands for { -1, -1, -1 }
   * @param colorBytes the number of bytes per pixel (usually 1, i.e. 256
   * distinct colors)
   * @return a corresponding Magick::Image
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  Magick::Image magickImageFromColorImageWithTransparency (ColorImage &img,
							   bool withTransparency = false,
							   coeff *transparentColors = NULL,
							   int colorBytes = 1);

  /**
   * Converts a ColorImage to a Magick::Image.
   * @param img the ColorImage object
   * @return a corresponding Magick::Image
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  Magick::Image magickImageFromColorImage (ColorImage &img);

  /**
   * Converts a Magick::Image to a ColorImage.
   * @param img the Magick::Image object
   * @return an auto_ptr to the corresponding ColorImage
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  std::auto_ptr<ColorImage> colorImageFromMagickImage (Magick::Image &img);

  /**
   * Creates a ColorImage object for an image in the file system using the
   * Magick classes.
   * @param inFile the input file name
   * @param transparencyBackground if not NONE, enforce WHITE or BLACK for
   * pixels marked as transparent in the image
   * @return an auto_ptr to the new ColorImage
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  std::auto_ptr<ColorImage> obtainColorImage (const std::string &inFile,
					      const TransparencyBackground
					      &transparencyBackground = NONE);

  /**
   * Writes a ColorImage to any file format using the Magick classes.
   * @param img the ColorImage object
   * @param outFile the output file name
   * @param quality the quality (e.g. JPEG quality) if applicable
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  void writeColorImage (ColorImage &img, const std::string &outFile,
			int quality = 100);

  /**
   * Writes a ColorImage to any file format using the Magick classes. This
   * does not use the usual export/import approach but creates an intermediate
   * Magick image from the scratch. However it should be noted that the result
   * may differ slightly from the source image due to Magick's quantization.
   * @param img the ColorImage object
   * @param outFile the output file name
   * @param quality the quality (e.g. JPEG quality) if applicable
   * @param withTransparency if set to true, the returned image will contain
   * transparency information according to the original image's colors.
   * NOTE: this will only work with 3-color images using RGB color model.
   * @param transparentColors an array of as many members as the image has
   * color channels. If at a given position the original image's pixel n-tuple
   * has identical values, the pixel will be considered transparent. The default
   * value NULL stands for { -1, -1, -1 }
   * @param colorBytes the number of bytes per pixel (usually 1, i.e. 256
   * distinct colors)
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  void writeColorImageWithTransparency (ColorImage &img,
					const std::string &outFile,
					int quality = 100,
					bool withTransparency = false,
					coeff *transparentColors = NULL,
					int colorBytes = 1);

  /**
   * Rescales and then writes a ColorImage to any file format using
   * the Magick classes.
   * @param img the ColorImage object
   * @param rows the target number of image rows
   * @param cols the target number of image cols
   * @param outFile the output file name
   * @param quality the quality (e.g. JPEG quality) if applicable
   * @exception ios_base:failure if an I/O operation did not succeed (e.g.
   * non-existent file, insufficient disk space etc.)
   * @exception invalid_argument for logical errors (e.g. unknown image file
   * format etc.)
   */
  void scaleAndWriteColorImage (ColorImage &img, int rows, int cols,
				const std::string &outFile, int quality = 100);
}

#endif // MAGICK_INTER_H_INCLUDED
