// ----------------------------------------------------------------------------
//
// 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.
//
// ----------------------------------------------------------------------------
//
// image.h
//
// Author:               Sameer Nene
// Date:                 05/17/94
// Version:              1.0
// Modification History:
// Bugs:
//
// Classes:
//   Image
//
// Notes:
//   This header includes declarations for the class Image. Besides being able
//   to store images, the class has several useful image processing methods.
//   
// ----------------------------------------------------------------------------


#ifndef IMAGE_INCLUDED
#define IMAGE_INCLUDED

class ImageUtil;
class VideoPixUtil;
class AnalogicsUtil;
class J300Util;
class J300ColorUtil;
class YUVPixel;

class Image {

  // Private Data

  int d_xsize, d_ysize;
  unsigned char *d_data_p;

  // Friends

  friend ImageUtil;
  friend VideoPixUtil;
  friend AnalogicsUtil;
  friend J300Util;
  
  // Public Functions

public:

  // Construct & Destroy

  Image();
  Image(int xsize, int ysize);
  Image(const Image&);
  ~Image();

  // Manipulators

  Image& operator=(const Image&);
  void set(int x, int y, int d);

  Image& operator-=(const Image&);
  // byte wise subtraction

  Image& paste(const Image &img, int x1 = 0, int y1 = 0);
  // pastes img to this image at x1, y1

  Image& booleanOr(const Image &img, int x1 = 0, int y1 = 0);
  // does a bitwise or operation between this image and img starting at
  // x1, y1

  Image& booleanAnd(const Image &img, int x1 = 0, int y1 = 0);
  // does a bitwise and operation between this image and img starting at
  // x1, y1

  Image& toBinary(int threshold = 20);
  // converts image to binary (0 | 255) by a simple thresholding
  
  // Accessors

  int get(int x, int y) const;
  int getXSize() const;
  int getYSize() const;

  int similarity(const Image&) const;
  // measure of similarity between two images. Lower return values mean greater
  // similarity
  
  Image& copy(Image *img, int x1, int y1, int x2, int y2) const;
  // copies window (x1, y1) - (x2, y2) of this image to img

};

class RGBPixel {

  // Private Data

  unsigned char d_red, d_blue, d_green;

friend J300Util;

  // Public Functions

public:

  // Construct & Destroy

  RGBPixel();
  RGBPixel(int red, int green, int blue);
  RGBPixel(const YUVPixel&);
  //RGBPixel(const RGBPixel&);

  // Modifiers

  //RGBPixel& operator=(const RGBPixel&);
  
  void red(int v);
  void green(int v);
  void blue(int v);

  // Accessors

  int red() const;
  int green() const;
  int blue() const;

};

class YUVPixel {

  // Private Data

  unsigned char d_y, d_u, d_v;

friend J300Util;

  // Public Functions

public:

  // Construct & Destroy

  YUVPixel();
  YUVPixel(int y, int u, int v);
  YUVPixel(const RGBPixel&);
  //YUVPixel(const YUVPixel&);

  // Modifiers

  //YUVPixel& operator=(const YUVPixel&);
  
  void y(int v);
  void u(int v);
  void v(int v);

  // Accessors

  int y() const;
  int u() const;
  int v() const;

};

class ColorImage {

  // Private Data

  int d_xsize, d_ysize;
  unsigned char *d_data_p;

  // Friends

  friend ImageUtil;
  friend VideoPixUtil;
  friend AnalogicsUtil;
  friend J300Util;
  friend J300ColorUtil;
  
  // Public Functions

public:

  // Construct & Destroy

  ColorImage();
  ColorImage(int xsize, int ysize);
  ColorImage(const ColorImage&);
  ~ColorImage();

  // Manipulators

  ColorImage& operator=(const ColorImage&);
  void set(int x, int y, int v);
  void set(int x, int y, int red, int green, int blue);
  void set(int x, int y, const RGBPixel&);

  ColorImage& paste(const ColorImage &img, int x1 = 0, int y1 = 0);
  // pastes img to this image at x1, y1

  void get(int x, int y, int *red, int *green, int *blue) const;
  RGBPixel get(int x, int y) const;
  int getXSize() const;
  int getYSize() const;

};

class YUVImage {

  // Private Data

  int d_xsize, d_ysize;
  unsigned char *d_ydata_p, *d_udata_p, *d_vdata_p;

  // Friends

  friend ImageUtil;
  friend VideoPixUtil;
  friend AnalogicsUtil;
  friend J300Util;
  
  // Public Functions

public:

  // Construct & Destroy

  YUVImage();
  YUVImage(int xsize, int ysize);
  YUVImage(const YUVImage&);
  ~YUVImage();

  // Manipulators

  YUVImage& operator=(const YUVImage&);
  void set(int x, int y, int v);
  void set(int x, int y, int Y, int U, int V);
  void set(int x, int y, const YUVPixel&);

  void get(int x, int y, int *Y, int *U, int *V) const;
  YUVPixel get(int x, int y) const;
  int getXSize() const;
  int getYSize() const;

};

#endif
