/*
 * Miscellanous type definitions etc...
 *
 * $Date$
 * $Revision$
 *
 */

#ifndef MISCDEFS_H__
#define MISCDEFS_H__
/**
 * @addtogroup WImage
 * @{ */

#include <cfloat>
#include <stdexcept>
#include <string>
#ifndef _WIN32_WCE
#include <iostream>
#else
/* we disable this warning because there is a macro DELETE in the Windows
 * CE toolkit which we just overwrite */
#pragma warning (disable: 4005)
#endif

#ifndef NEW
#define NEW(a)       new a
#endif
#ifndef DELETE
#define DELETE(a)    delete (a), (a) = NULL
#endif
#ifndef DELETEAR
#define DELETEAR(a)  delete [] (a), (a) = NULL
#endif
#ifndef DELETENOTNULL
#define DELETENOTNULL(a) if (a) { DELETE (a); } else {}
#endif
#ifndef DELETENOTNULLAR
#define DELETENOTNULLAR(a) if (a) { DELETEAR (a); } else {}
#endif

/** A pixel value. A one-byte integer type to store one greyscale value in
 * image files. */
typedef unsigned char pixel;
/** A coefficient value. A long floating point type to represent one
 * greyscale value for transforms or the pfi image format. */
typedef double        coeff;

/** Coeff epsilon. The epsilon for equals-operations on the {\em coeff}
 * type. */
#define COEFF_EPSILON ((coeff)DBL_EPSILON)

/** Coeff maximal value. */
#define COEFF_MAX ((coeff)DBL_MAX)

/** Coeff minimal value. */
#define COEFF_MIN ((coeff)DBL_MIN)

/** A two-tuple's maximum value. */
#define MIN(x,y) ((x) < (y)? (x): (y))

/** A two-tuple's minimum value. */
#define MAX(x,y) ((x) > (y)? (x): (y))

/** Macro for dividing a number by two using a shift operation. */
#define DIV2(x) ((unsigned)(x)>>1u)

/** Macro for multiplying a number by two using a shift operation. */
#define MUL2(x) ((unsigned)(x)<<1u)

/** Macro for calculating pow (2, n) using a shift operation. */
#define TWOPOW(n) (1u<<(unsigned)(n))

#define SQUARE(n) ((n)*(n))

/** Macro to circumvent problems with g++-3.0 */
#if defined (__GNUG__) && __GNUG__ >= 3 || defined (__INTEL_COMPILER)
#define FMT0 std::ios_base::fmtflags(0)
#else
#define FMT0 0
#endif

/** The four regions of a one-step transform. If there was more than one
 * step performed we'll find the same structure in the {\em LL} part
 * again. The two rows are: {\em LL}, {\em HL}, {\em LH} and {\em HH}. */
typedef enum { LL = 0, HL, LH, HH, areaINVALID } area;

/** Array for easier iteration over the areas. */
extern const area areas [areaINVALID]; /*= { LL, HL, LH, HH };*/

/** Color models. Either RGB or YUV. */
typedef enum { cm_rgb, cm_yuv, cm_grey, cm_unknown } clrmodel;

/** YUV color model channel names. */
typedef enum { yuv_y = 0, yuv_u, yuv_v, yuv_unknown } yuv;

/** RGB color model channel names. */
typedef enum { rgb_r = 0, rgb_g, rgb_b, rgb_unknown } rgb;

#if defined __WATCOMC__ || defined __GNUC__ && __GNUC__ < 3
#define HAS_NO_IOS_BASE
#endif

#ifdef HAS_NO_IOS_BASE
// Some wrapping for Watcom C++ (does not yet include a full STL)
namespace ios_base {
  class failure : public std::logic_error {
  public:
    failure (std::string const& what_arg)
      : logic_error( what_arg ) {
                    }
  };
  //#define ios_base::app ios::append

  enum open_mode {                  // How to open a stream
    in        = std::ios::in,            // - open for input
    out       = std::ios::out,           // - open for output
    nocreate  = std::ios::nocreate,      // - open only an existing file
    noreplace = std::ios::noreplace,     // - open only a new file
    binary    = std::ios::binary,        // - open as binary file

    app       = std::ios::app,           // Historical purposes
    ate       = std::ios::ate,
    trunc     = std::ios::trunc
  };
}
#endif

/** @} */

#endif /* MISCDEFS_H__ */

/* We put this outside the recursion stopper to allow overriding
 * defines set by some microsoft environments */
#if defined _MSC_VER || defined __WATCOMC__ || defined _WIN32_WCE
/** Moronize code for M\$ idiots. Since you can't compile any line of
 * code using the standard scope for loop variables (variables only
 * visible inside the loop body) with VC++ this circumvention is
 * necessary. */
# define for if(0);else for
# ifdef DELETE
#  undef DELETE
# endif
# define DELETE(a)    delete (a), (a) = NULL
#endif
