#ifndef PNG_H

#ifdef __GNUC__
#  pragma interface
#endif

#include <iostream.h>
#include <fstream.h>
#include "image.H"

class Tchunk {
private:
	int len;			// number of bytes in chunk's data field
	char type[5];		// 4-character type (type[4]==0 always)
	unsigned char *data;	// the data field, if len==0, data==0 also
	unsigned long read_uint4(istream& in);
	bool write_uint4(ostream& out, unsigned long x) const;
	static unsigned long crc(unsigned char *buf, unsigned char *typecode, int len);
	static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len);
	static unsigned long crc_table[256];
	static bool crc_table_computed;
	static void make_crc_table();
public:
	Tchunk();
	Tchunk(const char *typestring, int chunklen);
	bool read(istream& in);
	bool write(ostream& out) const;
	int length() const {return len;}
	const char *typestr() const {return type;}
	unsigned char dataref(int i) const {return data[i];}
	void dataset(int i, unsigned char x) {data[i] = x;}
	unsigned char *data_addr() {return data;}
	unsigned int uint4ref(int i) const {return (data[i] << 24) | (data[i+1] << 16) | (data[i+2] << 8) | data[i+3];}
	void uint4set(int i, unsigned long x) {
		data[i] = (x >> 24) & 0xFF;
		data[i+1] = (x >> 16) & 0xFF;
		data[i+2] = (x >> 8) & 0xFF;
		data[i+3] = x & 0xFF;
	}
	friend ostream& operator<<(ostream& o, const Tchunk& c);
	~Tchunk() {if (data) delete [] data;}
};

extern bool pngcheckheader(istream& in);		// read 8 bytes and check if PNG magic signature
extern bool mngcheckheader(istream& in);		// read 8 bytes and check if MNG magic signature
extern bool pngwriteheader(ostream& out);		// write PNG file header (eight magic bytes)
extern bool mngwriteheader(ostream& out);		// write MNG file header (eight magic bytes)
extern bool pngread(istream& in, Timage& image);	// read PNG chunks IHDR...IEND (file header must be already read)
extern bool pngwrite(ostream& out, const Timage& image);		// write PNG image (IHDR+IDAT+IEND)
extern bool mngreadfirst(istream& in, Timage& image, int& w, int& h);
extern bool mngwritefirst(ostream& out, const Timage& image);
extern bool mngreadnext(istream& in, int w, int h, Timage& image);
extern bool mngwritenext(ostream& out, const Timage& image);
extern bool mngwriteendmark(ostream& out);

#define PNG_H

#endif
