/***************************************************************************
 * Unit:    image               release 0.81                               *
 * Purpose: Upper layer for processing raster images                       *
 * Modul:   raster.cc                                                      *
 * Licency: GPL or LGPL                                                    *
 * Copyright: (c) 1998-2025 Jaroslav Fojtik                                *
 ***************************************************************************/
#ifndef __IMAGE_H__
#define __IMAGE_H__

#include "raster.h"


/* ---------- Global class Image --------- */
#include "stringa.h"


#define RAS_IMG_VERSION (0x200 | 81)

// Definition of errors while Loading/Saving File(s)
#define ErrOK		  0
#define ErrOpenFile	 -1
#define ErrReadFile	 -2
#define ErrWriteFile	 -3
#define ErrBadFileFormat -4
#define ErrEmptyRaster   -5
#define ErrUnsupportedResolution -6
#define ErrAccessData	 -7

#define ErrNoMem	-10

extern const char ExifPreffix[6];


typedef struct
{
   uint8_t Red;
   uint8_t Green;
   uint8_t Blue;
} RGB_Record;


class VectorImage;


class PropertyItem
{
public:
  PropertyItem(void);
  PropertyItem(const char *NewName);
  PropertyItem(const char *NewName, unsigned IniSize);
  virtual ~PropertyItem();

  bool Append(const void *OutCode, unsigned CodeSize);

  mutable short UsageCount;
  void *Data;
  uint32_t DataSize;
  string Name;
};


class PropertyItemInt: public PropertyItem
{
public:
  PropertyItemInt(const char *NewName, int Value);
};


class PropertyList
{
public:
  PropertyList(void) {pProperties=NULL;PropCount=0;};
  ~PropertyList();

  void AddProp(PropertyItem *NewProp);
  bool isEmpty(void) const {return PropCount==0 || pProperties==NULL;}
  const PropertyItem *Find(const char *FindName, unsigned &i) const;

  unsigned PropCount;
  PropertyItem **pProperties;
};


void OffsetExif(unsigned char *ExifData, uint32_t ExifSize, int32_t Offset);


class Image
	{
public: Raster2DAbstract *Raster;
	APalette *Palette;
	Image *Next;
	float x,y,dx,dy,RotAngle;
	VectorImage *VecImage;
	PropertyList Properties;

	Image(void): VecImage(NULL)  {RotAngle=x=y=dx=dy=0;Raster=NULL;Next=NULL;Palette=NULL;};
	Image(const Image & I, bool AllFrames=true);
	Image(Raster2DAbstract *NewRaster);
	~Image(void) {Erase();};
	IMAGE_TYPE ImageType(void) const;	// 0-none, 1-gray, 2-palette, 3-true color
	bool isEmpty(void) const;

	Raster2DAbstract *operator=(Raster2DAbstract *NewRaster);
	Image &operator=(const Image & I);

	uint32_t GetPixel(unsigned Offset1D, unsigned Offset2D) const {return(Raster==NULL?0:Raster->GetValue2D(Offset1D,Offset2D));};
	uint32_t GetPixelRGB(unsigned Offset1D, unsigned Offset2D) const;
	
	void SetPixel(unsigned SizeX, unsigned SizeY, uint32_t x) {if(Raster) Raster->SetValue2D(SizeX,SizeY,x);};

	void Create(unsigned SizeX, unsigned SizeY, int Planes);
	void Erase(void);
	void AttachRaster(Raster2DAbstract *NewRaster);
	void AttachPalette(APalette *NewPalette);
	void AttachVecImg(VectorImage *NewVecImg);
	void AttachProperty(PropertyItem *NewProp);
        void AttachPropList(PropertyList &PropL);
	};



int ReducePalette(Image *Img, unsigned maxColors);
bool HasExif(const Image *pI);
void AutoOrient(Image *pI);


/* -----File format loader dynamical list------ */
typedef Image (* TLoadPicture)(const char *Name);
typedef int (*TSavePicture)(const char *Name, const Image &Img);

#define FILE_FORMAT_CAP_EXIF	1
#define FILE_FORMAT_256_COLORS	2
#define FILE_FORMAT_DUPLICATE	4

class TImageFileHandler
	{
private:static TImageFileHandler *First;
	TImageFileHandler *Previous;
	TImageFileHandler *Next;

	const char *Extension;		///< File extension for particulat type.
	const char *Description;

public: TImageFileHandler(const char *NewShortKey, TLoadPicture LoadPicture_XXX=NULL, TSavePicture SavePicture_XXX=NULL, const char *NewDescription=NULL, const uint32_t NewFlags=0);
	~TImageFileHandler();

	TLoadPicture LoadPicture;
	TSavePicture SavePicture;
	uint32_t Flags;
	const char *extension() const {return(Extension);}
	const char *description() const {return(Description);}

	static TImageFileHandler *first(void) {return(First);}
	TImageFileHandler *next() const {return(Next);}
	};

int SavePicture(const char *Name,const Image &Img);
Image LoadPicture(const char *Name);
const char *ReadExt(const char *FileName);



#endif // __IMAGE_H__
