/*------------------------------------------------------------------------------
 src/lib/djImage/djImageOpColor.h
 
 Copyright (c) 2004-2006 Darby Johnston.
 All rights reserved.
 Use is subject to license terms.
------------------------------------------------------------------------------*/

#ifndef DJ_IMAGE_OP_COLOR_H
#define DJ_IMAGE_OP_COLOR_H
#include <djImageOp.h>

namespace dj {

// Image pixel operation.
//
class ImageOpPixel : public ImageOp1 {
public:

  ImageOpPixel(bool lut);
  virtual ~ImageOpPixel() = 0;
  
  virtual const Image work(const InputList &) const;

protected:

  virtual void workF32(PixelF32 *, int size, PIXEL_FORMAT) const {}

private:

  bool _lut;
};

// Image lookup table operation.
//
class ImageOpLut : public ImageOp1 {
public:

  const Str name() const { return "LUT"; }
  Plugin * copy() const { return new ImageOpLut(*this); }

  enum ATTR { ATTR_FILE_NAME };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  const StrList attr(const Str &) const;
  
  const PixelDataInfo info(const InfoList &) const;
  const Image work(const InputList &) const;
  
private:

  Str _fileName;
};

// Image color operation base.
//
class ImageOpColor : public ImageOpPixel {
public:

  ImageOpColor(bool lut = false);
  
  enum ATTR { ATTR_VALUE };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  virtual const StrList attr(const Str &) const;

protected:

  Color _value;
};
class ImageOpColor2 : public ImageOpPixel {
public:

  ImageOpColor2(bool lut = false);

  enum ATTR { ATTR_VALUE, ATTR_VALUE_2 };
  const StrList attrNameList() const;
  bool attr(const Str &, const StrList &);
  virtual const StrList attr(const Str &) const;

protected:

  Color _value, _value2;
};

// Image brightness/contrast operations.
//
class ImageOpBrightness : public ImageOpColor {
public:

  ImageOpBrightness();

  const Str name() const { return "Brightness"; }
  Plugin * copy() const { return new ImageOpBrightness(*this); }

protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};
class ImageOpContrast : public ImageOpColor {
public:

  ImageOpContrast();

  const Str name() const { return "Contrast"; }
  Plugin * copy() const { return new ImageOpContrast(*this); }

protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};

// Image hue/saturation operations.
//
class ImageOpHue : public ImageOpColor {
public:

  ImageOpHue();
  
  const Str name() const { return "Hue"; }
  Plugin * copy() const { return new ImageOpHue(*this); }
  
protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};
class ImageOpSaturation : public ImageOpColor {
public:

  const Str name() const { return "Saturation"; }
  Plugin * copy() const { return new ImageOpSaturation(*this); }
  
  //const Image work(const InputList &) const;
  
protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};

// Image gamma/levels operations.
//
class ImageOpGamma : public ImageOpColor {
public:

  ImageOpGamma();
  
  const Str name() const { return "Gamma"; }
  Plugin * copy() const { return new ImageOpGamma(*this); }
  
protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};
class ImageOpLevelsIn : public ImageOpColor2 {
public:

  ImageOpLevelsIn();
  
  const Str name() const { return "Levels In"; }
  Plugin * copy() const { return new ImageOpLevelsIn(*this); }
  
protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};
class ImageOpLevelsOut : public ImageOpColor2 {
public:

  ImageOpLevelsOut();
  
  const Str name() const { return "Levels Out"; }
  Plugin * copy() const { return new ImageOpLevelsOut(*this); }

protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};

// Image soft clip operation.
//
class ImageOpSoftClip : public ImageOpColor {
public:

  ImageOpSoftClip();

  const Str name() const { return "Soft Clip"; }
  Plugin * copy() const { return new ImageOpSoftClip(*this); }

protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};

// Image negate operation.
//
class ImageOpNegate : public ImageOpPixel {
public:

  ImageOpNegate();

  const Str name() const { return "Negate"; }
  Plugin * copy() const { return new ImageOpNegate(*this); }

protected:

  void workF32(PixelF32 *, int size, PIXEL_FORMAT) const;
};

// Utility.
//
inline const List<ImageOp *> imageOpColorList()
{
  List<ImageOp *> out;
  out += new ImageOpLut;
  out += new ImageOpBrightness;
  out += new ImageOpContrast;
  out += new ImageOpHue;
  out += new ImageOpSaturation;
  out += new ImageOpGamma;
  out += new ImageOpLevelsIn;
  out += new ImageOpLevelsOut;
  out += new ImageOpSoftClip;
  out += new ImageOpNegate;
  return out;
}

// Labels.
//
inline const StrList imageOpLutAttrStr()
  { return StrList() + Str("File Name"); }
inline const StrList imageOpColorAttrStr()
  { return StrList() + Str("Value"); }
inline const StrList imageOpColor2AttrStr()
  { return StrList() + Str("Value") + Str("Value 2"); }

}

#endif
