/***************************************************************************
 * Unit:    raster            release 0.40                                 *
 * Purpose: Prototypes for general manipulation n dimensional matrices     *
 * Modul:   raster.cc                                                      *
 * Licency: GPL or LGPL                                                    *
 * Copyright: (c) 1998-2026 Jaroslav Fojtik                                *
 ***************************************************************************/
#ifndef __Rasters_h
#define __Rasters_h

#include "typedfs.h"

#define RASTER_VERSION (0x100*0 | 40)

#ifndef No_Memory
 #define No_Memory    0x1
#endif

#if defined(uint64_t_defined)
 #define uint64_t_fix uint64_t
#else
 #define uint64_t_fix double
#endif



#ifdef _MSC_VER
 #pragma warning (push)
 #pragma warning (disable: 4250; disable: 4100) 
#endif
#ifdef __GNUC__
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  #pragma GCC diagnostic push
 #endif
 #pragma GCC diagnostic ignored "-Wunused-parameter"
#endif


#define RASTER_2D_VIRTUALS virtual void Lock2D(unsigned pos2D)	{}; \
                           virtual void UnLock2D(unsigned pos2D) {};


#ifndef RASTER_2D_VIRTUALS
  /** This Macro allows to push extra wirtual methods into RASTER_2D parent. */
  #define RASTER_2D_VIRTUALS
#endif

#ifdef _REENTRANT
  #define MP_CONST const
#else
  #define MP_CONST
#endif


#ifdef __cplusplus
extern "C" {
#endif

#ifndef RGBQuad_DEFINED
#define RGBQuad_DEFINED
typedef struct
	{
	uint32_t R,G,B,O;
	} RGBQuad;
#endif


#if defined(LO_ENDIAN) || defined(HI_ENDIAN)
/*
 #ifdef LO_ENDIAN
  #define Conv32_1(__Source,__Dest, __Count) Peel1BitNStep(__Source, 3+(const uint8_t*)(__Dest), __Count, 0x407)
 #endif
 #ifdef HI_ENDIAN
  #define Conv32_1(__Source,__Dest, __Count) Peel1BitNStep(__Source, (const uint8_t*)(__Dest), __Count, 0x407)
 #endif
*/

 #if defined(uint64_t_defined)
  #ifdef LO_ENDIAN  
   #define Conv64_1(__Source,__Dest, __Count) Peel1BitNStep(__Source, 7+(const uint8_t*)(__Dest), __Count, 0x807)
   #define Conv64_8(__Source,__Dest, __Count) Peel8BitNStep(__Source, 7+(const uint8_t*)(__Dest), __Count, 8);
  #endif
  #ifdef HI_ENDIAN
   #define Conv64_1(__Source,__Dest, __Count) Peel1BitNStep(__Source, (const uint8_t*)(__Dest), __Count, 0x807)
   #define Conv64_8(__Source,__Dest, __Count) Peel8BitNStep(__Source, (const uint8_t*)(__Dest), __Count, 8);
  #endif
 #endif

#endif

#ifdef OPTIMISE_SPEED
void Conv1_2(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
#endif
void Conv1_4(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv1_8(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv1_16(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv1_24(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv1_32(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
#ifdef OPTIMISE_SPEED
void Conv2_1(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv2_8(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv2_16(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv2_24(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv2_32(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
#endif
void Conv4_1(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_8(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_16(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_24(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_32(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_1(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_4(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_16(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_24(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_32(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv16_1(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_4(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_8(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_24(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_32(uint32_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv24_1(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv24_4(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv24_8(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv24_16(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv24_32(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
#ifndef Conv32_1
 void Conv32_1(uint8_t *Dest, const uint32_t *Src, unsigned Size1D);
#endif
void Conv32_4(uint8_t *Dest, const uint32_t *Src, unsigned Size1D);
void Conv32_8(uint8_t *Dest, const uint32_t *Src, unsigned Size1D);
void Conv32_16(uint16_t *Dest, const uint32_t *Src, unsigned Size1D);
void Conv32_24(uint8_t *Dest, const uint32_t *Src, unsigned Size1D);

#if defined(uint64_t_defined)
void Conv1_64(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_64(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_64(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv16_64(uint64_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv24_64(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv32_64(uint64_t *Dest, const uint32_t *Src, unsigned Size1D);

void Conv64_24(uint8_t *Dest, const uint64_t *Src, unsigned Size1D);
void Conv64_32(uint32_t *Dest, const uint64_t *Src, unsigned Size1D);
void Conv64_16(uint16_t *Dest, const uint64_t *Src, unsigned Size1D);
//void Conv64_8(uint8_t *Dest, const uint64_t *Src, unsigned Size1D);
#endif


void Flip1(uint8_t *b, unsigned len);
void Flip2(uint8_t *b, unsigned len);
void Flip4(uint8_t *b, unsigned len);
void Flip8(uint8_t *b, unsigned len);
void Flip16(uint16_t *w, unsigned len);
void Flip24(uint8_t *b, unsigned len);
void Flip32(uint32_t *d, unsigned len);
void Flip64(uint64_t_fix *d, unsigned len);
void FlipN(uint8_t *d, unsigned len, unsigned char BPP);

void Peel1BitNStep(uint8_t *Buffer1Bit, const uint8_t *BufferSrc, unsigned count, uint16_t PlaneStep);
void Join1BitNStep(const uint8_t *Buffer1Bit, uint8_t *Buffer, unsigned count, uint16_t PlaneStep);
void Peel8BitNStep(uint8_t *Buffer8Bit, const uint8_t *BufferSrc, unsigned count, uint8_t ByteStep);
void Join8BitNStep(const uint8_t *Buffer8Bit, uint8_t *Buffer, unsigned count, uint8_t ByteStep);
void Join16BitNStep(const uint16_t *Buffer16Bit, uint16_t *Buffer, unsigned count, uint8_t ByteStep);
void Peel16BitNStep(uint16_t *Buffer16Bit, const uint16_t *BufferSrc, unsigned count, uint8_t WordStep);


#ifdef USE_MMX
void Conv4_8_MMX(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_16_MMX(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_32_MMX(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_4_MMX(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_16_MMX(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_32_MMX(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv16_4_MMX(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_8_MMX(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_32_MMX(uint32_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv32_16_MMX(uint16_t *Dest, const uint32_t *Src, unsigned Size1D);
 #if defined(uint64_t_defined)
  void Conv4_64_MMX(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  void Conv8_64_MMX(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  void Conv16_64_MMX(uint64_t *Dest, const uint16_t *Src, unsigned Size1D);
  void Conv32_64_MMX(uint64_t *Dest, const uint32_t *Src, unsigned Size1D);
 #endif
#endif
#ifdef USE_SSE
void Conv4_8_SSE(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_16_SSE(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv4_32_SSE(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_4_SSE(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_16_SSE(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv8_32_SSE(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
void Conv16_4_SSE(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_8_SSE(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv16_32_SSE(uint32_t *Dest, const uint16_t *Src, unsigned Size1D);
void Conv32_16_SSE(uint16_t *Dest, const uint32_t *Src, unsigned Size1D);
 #if defined(uint64_t_defined)
  void Conv4_64_SSE(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  void Conv8_64_SSE(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  void Conv16_64_SSE(uint64_t *Dest, const uint16_t *Src, unsigned Size1D);
  void Conv32_64_SSE(uint64_t *Dest, const uint32_t *Src, unsigned Size1D);
 #endif
#endif

#if defined(USE_MMX) || defined(USE_SSE)
extern void (*Conv4_8dyn)(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv4_16dyn)(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv4_32dyn)(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv8_4dyn)(uint8_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv8_16dyn)(uint16_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv8_32dyn)(uint32_t *Dest, const uint8_t *Src, unsigned Size1D);
extern void (*Conv16_4dyn)(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
extern void (*Conv16_8dyn)(uint8_t *Dest, const uint16_t *Src, unsigned Size1D);
extern void (*Conv16_32dyn)(uint32_t *Dest, const uint16_t *Src, unsigned Size1D);
extern void (*Conv32_16dyn)(uint16_t *Dest, const uint32_t *Src, unsigned Size1D);

 #if defined(uint64_t_defined)
  extern void (*Conv4_64dyn)(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  extern void (*Conv8_64dyn)(uint64_t *Dest, const uint8_t *Src, unsigned Size1D);
  extern void (*Conv16_64dyn)(uint64_t *Dest, const uint16_t *Src, unsigned Size1D);
  extern void (*Conv32_64dyn)(uint64_t *Dest, const uint32_t *Src, unsigned Size1D);    
 #endif

#define Conv4_8 Conv4_8dyn
#define Conv4_16 Conv4_16dyn
#define Conv4_32 Conv4_32dyn
#define Conv4_64 Conv4_64dyn
#define Conv8_4 Conv8_4dyn
#define Conv8_16 Conv8_16dyn
#define Conv8_32 Conv8_32dyn
#define Conv8_64 Conv8_64dyn
#define Conv16_4 Conv16_4dyn
#define Conv16_8 Conv16_8dyn
#define Conv16_32 Conv16_32dyn
#define Conv16_64 Conv16_64dyn
#define Conv32_16 Conv32_16dyn
#define Conv32_64 Conv32_64dyn


#endif


#ifdef __cplusplus
}

#ifdef __BORLANDC__
 #include "common.h"
#endif


void AbstractError(const char *Name=NULL);
int NearAvailPlanes(int n);

#ifndef ABSTRACT_ERROR
 #ifdef CORRUPTED_ABSTRACT
  #define ABSTRACT_ERROR(abs_name) {AbstractError(abs_name);}
 #else
  #define ABSTRACT_ERROR(abs_name) =0
 #endif
#endif
#ifndef ABSTRACT_ERRORi
 #ifdef CORRUPTED_ABSTRACT
  #define ABSTRACT_ERRORi(abs_name) {AbstractError(abs_name);return(0);}
 #else
  #define ABSTRACT_ERRORi(abs_name) =0
 #endif
#endif


/** Base class for 1D data. */
class Raster1DAbstract
{
public: mutable long UsageCount;
	bool Shadow;			// The data are not allocated/deallocated with this object.
	unsigned Size1D;
	void *Data1D;

	Raster1DAbstract(void) {Size1D=UsageCount=0;Data1D=NULL;Shadow=false;};
	virtual ~Raster1DAbstract() 		{Erase1DStub();};

	virtual void Allocate1D(unsigned NewSize1D);
	virtual void Erase(void)		{Erase1DStub();};
	virtual void Erase1D(void)		{Erase1DStub();};
	virtual void Cleanup(void);
	void Erase1DStub(void);

	virtual uint32_t GetValue1D(unsigned x) const {return(0);};
	virtual double GetValue1Dd(unsigned x) const {return(GetValue1D(x));};
	virtual void SetValue1D(unsigned x, uint32_t NewValue) ABSTRACT_ERROR("SetValue1D");
	virtual void SetValue1Dd(unsigned x, double NewValue) {SetValue1D(x,(uint32_t)NewValue);};
        virtual void Set(unsigned x, const RGBQuad *RGB) {SetValue1D(x,(RGB->R+RGB->G+RGB->B)/3);};
	virtual void Get(unsigned x, RGBQuad *RGB) const {RGB->O=0;RGB->R=RGB->G=RGB->B=GetValue1D(x);};

	virtual int GetPlanes(void) const {return(0);};
	virtual unsigned GetSize1D(void) const {return(Size1D);};
	virtual unsigned char Channels(void) const {return 1;};
	void *GetRow(void)          {return(Data1D);};

/* This set of functions copy internal data in the proper format to the given buffer. */
	virtual void Get(Raster1DAbstract &R1) const;
	virtual void Get24BitRGB(void *Buffer24Bit) const;

/* This set of functions receives given data and stores them to the internal structure. */
	virtual void Set(const Raster1DAbstract &R1);

/* Bitwise operation with raster buffer. */
	virtual void Peel1Bit(void *Buffer1Bit, uint8_t plane) const;
	virtual void Join1Bit(const void *Buffer1Bit, uint8_t plane);
	virtual void Peel8Bit(void *Buffer8Bit, uint8_t plane8) const;
	virtual void Join8Bit(const void *Buffer8Bit, uint8_t plane8);

	virtual Raster1DAbstract *GetPalette(void) {return(NULL);}
	virtual void SetPalette(Raster1DAbstract *NewPalette) {AbstractError("Raster1DAbstract::SetPalette");}
	friend Raster1DAbstract *CreateRaster1D(unsigned SizeX, int Planes);	

protected:
#ifdef _REENTRANT
        virtual uint32_t PTR_GetValue1D(const void *RAW_Data1D, unsigned x) const {return(0);};
	virtual double PTR_GetValue1Dd(const void *RAW_Data1D, unsigned x) const {return(PTR_GetValue1D(RAW_Data1D,x));};
	virtual void PTR_SetValue1D(void *RAW_Data1D, unsigned x, uint32_t NewValue) const = 0; // {AbstractError("RAW_SetValue1D");};
	virtual void PTR_SetValue1Dd(void *RAW_Data1D, unsigned x, double NewValue) const {PTR_SetValue1D(RAW_Data1D,x,(uint32_t)NewValue);};
        virtual void PTR_Get(const void *RAW_Data1D, Raster1DAbstract &R1) const;
        virtual void PTR_Set(void *RAW_Data1D, const Raster1DAbstract &R1);
        //virtual void PTR_Get(const void *RAW_Data1D, unsigned x, RGBQuad *RGB) const {RGB->O=0;RGB->R=RGB->G=RGB->B=PTR_GetValue1D(RAW_Data1D,x);};
#endif
};
Raster1DAbstract *CreateRaster1D(unsigned Size1D, int Planes);


class Raster1DAbstractRGB: virtual public Raster1DAbstract
{
public:
    virtual uint32_t GetValue1DRAW(unsigned x) const ABSTRACT_ERRORi("Raster1DAbstractRGB::GetValue1DRAW");
    virtual void SetValue1DRAW(unsigned x, uint32_t NewValue) ABSTRACT_ERROR("Raster1DAbstractRGB::SetValue1DRAW");

    virtual unsigned char Channels(void) const {return 3;};

    virtual void Set(const Raster1DAbstract &R1);
    virtual void Set(const Raster1DAbstract &R1, const Raster1DAbstract &Palette);
    virtual void Set(unsigned x, const RGBQuad *RGB);

    virtual void Get(Raster1DAbstract &R1) const;
    virtual void Get(unsigned x, RGBQuad *RGB) const;

    virtual uint32_t R(unsigned x) const {return(GetValue1DRAW(3*x));}
    virtual uint32_t G(unsigned x) const {return(GetValue1DRAW(3*x+1));}
    virtual uint32_t B(unsigned x) const {return(GetValue1DRAW(3*x+2));}

    void setR(unsigned x, uint32_t newR) {SetValue1DRAW(3*x,newR);};
    void setG(unsigned x, uint32_t newG) {SetValue1DRAW(3*x+1,newG);};
    void setB(unsigned x, uint32_t newB) {SetValue1DRAW(3*x+2,newB);};
    void setA(unsigned x, uint32_t newA) {};

    friend Raster1DAbstractRGB *CreateRaster1DRGB(unsigned SizeX, unsigned Planes);

#ifdef _REENTRANT
protected:
    virtual uint32_t PTR_GetValue1DRAW(const void *RAW_Data1D, unsigned x) const = 0; // {AbstractError("PTR_GetValue1DRAW");return 0;};
    virtual void PTR_SetValue1DRAW(void *RAW_Data1D, unsigned x, uint32_t NewValue) = 0; // {AbstractError("PTR_SetValue1DRAW");};
#endif
};
Raster1DAbstractRGB *CreateRaster1DRGB(unsigned Size1D, int Planes);


class Raster1DAbstractRGBA: virtual public Raster1DAbstractRGB
{
public:
    virtual uint32_t GetValue1DRAW(unsigned x) const ABSTRACT_ERRORi("Raster1DAbstractRGBA::GetValue1DRAW");
    virtual void SetValue1DRAW(unsigned x, uint32_t NewValue) ABSTRACT_ERROR("Raster1DAbstractRGBA::SetValue1DRAW");

    virtual unsigned char Channels(void) const {return 4;};

    virtual void Set(const Raster1DAbstract &R1);

    virtual void Get(unsigned x, RGBQuad *RGB) const;
    virtual void Set(unsigned x, const RGBQuad *RGB);

    uint32_t R(unsigned x) const {return(GetValue1DRAW(4*x));}
    uint32_t G(unsigned x) const {return(GetValue1DRAW(4*x+1));}
    uint32_t B(unsigned x) const {return(GetValue1DRAW(4*x+2));}
    uint32_t A(unsigned x) const {return(GetValue1DRAW(4*x+3));}

    void setR(unsigned x, uint32_t newR) {SetValue1DRAW(4*x  ,newR);};
    void setG(unsigned x, uint32_t newG) {SetValue1DRAW(4*x+1,newG);};
    void setB(unsigned x, uint32_t newB) {SetValue1DRAW(4*x+2,newB);};
    void setA(unsigned x, uint32_t newA) {SetValue1DRAW(4*x+3,newA);};

    friend Raster1DAbstractRGBA *CreateRaster1DRGBA(unsigned Size1D, int Planes);

#ifdef _REENTRANT
protected:
    virtual uint32_t PTR_GetValue1DRAW(const void *RAW_Data1D, unsigned x) const = 0; // {AbstractError("PTR_GetValue1DRAW");return 0;};
    virtual void PTR_SetValue1DRAW(void *RAW_Data1D, unsigned x, uint32_t NewValue) = 0; // {AbstractError("PTR_SetValue1DRAW");};
#endif
};

Raster1DAbstractRGBA *CreateRaster1DRGBA(unsigned Size1D, int Planes);


class Raster2DAbstract: virtual public Raster1DAbstract
{
public: unsigned Size2D;
	void **Data2D;

	Raster2DAbstract(void) {Size2D=0;Data2D=NULL;}
	virtual ~Raster2DAbstract() 			{Erase2DStub();}

	virtual void Allocate2D(unsigned NewSize1D, unsigned NewSize2D);
	virtual void Erase(void)			{Erase2DStub();}
	virtual void Erase2D(void)			{Erase2DStub();}
	virtual void Cleanup(void);
        unsigned GetSize2D(void) const {return(Size2D);};

	uint32_t GetValue2D(unsigned Offset1D, unsigned Offset2D) MP_CONST;
	double GetValue2Dd(unsigned Offset1D, unsigned Offset2D) MP_CONST;
	void SetValue2D(unsigned Offset1D, unsigned Offset2D, long x);
	void SetValue2Dd(unsigned Offset1D, unsigned Offset2D, double x);

	void *GetRow(unsigned Offset2D)   {if(Data2D==NULL || Offset2D>=Size2D) return(NULL);return(Data2D[Offset2D]);}
        const void *GetRow(unsigned Offset2D) const {if(Data2D==NULL || Offset2D>=Size2D) return(NULL);return(Data2D[Offset2D]);}
        void Get(unsigned Offset1D, unsigned Offset2D, RGBQuad *RGB);
        void Set(unsigned Offset1D, unsigned Offset2D, const RGBQuad *RGB);

	Raster1DAbstract *GetRowRaster(unsigned Offset2D);

        void Get(unsigned Offset2D, Raster1DAbstract &R1) MP_CONST;
        void Set(unsigned Offset2D, const Raster1DAbstract &R1);

	friend Raster2DAbstract *CreateRaster2D(unsigned Size1D, unsigned Size2D, int Planes);

        RASTER_2D_VIRTUALS

protected:
	void Erase2DStub(void);

#if defined(_REENTRANT) && defined(RASTER_3D)
        uint32_t PTR_GetValue2D(const void **RAW_Data2D, unsigned Offset1D, unsigned Offset2D) const;
	double PTR_GetValue2Dd(const void **RAW_Data2D, unsigned Offset1D, unsigned Offset2D) const;
	void PTR_SetValue2D(void **RAW_Data2D, unsigned Offset1D, unsigned Offset2D, uint32_t NewValue) const;
	void PTR_SetValue2Dd(void **RAW_Data2D, unsigned Offset1D, unsigned Offset2D, double NewValue) const;
        void PTR_Get(const void **RAW_Data2D, unsigned Offset2D, Raster1DAbstract &R1) const;
        void PTR_Set(void **RAW_Data2D, unsigned Offset2D, const Raster1DAbstract &R1);
#endif
};

Raster2DAbstract *CreateRaster2D(unsigned Size1D, unsigned Size2D, int Planes);


/// 2D raster with RGB data interpretation and 8bits per channel.
class Raster2DAbstractRGB: virtual public Raster2DAbstract, virtual public Raster1DAbstractRGB
{
public:
	virtual uint32_t GetValue2DRAW(unsigned Offset1D, unsigned Offset2D);
	virtual void SetValue2DRAW(unsigned Offset1D, unsigned Offset2D, uint32_t x);

	uint32_t R(unsigned x, unsigned y) {return(GetValue2DRAW(3*x,y));}
	uint32_t G(unsigned x, unsigned y) {return(GetValue2DRAW(3*x+1,y));}
	uint32_t B(unsigned x, unsigned y) {return(GetValue2DRAW(3*x+2,y));}

	void setR(unsigned x, unsigned y, uint32_t newR) {SetValue2DRAW(3*x,y,newR);};
	void setG(unsigned x, unsigned y, uint32_t newG) {SetValue2DRAW(3*x+1,y,newG);};
	void setB(unsigned x, unsigned y, uint32_t newB) {SetValue2DRAW(3*x+2,y,newB);};

	Raster1DAbstractRGB *GetRowRasterRGB(unsigned Offset2D);

	friend Raster2DAbstractRGB *CreateRaster2DRGB(unsigned SizeX, unsigned SizeY, int Planes);
};

Raster2DAbstractRGB *CreateRaster2DRGB(unsigned Size1D, unsigned Size2D, int Planes);


class Raster2DAbstractRGBA: virtual public Raster2DAbstractRGB, virtual public Raster1DAbstractRGBA
{
public:
	virtual uint32_t GetValue2DRAW(unsigned Offset1D, unsigned Offset2D);
	virtual void SetValue2DRAW(unsigned Offset1D, unsigned Offset2D, uint32_t x);

	uint32_t R(unsigned x, unsigned y) {return(GetValue2DRAW(4*x,y));}
	uint32_t G(unsigned x, unsigned y) {return(GetValue2DRAW(4*x+1,y));}
	uint32_t B(unsigned x, unsigned y) {return(GetValue2DRAW(4*x+2,y));}
	uint32_t A(unsigned x, unsigned y) {return(GetValue2DRAW(4*x+3,y));}

	void setR(unsigned x, unsigned y, uint32_t newR) {SetValue2DRAW(4*x,y,newR);};
	void setG(unsigned x, unsigned y, uint32_t newG) {SetValue2DRAW(4*x+1,y,newG);};
	void setB(unsigned x, unsigned y, uint32_t newB) {SetValue2DRAW(4*x+2,y,newB);};
	void setA(unsigned x, unsigned y, uint32_t newA) {SetValue2DRAW(4*x+3,y,newA);};

	//virtual void A(unsigned x, uint32_t newA) {Raster1DAbstractRGBA::A(x,newA);};

	friend Raster2DAbstractRGBA *CreateRaster2DRGBA(unsigned SizeX, unsigned SizeY, int Planes);
};

Raster2DAbstractRGBA *CreateRaster2DRGBA(unsigned Size1D, unsigned Size2D, int Planes);




class Raster2DColorAbstract: public Raster1DAbstract
{
public: Raster1DAbstract *palette;

	virtual Raster1DAbstract *GetPalette(void) {return(palette);}
	virtual void SetPalette(Raster1DAbstract *NewPalette) {if(palette!=NULL) delete(palette); palette=NewPalette;}
};


#ifdef RASTER_3D
class Raster3DAbstract: virtual public Raster2DAbstract
	{
public: unsigned Size3D;
	void ***Data3D;

	Raster3DAbstract(void) {Size3D=0;Data3D=NULL;}
	virtual ~Raster3DAbstract() 			{Erase3DStub();}

	virtual void Allocate3D(unsigned NewSize1D, unsigned NewSize2D, unsigned NewSize3D);
	virtual void Erase(void)			{Erase3DStub();}
	virtual void Erase3D(void)			{Erase3DStub();}
        virtual void Cleanup(void);
        unsigned GetSize3D(void) const {return(Size3D);};

	uint32_t GetValue3D(unsigned Offset1D, unsigned Offset2D, unsigned Offset3D) MP_CONST;
        double GetValue3Dd(unsigned Offset1D, unsigned Offset2D, unsigned Offset3D) MP_CONST;
	void SetValue3D(unsigned Offset1D, unsigned Offset2D, unsigned Offset3D, uint32_t x);
        void SetValue3Dd(unsigned Offset1D, unsigned Offset2D, unsigned Offset3D, double x);

	void **GetRow(unsigned Offset3D)   {if(Data3D==NULL || Offset3D>=Size3D) return(NULL);return(Data3D[Offset3D]);}

        void Get(unsigned Offset2D, unsigned Offset3D, Raster1DAbstract &R1) MP_CONST;
        void Set(unsigned Offset2D, unsigned Offset3D, const Raster1DAbstract &R1);

        Raster1DAbstract *GetRowRaster(unsigned Offset2D, unsigned Offset3D);
	Raster2DAbstract *GetRowRaster(unsigned Offset3D);

        void *GetRow(unsigned Offset2D, unsigned Offset3D)   {if(Data3D==NULL || Offset3D>=Size3D) return(NULL);return(Data3D[Offset3D][Offset2D]);}
        const void *GetRow(unsigned Offset2D, unsigned Offset3D) const {if(Data3D==NULL || Offset3D>=Size3D) return(NULL);return(Data3D[Offset3D][Offset2D]);}

	void Erase3DStub(void);

        virtual Raster3DAbstract *CreateShadow(void);
	friend Raster3DAbstract *CreateRaster3D(unsigned Size1D, unsigned Size2D, unsigned Size3D, int Planes);
	};
Raster3DAbstract *CreateRaster3D(unsigned Size1D, unsigned Size2D, unsigned Size3D, int Planes);

void Flip1D(Raster3DAbstract *r3D);
void Flip2D(Raster3DAbstract *r3D);
void Flip3D(Raster3DAbstract *r3D);
#endif



class APalette: virtual public Raster1DAbstractRGB
	{
public: friend APalette *BuildPalette(unsigned Indices, char type);

        virtual void SetPalette(Raster1DAbstract *NewPalette) {AbstractError("APalette::SetPalette");}
	};
APalette *BuildPalette(unsigned Indices, char type=0);


typedef enum
{
  ImageNone = 0,	 //-none,
  ImageGray = 0x100,	 //1-gray,
  ImagePalette = 0x200,	 //2-palette,
  ImageTrueColor = 0x300, //3-true color - RGB
  ImagePaletteF=0x2000,	 //there is used abundant palette
  ImageReal =   0x4000,  //Real numbers are used
  ImageSigned = 0x8000	 //image uses signed numbers
} IMAGE_TYPE;


typedef enum
{
  EPS_DrawElipse =    1,
  EPS_colorimage =    2,
  EPS_rlecmapimage =  4,
  EPS_accentshow  =   8,
  EPS_ACCENTSHOW  =  16,
  EPS_FillBox1    =  32,
  EPS_FillBox2    =  64,
  EPS_FillPlus	  = 128,
  EPS_FillBalls	  = 256,
  EPS_FillTriangle= 512,
  EPS_FillSmSquare=1024,
  EPS_FillBricks   =2048,
  EPS_FillDiagBricks=4096,
  EPS_FillHoneycomb=8192,
  EPS_FillFishscale=16384,
#if !defined(__BORLANDC__) || (__BORLANDC__>=0x0500)
  EPS_FillArch   =  32768,
  EPS_FillChainlink=65536,
  EPS_FillPatio=  0x20000,
  EPS_FillWeave=  0x40000,
  EPS_FillWaves = 0x80000
#else
  #define EPS_FillArch 32768
  #define EPS_FillChainlink 65536
  #define EPS_FillPatio 0x20000
  #define EPS_FillWeave 0x40000
  #define EPS_FillWaves 0x80000
#endif
} EPS_COMPONENTS;



void Flip1D(Raster1DAbstract *r1D);

void Flip1D(Raster2DAbstract *r2D);
void Flip2D(Raster2DAbstract *r2D);
Raster2DAbstract *Flip1D2D(Raster2DAbstract *r2D);
int GrayPalette(APalette *Palette, int Planes=0);
int FillGray(Raster1DAbstractRGB *Palette, int Planes=0);



#endif // C++


#ifdef __GNUC__
 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
  #pragma GCC diagnostic pop
 #endif
#endif
#ifdef _MSC_VER 
 #pragma warning (pop)
#endif
#endif //__Rasters_h
