// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// imageutil.h
//
// Author:               Sameer Nene
// Date:                 05/17/94
// Version:              1.0
// Modification History:
// Bugs:
//   NormalizeSize is too slow.
//
// Classes:
//   ImageUtil
//
// Notes:
//   This header includes declarations for the class ImageUtil. ImageUtil is a
//   static class which implements miscellaneous useful image operations.
//   
// ----------------------------------------------------------------------------


#ifndef IMAGEUTIL_INCLUDED
#define IMAGEUTIL_INCLUDED

#ifndef ERROR_INCLUDED
#include "errorscope.h"
#endif

#ifdef XSUPPORT
#include <X11/Xlib.h>
#endif

class Vector;
class Image;
class ColorImage;

class ImageUtil : public ErrorScope {

  // Private Data

  static const double A;
  // Parameter for cubic convolution kernel. Use -.5 for mathematical accuracy
  // -1. gives good visual results. For more info., refer to Digital
  // Image Warping - George Wolberg pp. 129-131

  static int d_x1, d_y1, d_x2, d_y2;
  static int d_area;
  
  // Private Functions
  
  static double ckernel(double);
  // Cubic convolution kernel. For more info., refer to Digital Image
  // Warping - George Wolberg pp. 129-131

  static void rlabel(Image*, int x, int y, int THRESHOLD);
  
  // Public Members

public:

  enum {PRESERVE_ASPECT = 0, NOPRESERVE_ASPECT = 1};
  enum {NOGAMMA_CORRECT = 0, GAMMA_CORRECT = 1};

  // Disk Stuff
  
  static Error PGMGetFromDisk(Image*, const char *fileName);
  // Reads PGM formatted file into Image

  static Error PGMDumpToDisk(const Image&, const char *fileName);
  // Dumps Image in PGM format to disk

  static Error PPMGetFromDisk(ColorImage*, const char *fileName);
  // Reads PPM format file into Image

  static Error PPMDumpToDisk(const ColorImage&, const char *fileName);
  // Dumps Image in PPM format to disk

  // Image Processing Stuff

  static void FindBoundingBox(const Image&, int *x1, int *y1, int *x2, int *y2,
			      int THRESHOLD = 20);
  // A crude threshold based segmentation. x1, y1, x2 & y2 return a bounding
  // box for the segmented object

  static void FindBoundingBoxReliable(const ColorImage&,
				      int *x1, int *y1, int *x2, int *y2,
				      int THRESHOLD = 20,
				      int AREATHRESHOLD = 100);
  // x1, y1, x2 & y2 return a bounding box for the segmented object
  
  static void FindBoundingBox(const ColorImage&, int *x1, int *y1, int *x2,
			      int *y2, int THRESHOLD = 40);
  // A crude threshold based segmentation. x1, y1, x2 & y2 return a bounding
  // box for the segmented object

  static void CropImage(const Image&, Vector*, int x1, int y1, int x2, int y2);
  // Crops image with window (x1,y1)-(x2,y2) into Vector

  static void CropImage(const ColorImage&, Vector *r, Vector *g, Vector *b,
			int x1, int y1, int x2, int y2);
  // Crops image with window (x1,y1)-(x2,y2) into Vector

  static void ImageToVector(const Image&, Vector*);
  // converts image to vector

  static void VectorToImage(const Vector&, Image*, int xsize, int ysize,
			    int flag = NOGAMMA_CORRECT);
  // converts vector to image of xsize x ysize at the same time scaling the
  // vector by scale. If flag is supplied as GAMMA_CORRECT, then the Vector is
  // converted to an image with linear gamma of intensities from 0-255. The
  // default simply converts a Vector to an Image. This could be a problem
  // when the Vector has been normalized because the image will then have only
  // ones or zeros.

  static void ImageUtil::VectorToImage(const Vector &red, const Vector &green,
				       const Vector &blue, ColorImage *i,
				       int xsize, int ysize,
				       int flag = NOGAMMA_CORRECT);
  // converts vector to a color image of xsize x ysize at the same time
  // scaling the vector by scale. If flag is supplied as GAMMA_CORRECT, then
  // the Vector is converted to an image with linear gamma of intensities from
  // 0-255. The default simply converts a Vector to a ColorImage. This could be
  // a problem when the Vector has been normalized because the image will then
  // have only ones or zeros.

  static void NormalizeSize(const Image&, Vector*, int x1, int y1, int x2,
			    int y2, int XSIZE = 128, int YSIZE = 128,
			    int aspectFlag = PRESERVE_ASPECT);
  // Crops Image with window (x1,y1)-(x2,y2), resizes cropped image to
  // (XSIZE, YSIZE) and copies into Vector. When PRESERVE_ASPECT is specified,
  // aspect ratio is preserved and the image is centered in the (XSIZE,YSIZE)
  // box. Any extra space is padded with 0s, resulting in a black area.
  // Specifying NOPRESERVE_ASPECT will resize the image to the specified
  // dimensions which could distort the original aspect ratio.

  static void NormalizeSize(const ColorImage&, Vector *r, Vector *g, Vector *b,
			    int x1, int y1, int x2, int y2, int XSIZE = 128,
			    int YSIZE = 128, int aspectFlag = PRESERVE_ASPECT);
  // Crops Image with window (x1,y1)-(x2,y2), resizes cropped image to
  // (XSIZE, YSIZE) and copies into Vector. When PRESERVE_ASPECT is specified,
  // aspect ratio is preserved and the image is centered in the (XSIZE,YSIZE)
  // box. Any extra space is padded with 0s, resulting in a black area.
  // Specifying NOPRESERVE_ASPECT will resize the image to the specified
  // dimensions which could distort the original aspect ratio.

  static void colorImageToMono(const ColorImage&, Image*);
  // convert color image to monochrome

#ifdef XSUPPORT

  static void setXImage(XImage*, const Image&, const unsigned long *lut);
  // converts an Image to an 8 bit XImage. The pixel values of the XImage are
  // obtained from the lookup table lut. The lookup table has 256 entries. It
  // used to map monochrome intensities from Image to XImage pixel values. This
  // method is used mainly in the X utilities to display an Image with a
  // limited set of available colormap entries.

  static void imageToXImage(const Image&, XImage*);
  // converts Image to XImage without color translation.

  static void imageToXImage(const ColorImage&, XImage*);
  // converts Image to XImage without color translation.

#endif
  
};

#endif
