 /*File Name: PicturMatrix.cpp
  Author: Betti Österholz ; Date: 25.08.2003
  System: C++
  

  Copyright (C) 2004  Betti Österholz

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, June 1991, of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "PicturMatrix.h"


PicturMatrix::PicturMatrix():NumberOfColorComponents(0),NumberOfPositionComponents(0)
//standart constructor constructs a blank object
{

Depth=new unsigned int[1];;
Depth[0]=0;

Matrix=new Color****[0];
Matrix[0]=new Color***[0];
Matrix[0][0]=new Color**[0];
Matrix[0][0][0]=new Color*[0];
Matrix[0][0][0][0]=0;
Size=new unsigned long[4];
for (int a=0;a<4;a++)
	Size[a]=1;
Background=new Color(1);
Background->setValueToValue(1,0);
}

PicturMatrix::PicturMatrix(unsigned long* sz,unsigned int ncc,unsigned int* dep)
//parameter constructor
//constructs a matrix sz great with everywher 0 pointer(no entry)
//pre: the size sz the new matrix should have
//  the number of components of the color vectors and the depth of
//  each of this components
{
unsigned short npc=0;
for (unsigned short i=0;i<4;i++)
{
	if (sz[i]!=0) npc++;
}
NumberOfPositionComponents=npc;
NumberOfColorComponents=ncc;
Depth=new unsigned int[NumberOfColorComponents];
for (unsigned int i=0;i<ncc;i++)
	{Depth[i]=dep[i];}
Size=new unsigned long[4];
for (int a=0;a<4;a++)
	Size[a]=sz[a];
Matrix=new Color****[Size[0]];
unsigned long i[4];
for (i[0]=0;i[0]<Size[0];i[0]++)
{
	Matrix[i[0]]=new Color***[Size[1]];
	for (i[1]=0;i[1]<Size[1];i[1]++)
	{
		Matrix[i[0]][i[1]]=new Color**[Size[2]];
		for (i[2]=0;i[2]<Size[2];i[2]++)
		{
			Matrix[i[0]][i[1]][i[2]]=new Color*[Size[3]];
			for (i[3]=0;i[3]<Size[3];i[3]++)
			{
				Matrix[i[0]][i[1]][i[2]][i[3]]=0;
			}
		}
	}
}
Background=new Color(3);
Background->setValueToValue(1,0);
Background->setValueToValue(2,0);
Background->setValueToValue(3,0);
}

PicturMatrix::PicturMatrix(const PicturMatrix& matrx,bool copy)
//if copy is true constructs a object with the same values as the given
//else constructs a object with the same values but the Matrix values/Color pointers are all set to 0
{
NumberOfColorComponents=matrx.getNumberOfColorComponents();
NumberOfPositionComponents=matrx.getNumberOfPositionComponents();
Depth=new unsigned int[NumberOfColorComponents];
for (unsigned int a=0;a<NumberOfColorComponents;a++)
	{Depth[a]=matrx.getDepthOfComponent(a+1);}
Size=matrx.getSize();
unsigned long i[4];
Matrix=new Color****[Size[0]];
for (i[0]=0;i[0]<Size[0];i[0]++)
{
	Matrix[i[0]]=new Color***[Size[1]];
	for (i[1]=0;i[1]<Size[1];i[1]++)
	{
		Matrix[i[0]][i[1]]=new Color**[Size[2]];
		for (i[2]=0;i[2]<Size[2];i[2]++)
		{
			Matrix[i[0]][i[1]][i[2]]=new Color*[Size[3]];
			for (i[3]=0;i[3]<Size[3];i[3]++)
			{
				if (copy)
				{
					Color* tmp=matrx.getColorFrom(i);
					if (tmp) {Matrix[i[0]][i[1]][i[2]][i[3]]=tmp->copy();}
					else {Matrix[i[0]][i[1]][i[2]][i[3]]=0;}
				}else {Matrix[i[0]][i[1]][i[2]][i[3]]=0;}
			}
		}
	}
}
Background=(matrx.getBackgroundColor())->copy();
}

PicturMatrix::PicturMatrix(char* file)
//load constructor
//constructs a object with the values as the given fram a file
{
Size=new unsigned long[4];
for (int a=0;a<4;a++)
	Size[a]=1;
Matrix=new Color****[0];
Matrix[0]=new Color***[0];
Matrix[0][0]=new Color**[0];
Matrix[0][0][0]=new Color*[0];
Matrix[0][0][0][0]=0;
Background=new Color(1);
Background->setValueToValue(1,0);
Depth=new unsigned int[1];
if (!(load(file)))
{
	NumberOfPositionComponents=0;
	NumberOfColorComponents=0;
	Depth=new unsigned int[NumberOfColorComponents];
}
}

PicturMatrix::~PicturMatrix()
//destructor
{
long i[4];
for (i[0]=Size[0]-1;i[0]>=0;i[0]--)
{
	for (i[1]=Size[1]-1;i[1]>=0;i[1]--)
	{
		for (i[2]=Size[2]-1;i[2]>=0;i[2]--)
		{
			for (i[3]=Size[3]-1;i[3]>=0;i[3]--)
			{
				if (Matrix[i[0]][i[1]][i[2]][i[3]]) {delete Matrix[i[0]][i[1]][i[2]][i[3]];}
			}
			delete Matrix[i[0]][i[1]][i[2]];
		}
	delete Matrix[i[0]][i[1]];
	}
delete Matrix[i[0]];
}
delete Matrix;
delete Size;
delete Depth;
delete Background;
}

unsigned long* PicturMatrix::getSize() const
//returns the size of the Matrix
//post: the unsigned int[4] array of the size
{
unsigned long *sz=new unsigned long[4];
for (int a=0;a<4;a++)
	sz[a]=Size[a];
return sz;
}

bool PicturMatrix::setColorOnPosition(unsigned long* pos,Color col)
//insert on the position ps in the Matrix a copy of the given color
//object col, the eventuell old Color object on this position is deleted
//if no ReferenceColor is defined it set also the ReferenceColor to
//the same type as the given Color object col
//pre: the Color col to insert an the position pos to insert
{
if ((pos[0]<Size[0])&&(pos[1]<Size[1])&&(pos[2]<Size[2])&&(pos[3]<Size[3])){
	if (Matrix[pos[0]][pos[1]][pos[2]][pos[3]])
	{//ther is a Color object on the position in the Matrix
		delete Matrix[pos[0]][pos[1]][pos[2]][pos[3]];
		Matrix[pos[0]][pos[1]][pos[2]][pos[3]]=col.copyValue();
	}else{//ther is no Color object on the position in the Matrix yet
		Matrix[pos[0]][pos[1]][pos[2]][pos[3]]=col.copyValue();
	}
	return true;
}
return false;
}

void PicturMatrix::overlap(PicturMatrix matrix)
//if in the given matrix is on a position a Color Object a copy
//of this is insert on the same Position in the Matrix of this Object
//if on this position is a 0 pointer and the position exsists(lower
//Size)
//pre: the PicturMatrix matrix to insert with this Pictur matrix oferlapping
{
unsigned long i[4];
for (i[0]=0;i[0]<Size[0];i[0]++)
	for (i[1]=0;i[1]<Size[1];i[1]++)
		for (i[2]=0;i[2]<Size[2];i[2]++)
			for (i[3]=0;i[3]<Size[3];i[3]++)
			{
				if (Matrix[i[0]][i[1]][i[2]][i[3]]==0)
				{
					Color* tmp=matrix.getColorFrom(i);
					if (tmp) Matrix[i[0]][i[1]][i[2]][i[3]]=tmp->copy();
				}
			}
}

bool PicturMatrix::load(char* file)
//load a pictur Matrix from the file with name file
//pre: the name of the file to load the PicturMatrix from
{
//read the ending of the file name
unsigned int end_part=0;
unsigned int i=0;
while (file[i]!=false)
{
	if (file[i]=='.') {end_part=i+1;}
	i++;
}
char fileend[i-end_part];
for (unsigned int a=end_part;a<i;a++)
{
	fileend[a-end_part]=file[a];
}
if (fileend[1]=='m')
	{return loadBitmap(file);}//fileend = bmp
if (fileend[1]=='t')
	{return load_btx(file);}//fileend = btx
return false;
}

bool PicturMatrix::store(char* file)
//store this pictur Matrix to the file with name file
//pre: the name of the file to load the PicturMatrix from
{
//read the ending of the file name
unsigned int end_part=0;
unsigned int i=0;
while (file[i]!=false)
{
	if (file[i]=='.') {end_part=i+1;}
	i++;
}
char fileend[i-end_part];
for (unsigned int a=end_part;a<i;a++)
{
	fileend[a-end_part]=file[a];
}
if (fileend[1]=='m')
	{return saveBitmap(file);}//fileend = bmp
if (fileend[1]=='t')
	{return save_btx(file);}//fileend = btx
return false;
}

unsigned long PicturMatrix::distanceTo(PicturMatrix matrix) const
//evaluate the distance from the given PicturMatrix matrix
//pre: the PicturMatrix to evaluate the distance from this PicturMatrix
//post: a unsigned long number for the distance
{
unsigned long dist=0;
long dtmp;//temporal distant of tow color components
double* tmp1;
double* tmp2;//temporal Color Component pointer
Color* tmpc;
Color* tmpc1;
unsigned long i[4];
for (i[0]=0;i[0]<Size[0];i[0]++)
	for (i[1]=0;i[1]<Size[1];i[1]++)
		for (i[2]=0;i[2]<Size[2];i[2]++)
			for (i[3]=0;i[3]<Size[3];i[3]++)
			{
				tmpc=matrix.getColorFrom(i);
				tmpc1=getColorFrom(i);
				for (unsigned int a=1;a<=getNumberOfColorComponents();a++)
				{
					tmp1=tmpc1->getComponentPointer(a);
					tmp2=tmpc->getComponentPointer(a);
					dtmp=(long)((*tmp1)-(*tmp2));
					if (dtmp<0) {dtmp=-dtmp;}//abs function
					if ((unsigned long)dtmp>Depth[a-1])
						{dist=dist+Depth[a-1];}
					else{
						dist=dist+dtmp;;
					}
				}
			}
return dist;
}

unsigned long PicturMatrix::distanceOfArea(PicturMatrix matrix, unsigned long* from, unsigned long* to) const
//evaluate the distance from the given PicturMatrix matrix in the area
//from to to(inclusiv to)
//pre: the PicturMatrix to evaluate the distance from this PicturMatrix,
//  the lower bound from and upper bound to of the area
//post: a unsigned long number for the distance
{
unsigned long dist=0;
long dtmp;//temporal distant of tow color components
double* tmp1;
double* tmp2;//temporal Color Component pointer
Color* tmpc;
Color* tmpc1;
unsigned long i[4];
for (i[0]=from[0];i[0]<=to[0];i[0]++)
	for (i[1]=from[1];i[1]<=to[1];i[1]++)
		for (i[2]=from[2];i[2]<=to[2];i[2]++)
			for (i[3]=from[3];i[3]<=to[3];i[3]++)
			{
				tmpc=matrix.getColorFrom(i);
				tmpc1=getColorFrom(i);
				for (unsigned int a=1;a<=getNumberOfColorComponents();a++)
				{
					tmp1=tmpc1->getComponentPointer(a);
					tmp2=tmpc->getComponentPointer(a);
					dtmp=(long)((*tmp1)-(*tmp2));
					if (dtmp<0) dtmp=-dtmp;//abs function
					if ((unsigned long)dtmp>Depth[a-1])
						{dist=Depth[a-1];}
					else{
						dist=dist+dtmp;
					}
				}
			}
return dist;
}

void PicturMatrix::resize(unsigned long* nsize)
//resize the Matrix to the new size nsize
//pre: the new size of of the object nsize
{
long i[4];
Color *****tmatrix=new Color****[nsize[0]];//matrix to save values
for (i[0]=0;i[0]<(long)nsize[0];i[0]++)
{
	tmatrix[i[0]]=new Color***[nsize[1]];
	for (i[1]=0;i[1]<(long)nsize[1];i[1]++)
	{
		tmatrix[i[0]][i[1]]=new Color**[nsize[2]];
		for (i[2]=0;i[2]<(long)nsize[2];i[2]++)
		{
			tmatrix[i[0]][i[1]][i[2]]=new Color*[nsize[3]];
			for (i[3]=0;i[3]<(long)nsize[3];i[3]++)
			{
				if((i[0]<(long)Size[0])&&(i[1]<(long)Size[1])&&(i[2]<(long)Size[2])&&(i[3]<(long)Size[3]))
					{tmatrix[i[0]][i[1]][i[2]][i[3]]=Matrix[i[0]][i[1]][i[2]][i[3]];}
			}
		}
	}
}
//delete old Matrix
for (i[0]=Size[0]-1;i[0]>=0;i[0]--)
{
	for (i[1]=Size[1]-1;i[1]>=0;i[1]--)
	{
		for (i[2]=Size[2]-1;i[2]>=0;i[2]--)
		{
			for (i[3]=Size[3]-1;i[3]>=0;i[3]--)
			{
				//delet all color who don't needed anymore
				if ((Matrix[i[0]][i[1]][i[2]][i[3]])&&(i[0]>=(long)nsize[0])&&(i[1]>=(long)nsize[1])&&(i[2]>=(long)nsize[2])&&(i[3]>=(long)nsize[3]))
					{delete Matrix[i[0]][i[1]][i[2]][i[3]];}
			}
			delete Matrix[i[0]][i[1]][i[2]];
		}
	delete Matrix[i[0]][i[1]];
	}
delete Matrix[i[0]];
}
delete Matrix;
//copy values back to orginal matrix
Matrix=new Color****[nsize[0]];
for (i[0]=0;i[0]<(long)nsize[0];i[0]++)
{
	Matrix[i[0]]=new Color***[nsize[1]];
	for (i[1]=0;i[1]<(long)nsize[1];i[1]++)
	{
		Matrix[i[0]][i[1]]=new Color**[nsize[2]];
		for (i[2]=0;i[2]<(long)nsize[2];i[2]++)
		{
			Matrix[i[0]][i[1]][i[2]]=new Color*[nsize[3]];
			for (i[3]=0;i[3]<(long)nsize[3];i[3]++)
			{
				if((i[0]<(long)Size[0])&&(i[1]<(long)Size[1])&&(i[2]<(long)Size[2])&&(i[3]<(long)Size[3]))
					{Matrix[i[0]][i[1]][i[2]][i[3]]=tmatrix[i[0]][i[1]][i[2]][i[3]];}
				else{Matrix[i[0]][i[1]][i[2]][i[3]]=0;}
			}
		}
	}
}

//delete tmatrix(why eror?)
/*for (i[0]=nsize[0]-1;i[0]>=0;i[0]--)
{
	for (i[1]=nsize[0]-1;i[1]>=0;i[1]--)
	{
		for (i[2]=nsize[0]-1;i[2]>=0;i[2]--)
		{
			//don't delet the color objects
			cout<<" delte matrix "<<endl<<flush;
			delete tmatrix[i[0]][i[1]][i[2]];
		}
	delete tmatrix[i[0]][i[1]];
	}
delete tmatrix[i[0]];
}
delete tmatrix;
*/

for (int a=0;a<4;a++)
	Size[a]=nsize[a];
}


void PicturMatrix::clear()
//clears the matrix; deletes all Color Objects in it
//post: a blank Matrix
{
long i[4];
for (i[0]=Size[0]-1;i[0]>=0;i[0]--)
{
	for (i[1]=Size[1]-1;i[1]>=0;i[1]--)
	{
		for (i[2]=Size[2]-1;i[2]>=0;i[2]--)
		{
			for (i[3]=Size[3]-1;i[3]>=0;i[3]--)
			{
				//delet all color who don't needed anymore
				if (Matrix[i[0]][i[1]][i[2]][i[3]])
					{
						delete Matrix[i[0]][i[1]][i[2]][i[3]];
						Matrix[i[0]][i[1]][i[2]][i[3]]=0;
					}
			}
		}
	}
}
}

bool PicturMatrix::loadBitmap(char* file)
//load a pictur Matrix from the bitmap pictur file with name file
//pre: the name of the bitmap pictur file to load the PicturMatrix from
{
FILE *stream=fopen( file, "r" );
if (stream==NULL){return false;};
NumberOfPositionComponents=2;
unsigned char c1,c2;
c1=readint(stream,1);c2=readint(stream,1);//identifier
unsigned int filesize=readint(stream,4);//filesize
readint(stream,4);//reserved
readint(stream,4);//Offset from filebegin till data
readint(stream,4);//bitmap header size
unsigned long *nsize=new unsigned long[4];
nsize[1]=readint(stream,4);//horizontale width of bitmap pixels
nsize[0]=readint(stream,4);//vertical width of bitmap pixels
nsize[2]=1;
nsize[3]=1;
readint(stream,2);//number of planes in this bitmap should be 1
unsigned int bpp=readint(stream,2);//bits per pixel
readint(stream,4);//compression specification, should be 0=none
readint(stream,4);//size of bitmap data
readint(stream,4);//horizontal pixel per meter, uninportant
readint(stream,4);//vertical pixel per meter, uninportant
unsigned int col=readint(stream,4);//number of colors
if (((nsize[0]*nsize[1]*nsize[2]*nsize[3])/8)>filesize)
	//if what you maximal need to save the all points of the pictur is biger the the filesize, there is an error
	{nsize[0]=0;nsize[1]=0;nsize[2]=0;nsize[3]=0;col=0;bpp=3;}
resize(nsize);//make big enougth matrix
delete Depth;
switch (bpp)
{
case 1:Depth=new unsigned int[1];
	Depth[0]=2;
	NumberOfColorComponents=1;
	col=2;
	break;
case 4:Depth=new unsigned int[1];
	Depth[0]=16;
	NumberOfColorComponents=1;
	break;
case 8:Depth=new unsigned int[1];
	Depth[0]=256;
	NumberOfColorComponents=1;
	break;
case 16:Depth=new unsigned int[2];
	Depth[0]=256;
	Depth[1]=256;
	NumberOfColorComponents=2;
	break;
case 24:Depth=new unsigned int[3];
	Depth[0]=256;
	Depth[1]=256;
	Depth[2]=256;
	NumberOfColorComponents=3;
	break ;
case 32:Depth=new unsigned int[3];
	Depth[0]=256;
	Depth[1]=256;
	Depth[2]=65536;
	NumberOfColorComponents=3;
	break;
}
readint(stream,4);//number of important colors, should be equal number of colors
//color table
if ((col==0)&&(bpp==4)){col=16;}
if (!((bpp==24)))
	for (unsigned int i=0;i<col;i++ )
	{
		cout<<"color "<<i<<"  0;R;G;B "<<readint(stream,1)<<";"<<readint(stream,1)<<";"<<readint(stream,1)<<";"<<readint(stream,1)<<endl;
	}
//read pixels
long pos[4]={0,0,0,0};
if (bpp==24)
{
	Color col=Color(3);
	int n=0;
	for (pos[0]=(long)(Size[0]-1);pos[0]>=0;pos[0]-- )
	{
		for (pos[1]=0;pos[1]<(long)Size[1];pos[1]++ )
		{
			col.setValueToValue(1,(int)readint(stream,1));
			col.setValueToValue(2,(int)readint(stream,1));
			col.setValueToValue(3,(int)readint(stream,1));
			n=n+3;
			setColorOnPosition((unsigned long*)pos,col);
		}
		n=4-(n-(n/4*4));
		if (n==4) {n=0;}
		readint(stream,n);
		n=0;
	}
	delete Background;
	Background=new Color(3);
	Background->setValueToValue(1,0);
	Background->setValueToValue(2,0);
	Background->setValueToValue(3,0);
}
if (bpp==1)//black and whit pictur
{
	Color col=Color(1);
	int w;
	int n=0;
	int rest;
	for (unsigned int xi=0;xi<nsize[0];)
	{
   	for (unsigned int yi=0;yi<nsize[1];)
		{
			int bw=readint(stream,1);n++;
			rest=((int)nsize[1]-((int)yi));
			for (int i=0;i<8;i++)
			{
				w=bw;
				bw=bw*2;
				if (bw>=256){bw-=256;}
				if (w==(bw/2))
					{col.setValueToValue(1,0);}
				else{col.setValueToValue(1,1);}
				pos[0]=nsize[0]-1-xi;
				pos[1]=yi;//upside down
				setColorOnPosition((unsigned long*)pos,col);
				//actualisize position
				yi++;
				if ((xi==nsize[0])&&(yi==nsize[1]))
					{break;}
				else{
					if ((yi==nsize[1])&&(i<8))
					{
						xi++;
						break;
					}
				if (i>=rest)
					{break;}
				}
			}
		}
		//every line ends with the 32 bit word of the file bitmapdata area
		n=4-(n-(n/4*4));
		if (n==4) {n=0;}
		readint(stream,n);
		n=0;
	}
}
if (bpp==4)//pictur with 16 Colors
{
	int bw;
	int n=0;
	Color col=Color(1);
	for (pos[0]=(long)(Size[0]-1);pos[0]>=0;pos[0]-- )
	{
		for (pos[1]=0;pos[1]<(long)Size[1];pos[1]++ )
		{
			bw=(int)readint(stream,1);
			n++;
			col.setValueToValue(1,bw/16);
			setColorOnPosition((unsigned long*)pos,col);
			pos[1]++;
			if (pos[1]>=(long)Size[1])
				{break;}
			col.setValueToValue(1,bw%16);
			setColorOnPosition((unsigned long*)pos,col);
		}
		n=4-(n-(n/4*4));
		if (n==4) {n=0;}
		readint(stream,n);
		n=0;

	}
	delete Background;
	Background=new Color(1);
	Background->setValueToValue(1,0);
}


fclose(stream);
return true;
}





bool PicturMatrix::saveBitmap(char* file) const
//store this pictur Matrix to the bitmap pictur file with name file
//pre: the name of the bitmap pictur file to store this PicturMatrix to
{
unsigned int bpp=0;

if ((NumberOfColorComponents==3)&&(Depth[0]==256)&&(Depth[1]==256)&&(Depth[2]==256))
	{bpp=24;}//bits per pixel; 24 for no color table
if ((NumberOfColorComponents==1)&&(Depth[0]==2))
	{bpp=1;}//bits per pixel; 24 for no color table

FILE *stream=fopen( file, "w" );
if (stream==NULL){return false;};
char c='B';
writeint(stream,1,c);
c='M';
writeint(stream,1,c);
if (bpp==24)
	{writeint(stream,4, 54+(Size[0]*Size[1])*(bpp/8));}//filesize
if (bpp==1)
	{writeint(stream,4, 62+((((Size[0]-1)/32+1)*32)*Size[1]));}//filesize

writeint(stream,4,0);//reserved
if (bpp==24)
	{writeint(stream,4,54);}//Offset from filebegin till data; 54 when no color table
if (bpp==1)
	{writeint(stream,4,62);}//Offset from filebegin till data; 62 for 2 color entrys color

writeint(stream,4,40);//bitmap header size
writeint(stream,4,Size[1]);//horizontale width of bitmap pixels
writeint(stream,4,Size[0]);//vertical width of bitmap pixels
writeint(stream,2,1);//number of planes in this bitmap should be 1
writeint(stream,2,bpp);//bits per pixel; 24 for no color table
writeint(stream,4,0);//compression specification, should be 0=none
if (bpp==24)
	{writeint(stream,4,((unsigned int)(((Size[0]*Size[1])*(bpp/8)+2)/4)*4));}//size of bitmap data
if (bpp==1)
	{writeint(stream,4,((unsigned int)((((Size[0]-1)/32+1)*32)*Size[1])));}//size of bitmap data

writeint(stream,4,0);//horizontal pixel per meter, uninportant
writeint(stream,4,0);//vertical pixel per meter, uninportant

if (bpp==24)
{
	writeint(stream,4,0);//number of colors
	writeint(stream,4,0);//number of important colors, should be equal number of colors
}
if (bpp==1)
{
	writeint(stream,4,2);//number of colors
	writeint(stream,4,2);//number of important colors, should be equal number of colors
}

long pos[4]={0,0,0,0};
if (bpp==24)
{
	Color *col;
	int tmp;
	for (pos[0]=(long)(Size[0]-1);pos[0]>=0;pos[0]-- )
	{
		for (pos[1]=0;pos[1]<(long)Size[1];pos[1]++ )
		{
			col=getColorFrom((unsigned long*)pos);
			for (unsigned short i=1;i<=3;i++)
			{
				tmp=col->getValue(i);
				if (tmp<0) {tmp=0;}//normalise
				if (tmp>255) {tmp=255;}
				writeint(stream,1,tmp);
			}
		}
	}
}
if (bpp==1)//black and whit pictur
{
	Color *col;
	writeint(stream,4,0);//indize black
	writeint(stream,1,255);writeint(stream,1,255);writeint(stream,1,255);writeint(stream,1,0);//indize whith
	int n=0;
	int rest;
	int bw,tmp;
	for (unsigned int xi=0;xi<Size[0];)
	{
   	for (unsigned int yi=0;yi<Size[1];)
		{
			bw=0;
			rest=((int)Size[1]-((int)yi));
			for (int i=0;i<8;i++)
			{
				bw=bw*2;
				if (yi<Size[1])
				{
					pos[0]=Size[0]-1-xi;
					pos[1]=yi;//upside down
					col=getColorFrom((unsigned long*)pos);
					tmp=col->getValue(1);
					bw+=tmp;
					if (bw>=256){bw-=256;}//should not happen
				}
				//actualisize position
				yi++;
				if ((xi!=Size[0])&&(yi==Size[1])&&(i<8))
				{
					xi++;
				}
			}
			writeint(stream,1,bw);n++;
		}
		//every line ends with the 32 bit word of the file bitmapdata area
		n=4-(n-(n/4*4));
		if (n==4) {n=0;}
		writeint(stream,n,0);
		n=0;
	}
}



fclose(stream);
return true;
}


unsigned int PicturMatrix::readint(FILE *stream,unsigned short byte) const
//reads a value with byte bytes from the stream and returns his integer value
//pre: the ifstream stream to read from and the number of bytes byte to read
//post: the readed value
{
unsigned char tc=0;
unsigned int read=0;
unsigned int exp=1;
for (unsigned short i=0;i<byte;i++)
{
	tc=fgetc(stream);
	read=(unsigned short)tc*exp+read;
	exp=exp*256;
}
return read;
}

void PicturMatrix::writeint(FILE *stream,unsigned short byte,int write) const
//writes the value of write with byte bytes to the stream stream
//pre: the value write to write, how much byte byte write should use and the stream to write to
//post: the value of write with byte bytes in the stream stream
{
for (unsigned short i=0;i<byte;i++)
{
	fputc(((unsigned char)(write%256)),stream);
	write=write/256;
}
}

bool PicturMatrix::load_btx(char* file)
//load a saved btx(own format)
//post: the data of the btx file in this Matrix
{
NumberOfPositionComponents=2;
FILE *stream=fopen( file, "r" );
if (stream==NULL){return false;};
char c='a';
unsigned int tmp=0;
c=readint(stream,1);
while (c!=';')//read greatness x
{
	tmp=tmp*10+charToInt(c);
	c=readint(stream,1);
}
unsigned long *nsize=new unsigned long[4];
nsize[0]=tmp;//horizontale width of bitmap pixels
tmp=0;
c=readint(stream,1);
while ((c!=';')&&(c!='\n'))//read greatness y
{
	tmp=tmp*10+charToInt(c);
	c=readint(stream,1);
}
nsize[1]=tmp;//vertical width of bitmap pixels
nsize[2]=1;
nsize[3]=1;
resize(nsize);//make big enougth matrix
delete Depth;
Depth=new unsigned int[1];
Depth[0]=2;
NumberOfColorComponents=1;
unsigned long *pos=new unsigned long[4];
pos[2]=0;pos[3]=0;
Color col=Color(1);
for (pos[0]=0;pos[0]<nsize[0];pos[0]++)
{
	for (pos[1]=0;pos[1]<nsize[1];pos[1]++)
	{
		c='a';
		while ((c!='0')&&(c!='1')) {c=readint(stream,1);}//read until a 1 or 0 readed

		if (c=='0'){col.setValueToValue(1,0);}
		if (c=='1'){col.setValueToValue(1,1);}
		setColorOnPosition((unsigned long*)pos,col);
	}
}
fclose(stream);
return true;
}

bool PicturMatrix::save_btx(char* file) const
//store this pictur Matrix to the btx pictur file with name file
//pre: the name of the btx pictur file to store this PicturMatrix to
{
ofstream *stream=new ofstream(file);
(*stream)<<Size[0]<<';';//horizontale width of bitmap pixels
(*stream)<<Size[1]<<';'<<endl;//vertical width of bitmap pixels
long pos[4]={0,0,0,0};
Color *col;
for (pos[0]=0;pos[0]<(long)(Size[0]);pos[0]++ )
{
	for (pos[1]=0;pos[1]<(long)Size[1];pos[1]++ )
	{
		col=getColorFrom((unsigned long*)pos);
		(*stream)<<((col->getValue(1))!=0);
	}
	(*stream)<<endl;
}
(*stream)<<flush;
delete stream;
return true;
}



int PicturMatrix::charToInt(char c)
//makes the char c to a integer number
//pre: the char c
//post: the integer number the char c represents(e.g. "1"=1)
{
switch (c)
{
	case '0':return 0;
	case '1':return 1;
	case '2':return 2;
	case '3':return 3;
	case '4':return 4;
	case '5':return 5;
	case '6':return 6;
	case '7':return 7;
	case '8':return 8;
	case '9':return 9;
}
return -1;//error
}

