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

#ifndef DJ_PIXEL_H
#define DJ_PIXEL_H
#include <djBox.h>

namespace dj {

// Pixel type:
// * u8 - 8-bit unsigned integer.
// * u16 - 16-bit unsigned integer.
// * f32 - 32-bit float.
//
enum PIXEL_TYPE {
  PIXEL_U8,
  PIXEL_U16,
  PIXEL_F32
};
static const int pixelTypeSize = 3;
typedef uint8_t PixelU8;
typedef uint16_t PixelU16;
typedef float PixelF32;
int pixelSize(PIXEL_TYPE);
static const int pixelU8Min = 0;
static const int pixelU8Max = 255;
static const int pixelU8Range = 256;
static const int pixelU16Min = 0;
static const int pixelU16Max = 65535;
static const int pixelU16Range = 65536;
static const double pixelF32Min = -FLT_MAX;
static const double pixelF32Max = FLT_MAX;

// Pixel format:
// * l - Luminance.
// * la - Luminance, alpha.
// * rgb - Red, green, blue.
// * rgba - Red, green, blue, alpha.
//
enum PIXEL_FORMAT {
  PIXEL_L,
  PIXEL_LA,
  PIXEL_RGB,
  PIXEL_RGBA
};
static const int pixelFormatSize = 4;
static const int pixelFormatMax = 4;
int pixelSize(PIXEL_FORMAT);

// Pixel.
//
class Pixel {
public:

  Pixel();
  Pixel(PIXEL_FORMAT, PIXEL_TYPE);

  // Set.
  //
  void set(PIXEL_FORMAT, PIXEL_TYPE);
  void format(PIXEL_FORMAT);
  void type(PIXEL_TYPE);

  // Get.
  //
  PIXEL_FORMAT format() const { return _format; }
  PIXEL_TYPE type() const { return _type; }

private:

  PIXEL_FORMAT _format;
  PIXEL_TYPE _type;
};
int pixelSize(const Pixel &);

// Functions.
//
void pixelCopy(
  const void * in, void * out,
  int size, const Pixel & inPixel, const Pixel & outPixel,
  int proxyScale = 1,
  bool mirror = false,
  int interleave = 0,
  bool endian = false
);

void pixelPlanar(
  const void * in, void * out,
  const Vec2i & size, PIXEL_FORMAT, PIXEL_TYPE inType, PIXEL_TYPE outType
);

void pixelGradient(void * in, int size, const Pixel &);

void pixelLut(
  const void * in, void * out, int size,
  const void * lutPlanar, int lutSize,
  PIXEL_FORMAT, PIXEL_TYPE inType, PIXEL_TYPE outType
);

// Comparison.
//
bool operator == (const Pixel &, const Pixel &);
bool operator != (const Pixel &, const Pixel &);

// Conversion.
//
PixelU16 pixelU8ToU16(PixelU8);
PixelF32 pixelU8ToF32(PixelU8);
PixelU8  pixelU16ToU8(PixelU16);
PixelF32 pixelU16ToF32(PixelU16);
PixelU8  pixelF32ToU8(PixelF32);
PixelU16 pixelF32ToU16(PixelF32);
void rgbToHsv(const double [3], double [3]);
void hsvToRgb(const double [3], double [3]);

// Serialize.
//
const StrList deflateStr(const Pixel &);
bool inflateStr(StrList &, Pixel *);

// Labels.
//
inline const StrList pixelTypeStr()
  { return StrList() + Str("U8") + Str("U16") + Str("F32"); }
inline const StrList pixelFormatStr()
  { return StrList() + Str("L") + Str("LA") + Str("RGB") + Str("RGBA"); }

// Debugging.
//
Dbg & operator << (Dbg &, PIXEL_TYPE);
Dbg & operator << (Dbg &, PIXEL_FORMAT);
Dbg & operator << (Dbg &, const Pixel &);

}

#include <djPixel_.h>
#endif
