/***************************************************************
* Unit:    rasters           release 0.31                      *
* Purpose: Test of functionality of raster container library.  *
* Licency: GPL (only)                                          *
* Copyright: (c) 1998-2024 Jaroslav Fojtik                     *
****************************************************************/
#ifdef _MSC_VER
    #include <windows.h> 
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#define CurrentDir

#ifdef __BORLANDC__
#include <alloc.h>
#else
#define heapcheck() 1
#endif

#include "common.h"
#include "raster.h"


/* const char String1[] = "This is a pig";
const char String2[] = "This is an eagle";
const char* const List1[] = {String1,String2}; */



void Benchmark(void);
void Benchmark2(void);
void Benchmark3(void);
void B2(void);

FILE *TempF;
const char vec[] = {1,2,4,8,16,24,32
#if defined(uint64_t) || defined(uint64_t_defined)
		,64
#endif
		,-32,-64
		};
unsigned long val_max[] = {2,4,16,256,65536,0x1000000,0xFFFFFFFF
#if defined(uint64_t) || defined(uint64_t_defined)
		,0xFFFFFFFF
#endif
		,0xFFFFFFFF,0xFFFFFFFF};

char vecRGB[] = {5,8,16};
char vecRGBA[] = {8,16};
const signed char vecFlt[] = {-32,-64};

#define MAX_K (sizeof(vec)-2)


#define DOUBLE_EPSILON      1e-5
inline bool CompareDoubles(const double & value1, const double & value2)
{
  return fabs(value1-value2) < DOUBLE_EPSILON;
}


bool CompareRasters(Raster1DAbstract *RA1, Raster1DAbstract *RA2)
{
  if(RA1==NULL) return(RA2==NULL || RA2->Size1D==0);
  if(RA2==NULL) return(RA1->Size1D==0);

  if(RA1->Size1D != RA2->Size1D) return false;

  if(RA1->Channels()>1 || RA2->Channels()>1)
  {
    RGBQuad q1, q2;
    q1.O = q2.O = 0;
    for(unsigned sz1D=0; sz1D<RA1->Size1D; sz1D++)
    {
      RA1->Get(sz1D,&q1);
      RA2->Get(sz1D,&q2);
      if(memcmp(&q1,&q2,sizeof(q1))) return false;
    }
  }
  
  if(RA1->GetPlanes()>=0 && RA2->GetPlanes()>=0)
  {
    for(unsigned sz1D=0; sz1D<RA1->Size1D; sz1D++)
    {
      if(RA1->GetValue1D(sz1D) != RA2->GetValue1D(sz1D)) return false;
    }
    return true;
  }

  for(unsigned sz1D=0; sz1D<RA1->Size1D; sz1D++)
  {
    const double tmp1 = RA1->GetValue1Dd(sz1D);
    const double tmp2 = RA2->GetValue1Dd(sz1D);
    if(!CompareDoubles(tmp1,tmp2)) return false;
  }
  return true;
}


bool CompareRasters(Raster2DAbstract *RA1, Raster2DAbstract *RA2)
{
  if(RA1==NULL) return(RA2==NULL || RA2->Size1D==0 || RA2->Size2D==0);
  if(RA2==NULL) return(RA1->Size1D==0 || RA1->Size2D==0);

  if(RA1->Size1D != RA2->Size1D) return false;
  if(RA1->Size2D != RA2->Size2D) return false;

  for(unsigned sz2D=0; sz2D<RA1->Size2D; sz2D++)
    for(unsigned sz1D=0; sz1D<RA1->Size1D; sz1D++)
      {
      if(RA1->GetValue2D(sz1D,sz2D) != RA2->GetValue2D(sz1D,sz2D))
	  return false;
      }
  return true;
}


#ifdef RASTER_3D
bool CompareRasters(Raster3DAbstract *RA1, Raster3DAbstract *RA2)
{
  if(RA1==NULL) return(RA2==NULL || RA2->Size1D==0 || RA2->Size2D==0 || RA2->Size3D==0);
  if(RA1==NULL) return(RA1->Size1D==0 || RA1->Size2D==0 || RA1->Size3D==0);

  if(RA1->Size1D != RA2->Size1D) return false;
  if(RA1->Size2D != RA2->Size2D) return false;
  if(RA1->Size3D != RA2->Size3D) return false;

  for(unsigned sz3D=0; sz3D<RA1->Size3D; sz3D++)
    for(unsigned sz2D=0; sz2D<RA1->Size2D; sz2D++)
      for(unsigned sz1D=0; sz1D<RA1->Size1D; sz1D++)
	{
	if(RA1->GetValue3D(sz1D,sz2D,sz3D) != RA2->GetValue3D(sz1D,sz2D,sz3D))
	    return false;
	}
  return true;
}
#endif


void PrintRasters(Raster1DAbstract *RA)
{
  if(RA==NULL || RA->Size1D==0)
  {
    printf("\n[]");
    return;
  }

  printf("\n[");
  if(RA->Channels()>1)
  {
    RGBQuad q;
    for(unsigned sz1D=0; sz1D<RA->Size1D; sz1D++)
    {
      RA->Get(sz1D,&q);
      printf("#%2.2X%2.2X%2.2X", q.R, q.G, q.B);
    }
  }
  else
  {
    if(RA->GetPlanes()<=-32)
    {
      for(unsigned sz1D=0; sz1D<RA->Size1D; sz1D++)
      {
        printf("%f, ", RA->GetValue1Dd(sz1D));
      }
    }
    else
    {
      for(unsigned sz1D=0; sz1D<RA->Size1D; sz1D++)
      {
        printf("%u, ", RA->GetValue1D(sz1D));
      }
    }
  }
  printf("]");
}


void PrintRasters(Raster2DAbstract *RA)
{
  if(RA==NULL || RA->Size1D==0 || RA->Size2D==0)
    {
    printf("\n[]");
    return;
    }

  printf("\n[");
  for(unsigned sz2D=0; sz2D<RA->Size2D; sz2D++)
    {
    for(unsigned sz1D=0; sz1D<RA->Size1D; sz1D++)
      {
      printf("%d, ", RA->GetValue2D(sz1D,sz2D));
      }
    printf(";\n");
    }
  printf("]");
}


int main(int argc, char *argv[])
{
unsigned i;
int j, k, l, err;
bool Pause = false;
int Ops=0;
#ifdef RASTER_3D
int m;
#endif


 //Raster1DAbstract *R1 = CreateRaster1D(4,2);
 //FILE *F=fopen("o:\\temp\\44\\flip2.txt","wb");
 //for(i=0; i<256; i++)
 //{*(unsigned char*)R1->Data1D=i; Flip1D(R1); fprintf(F,"0x%2.2X,",*(unsigned char*)R1->Data1D);}
 //fclose(F);

// for(i=0; i<=1; i++)
//   puts(List1[i]);
// puts(String1);

 puts("");
 puts("<<<rasters>>> (c)1998-2024 Jaroslav Fojtik");
 printf("         This program tests the raster library, release %d.%d\n",
	RASTER_VERSION>>8, RASTER_VERSION&0xFF);

 //B2();

 if(argc>1)
   {
   for(i=1;i<argc;i++)
     {
     if(!strcmp(argv[i],"-bench3"))    Ops=8;
     if(!strcmp(argv[i],"-bench2"))    Ops=4;
     if(!strcmp(argv[i],"-bench"))     Ops|=3;
     if(!strcmp(argv[i],"-demo"))      Ops|=4;
     if(!strcmp(argv[i],"-test"))      Ops|=1;
     if(!strcmp(argv[i],"-benchonly")) Ops|=2;
     if(!strcmp(argv[i],"-pause"))     Pause=true;
     }
   }

 if(Ops==0) Ops=3;

 err = 0;
 if(Ops & 1)
 {
 Raster1DAbstract *RA1 = NULL;
 Raster1DAbstract *RA2 = NULL;
 Raster2DAbstract *RA2d1 = NULL;
#ifdef RASTER_3D
 Raster3DAbstract *RA3d1 = NULL;
#endif

//#if 1

 printf(" get/set pixel 1D [");
 for(j=0; j<sizeof(vec); j++)
 {
   printf("%s%d", j==0?"":",", vec[j]);
   RA1 = CreateRaster1D(1000,vec[j]);
   for(i=0; i<3000; i++)
   {
     RA1->SetValue1D(i%1000,(i+5)%val_max[j]);
     if(RA1->GetValue1D(i%1000) != (i+5)%val_max[j])
     {
       printf("Wrong value read [%d] sz:%d, planes:%d, value expected:%ld, value read:%ld",
		i%RA1->Size1D, RA1->Size1D, vec[j], (i+5)%val_max[j], RA1->GetValue1D(i%1000));
       err = j;
       goto Abnormal_End;
     }
   }

   for(i=2000; i<3000; i++)
   {
     if(RA1->GetValue1D(i%1000) != (i+5)%val_max[j])
     {
       printf("Wrong value read [%d] sz:%d, planes:%d, value expected:%ld, value read:%ld",
		i%RA1->Size1D, RA1->Size1D, vec[j], (i+5)%val_max[j], RA1->GetValue1D(i%1000));
       err = j+10;
       goto Abnormal_End;
     }
   }
   delete RA1; RA1=NULL;
 }
 printf("]\n");


 printf(" get/set pixel 2D [");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?"":",", vec[j]);
   RA2d1 = CreateRaster2D(131,33,vec[j]);
   for(i=0; i<300; i++)
     for(k=0; k<300; k++)
       {
       long val = (i+k+5)%val_max[j];
       RA2d1->SetValue2D(i%131, k%33, val);
       if(RA2d1->GetValue2D(i%131, k%33) != val)
         {
         printf("Wrong value read [%d,%d], planes:%d, value expected:%ld, value read:%ld",
		i%131,k%33, vec[j], val, RA2d1->GetValue2D(i%131,k%33));
         err = j+20;
	 goto Abnormal_End;
         }
     }

     for(i=300-131; i<300; i++)
       for(k=300-33; k<300; k++)
       {
	 long val = (i+k+5)%val_max[j];
	 if(RA2d1->GetValue2D(i%131,k%33) != val)
           {
           printf("Wrong value read [%d,%d], planes:%d, value expected:%ld, value read:%ld",
		i%131, k%33, vec[j], val, RA2d1->GetValue2D(i%131,k%33));
           err = j+30;
	   goto Abnormal_End;
           }
     }
    delete RA2d1; RA2d1=NULL;
  }
 printf("]\n");

#ifdef RASTER_3D
 printf(" get/set pixel 3D [");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?"":",", vec[j]);
   RA3d1 = CreateRaster3D(15,19,17, vec[j]);
   for(i=0; i<44; i++)
     for(k=0; k<44; k++)
       for(l=0; l<44; l++)
         {
         long val = (i+k+l+5)%val_max[j];
	 RA3d1->SetValue3D(i%15, k%19, l%17, val);
	 if(RA3d1->GetValue3D(i%15, k%19, l%17) != val)
	   {
	   printf("Wrong value read [%d,%d,%d], planes:%d, value expected:%ld, value read:%ld",
		i%15,k%19,l%17, vec[j], val, RA3d1->GetValue3D(i%15,k%19,l%17));
	   err = j+20;
           goto Abnormal_End;
           }
     }

     //putchar('.');
     for(i=44-15; i<44; i++)
       for(k=44-19; k<44; k++)
	 for(l=44-17; l<44; l++)
           {
	   long val = (i+k+l+5)%val_max[j];
	   if(RA3d1->GetValue3D(i%15, k%19, l%17) != val)
	     {
	     printf("Wrong value read [%d,%d,%d], planes:%d, value expected:%ld, value read:%ld",
		i%15,k%19,l%17, vec[j], val, RA3d1->GetValue3D(i%15,k%19,l%17));
             err = j+30;
             goto Abnormal_End;
             }
     }
    delete RA3d1; RA3d1=NULL;
    //putchar('+');
 }
 printf("]\n");
#endif


 printf(" get/set pixel 1D float");
 for(j=0; j<sizeof(vecFlt); j++)
   {
   const unsigned ARRAY_SIZE = 1000;

   printf("%s%d", j==0?" [":",", vecFlt[j]);
   RA1 = CreateRaster1D(ARRAY_SIZE,vecFlt[j]);
   if(RA1==NULL)
   {
     printf("Failed to create raster with %d planes", vecFlt[j]);
     err=-100;
     goto Abnormal_End;
   }

	// Check double access
   for(i=0; i<3000; i++)
     {
     RA1->SetValue1Dd(i%ARRAY_SIZE, (i+5)/256.0);
     if(!CompareDoubles(RA1->GetValue1Dd(i%ARRAY_SIZE),(i+5)/256.0))
       {
       printf("Wrong value[%d] read, planes:%d, value expected:%g, value read:%g",
		i%RA1->Size1D, vecFlt[j], (i+5)/256.0, RA1->GetValue1Dd(i%ARRAY_SIZE));
       err = j;
       goto Abnormal_End;
       }
     }

   for(i=2000; i<3000; i++)	// Last 1000 values has been stored, check them
     {
     if(!CompareDoubles(RA1->GetValue1Dd(i%ARRAY_SIZE), (i+5)/256.0))
       {
       printf("Wrong value[%u] read, planes:%d, value expected:%g, value read:%g",
		i%RA1->Size1D, vecFlt[j], (i+5)/256.0, RA1->GetValue1Dd(i%ARRAY_SIZE));
       err = j+10;
       goto Abnormal_End;
       }
     }

	// Check UINT32 access
   for(i=0; i<3000; i++)
     {
     RA1->SetValue1D(i%ARRAY_SIZE, (i+5));
     if(RA1->GetValue1D(i%ARRAY_SIZE) != (i+5))
       {
       printf("\nWrong UINT32 value[%u] read, planes:%d, value expected:%ld, value read:%ld",
		i%ARRAY_SIZE, vecFlt[j], (long)(i+5), RA1->GetValue1D(i%ARRAY_SIZE));
       err = j;
       goto Abnormal_End;
       }
     }

   for(i=2000; i<3000; i++)	// Last 1000 values has been stored, check them
     {
     if(RA1->GetValue1D(i%ARRAY_SIZE) != (i+5))
       {
       printf("\nWrong UINT32 value[%u] read, planes:%d, value expected:%ld, value read:%ld",
		i%RA1->Size1D, vecFlt[j], (long)(i+5), RA1->GetValue1D(i%ARRAY_SIZE));
       err = j+10;
       goto Abnormal_End;
       }
     }

   delete RA1; RA1=NULL;
   }
 printf("]\n");


 printf(" get/set pixel 2D float [");
 for(j=0; j<sizeof(vecFlt); j++)
   {
   printf("%s%d", j==0?"":",", vecFlt[j]);
   RA2d1 = CreateRaster2D(131,33,vecFlt[j]);
   for(i=0; i<300; i++)
     for(k=0; k<300; k++)
       {
       double val = (i+k+5)/128.0;
       RA2d1->SetValue2Dd(i%131, k%33, val);
       if(!CompareDoubles(RA2d1->GetValue2Dd(i%131, k%33), val))
         {
	 printf("Wrong value read [%d,%d], planes:%d, value expected:%g, value read:%g",
		i%131,k%33, vecFlt[j], val, RA2d1->GetValue2Dd(i%131,k%33));
	 err = j + 20;
	 goto Abnormal_End;
         }
     }

     for(i=300-131; i<300; i++)
       for(k=300-33; k<300; k++)
         {
	 double val = (i+k+5)/128.0;
	 if(!CompareDoubles(RA2d1->GetValue2Dd(i%131,k%33), val))
           {
	   printf("Wrong value read [%d,%d], planes:%d, value expected:%g, value read:%g",
		i%131, k%33, vecFlt[j], val, RA2d1->GetValue2Dd(i%131,k%33));
	   err = j + 30;
	   goto Abnormal_End;
           }
         }
    delete RA2d1; RA2d1=NULL;
   }
 printf("]\n");


#ifdef RASTER_3D
 printf(" get/set pixel 3D float [");
 for(j=0; j<sizeof(vecFlt); j++)
   {
   printf("%s%d", j==0?"":",", vecFlt[j]);
   RA3d1 = CreateRaster3D(15,19,17, vecFlt[j]);
   for(i=0; i<44; i++)
     for(k=0; k<44; k++)
       for(l=0; l<44; l++)
         {
	 double val = (i+k+l+5)/(512.0+j);
	 RA3d1->SetValue3Dd(i%15, k%19, l%17, val);
	 if(!CompareDoubles(RA3d1->GetValue3Dd(i%15, k%19, l%17), val))
	   {
	   printf("Wrong value read [%d,%d,%d], planes:%d, value expected:%g, value read:%g",
		i%15,k%19,l%17, vec[j], val, RA3d1->GetValue3Dd(i%15,k%19,l%17));
	   err = j+20;
	   goto Abnormal_End;
	   }
     }

     //putchar('.');
     for(i=44-15; i<44; i++)
       for(k=44-19; k<44; k++)
	 for(l=44-17; l<44; l++)
           {
	   double val = (i+k+l+5) / (512.0+j);
	   if(!CompareDoubles(RA3d1->GetValue3Dd(i%15, k%19, l%17), val))
	     {
	     printf("Wrong value read [%d,%d,%d], planes:%d, value expected:%g, value read:%g",
		i%15,k%19,l%17, vec[j], val, RA3d1->GetValue3D(i%15,k%19,l%17));
             err = j+30;
             goto Abnormal_End;
             }
     }
    delete RA3d1; RA3d1=NULL;
    //putchar('+');
 }
 printf("]\n");
#endif


 printf(" get/set whole container 1D [");
 for(j=0; j<sizeof(vec); j++)
   {
   if(vec[j] <= -32) continue;			// float capable containrs are not fully finished for this.
   const unsigned CONT_SZ = 999;

   printf("%s%d", j==0?"":",", vec[j]);
   RA1 = CreateRaster1D(CONT_SZ, vec[j]);
   RA2 = CreateRaster1D(CONT_SZ, vec[j]);

   for(i=0; i<CONT_SZ; i++)
   {
     const uint32_t ValueStored = (0x10001*i+7)%val_max[j];
     RA1->SetValue1D(i,ValueStored);
   }

   for(k=0; k<MAX_K; k++)
     {
     Raster1DAbstract *RA3 = CreateRaster1D(CONT_SZ,vec[k]);
     if(RA3==NULL)
	{
	 printf("1D raster %d planes fails to create",vec[k]);
	 goto Abnormal_End;
	 }

     //printf("\n%ld, %ld, %ld", RA1->GetValue1D(0), RA2->GetValue1D(0), RA3->GetValue1D(0));
     RA3->Set(*(const Raster1DAbstract*)RA1);
     //printf("\n%ld, %ld, %ld", RA1->GetValue1D(0), RA2->GetValue1D(0), RA3->GetValue1D(0));
     RA3->Get(*RA2);
     //printf("\n%ld, %ld, %ld", RA1->GetValue1D(0), RA2->GetValue1D(0), RA3->GetValue1D(0));

     int shift = ((vec[k]>32)?32:vec[k]) - ((vec[j]>32)?32:vec[j]);		// Bitplane difference
     unsigned long MASK = 0xFFFFFFFF;
     if(shift<0) MASK <<= -shift;

     for(i=0; i<CONT_SZ; i++)
     {
       uint32_t ValueStored = (0x10001*i+7)%val_max[j];      
       uint32_t ValueGet = RA2->GetValue1D(i);       

       if((ValueGet&MASK) != (ValueStored&MASK))
       {
	 err = RA1->GetValue1D(i);
	 err = RA3->GetValue1D(i);
	 printf("\nWrong value read at IDX:%d, planes: %d->%d->%d, values:%lXh;%lXh->(through)%lXh->%lXh", i,
		vec[j], vec[k], vec[j], ValueStored, RA1->GetValue1D(i), RA3->GetValue1D(i), ValueGet);
         printf("\nShift=%d; MASK=%X", shift, MASK);
         PrintRasters(RA1);
         PrintRasters(RA3);
         PrintRasters(RA2);

	 err = j+40;

         //for(unsigned x=0; x<CONT_SZ; x++)
         //  printf("(%d %d %d) ", RA1->GetValue1D(x), RA3->GetValue1D(x), RA2->GetValue1D(x));
	 goto Abnormal_End;
       }
     }

     delete RA3; RA3=NULL;
     }

    delete RA2; RA2=NULL;
    delete RA1; RA1=NULL;
   }
 printf("]\n");


 printf(" boundary settings 1D");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?" [":",", vec[j]);
   for(i=0; i<259; i++)
     {
       RA1 = CreateRaster1D(i,vec[j]);
       if(RA1==NULL)
	 {
	 printf("Raster %d planes fails to create",vec[j]);
	 goto Abnormal_End;
	 }

       for(k=0;k<i;k++)
	 RA1->SetValue1D(k,1);

       if(RA1->GetValue1D(i+1)!=0)
	 {
	 printf("Strange boundary value read, planes:%d, value expected:0, value read:%ld",
		vec[j], RA1->GetValue1D(i+1));
	 err = j+50;
	 goto Abnormal_End;
	 }

       for(k=0;k<i;k++)
	 if(RA1->GetValue1D(k)!=1)
	   {
	   printf("Wrong value read, planes:%d, value expected:1, value read:%ld",
		vec[j], RA1->GetValue1D(k));
	   err = j+60;
	   goto Abnormal_End;
	   }

    delete RA1; RA1=NULL;
    }
  }
  printf("]\n");


  puts(" boundary settings 2D");
  const int BOUNDARY2D_2 = 5;
  for(i=0; i<259; i++)			// iterate Size1D
    for(j=0; j<MAX_K; j++)		// iterate bit planes
      {
	  // test in dimension 1
      RA2d1 = CreateRaster2D(i,BOUNDARY2D_2,vec[j]);
      if(RA2d1==NULL)
	{
	 printf("2D raster %d planes fails to create",vec[j]);
	 goto Abnormal_End;
	 }

       for(l=0; l<BOUNDARY2D_2; l++)    // Iterate in dimension 2.
	 {
	 for(k=0;k<i;k++)		// Iterate in dimension 1.
	   RA2d1->SetValue2D(k,l,1);

	 if(RA2d1->GetValue2D(i+1,l)!=0) // This should overflow dimension 1.
	   {
	   printf("Strange boundary value read [%d,%d], planes:%d, value expected:0, value read:%ld",
		i+1, l, vec[j], RA2d1->GetValue2D(i+1,l));
	   err = j+70;
	   goto Abnormal_End;
	   }

	 for(k=0;k<i;k++)
	   if(RA2d1->GetValue2D(k,l)!=1)
	     {
	     printf("Wrong value read [%d,%d], planes:%d, value expected:1, value read:%ld",
		k,l, vec[j], RA2d1->GetValue2D(k,l));
	     err = j+80;
	     goto Abnormal_End;
	     }
	 }
       delete RA2d1; RA2d1=NULL;

	  // test in dimension 2
       RA2d1 = CreateRaster2D(5,i,vec[j]);
       if(RA2d1==NULL)
	 {
	 printf("2D raster %d planes fails to create",vec[j]);
	 err = j+90;
	 goto Abnormal_End;
	 }

       for(l=0; l<5; l++)
	 {
	 for(k=0;k<i;k++)
	   RA2d1->SetValue2D(l,k,1);

	 if(RA2d1->GetValue2D(l,i+1)!=0)
	   {
	   printf("Strange boundary value read [%d,%d], planes:%d, value expected:0, value read:%ld",
		l, i+1, vec[j], RA2d1->GetValue2D(l,i+1));
	   err = j+100;
	   goto Abnormal_End;
	   }

	 for(k=0;k<i;k++)
	   if(RA2d1->GetValue2D(l,k)!=1)
	     {
	     printf("Wrong value read [%d,%d], planes:%d, value expected:1, value read:%ld",
		l,k, vec[j], RA2d1->GetValue2D(l,k));
	     err = j+110;
	     goto Abnormal_End;
	     }
	 }
       delete RA2d1; RA2d1=NULL;
       }


#ifdef RASTER_3D
   puts(" boundary settings 3D");
   const int BOUNDARY3D_2 = 3;
   const int BOUNDARY3D_3 = 5;
   m = 0;
   for(i=0; i<65; i+=((i<=33)?1:3))		// Iterate dimension 1 size.
     for(j=0; j<MAX_K; j++)	// iterate bit planes
       {
	  // test in dimension 1
       RA3d1 = CreateRaster3D(i,BOUNDARY3D_2,BOUNDARY3D_3,vec[j]);
       if(RA3d1==NULL)
	 {
	 printf("3D raster %d planes fails to create",vec[j]);
	 goto Abnormal_End;
	 }

       for(m=0; m<BOUNDARY3D_3; m++)	// Iterate dimension 3.
	 for(l=0; l<BOUNDARY3D_2; l++)	// Iterate dimension 2.
	   {
	   for(k=0;k<i;k++)		// Iterate dimension 1.
	     RA3d1->SetValue3D(k,l,m,1);

	   if(RA3d1->GetValue3D(i+1,l,m)!=0)
	     {
	     printf("Strange boundary value read [%d,%d,%d], planes:%d, value expected:0, value read:%ld",
		    i+1, l, m, vec[j], RA3d1->GetValue3D(i+1,l,m));
	     err = j+120;
	     goto Abnormal_End;
	     }

	    for(k=0;k<i;k++)
	      if(RA3d1->GetValue3D(k,l,m)!=1)
		{
		printf("Wrong value read [%d,%d,%d], planes:%d, value expected:1, value read:%ld",
		       k,l,m, vec[j], RA3d1->GetValue3D(k,l,m));
		err = j+130;
		goto Abnormal_End;
		}
	  }
       delete RA3d1; RA3d1=NULL;

	// test in dimension 2
       RA3d1 = CreateRaster3D(5,i,3,vec[j]);
       if(RA3d1==NULL)
	 {
	 printf("3D raster %d planes fails to create",vec[j]);
	 err = j+140;
	 goto Abnormal_End;
	 }

       for(l=0; l<5; l++)
	 for(m=0; m<3; m++)
	   {
	   for(k=0;k<i;k++)
	     RA3d1->SetValue3D(l,k,m,1);

	   if(RA3d1->GetValue3D(l,i+1,m)!=0)
	     {
	     printf("Strange boundary value read [%d,%d,%d], planes:%d, value expected:0, value read:%ld",
		  l,i+1,m, vec[j], RA2d1->GetValue2D(l,i+1));
	     err = j+150;
	     goto Abnormal_End;
	     }

	   for(k=0;k<i;k++)
	     if(RA3d1->GetValue3D(l,k,m)!=1)
	       {
	       printf("Wrong value read [%d,%d,%d] %ux%ux%u, planes:%d, value expected:1, value read:%ld",
		    l,k,m, RA3d1->Size1D, RA3d1->Size2D, RA3d1->Size3D,
		    vec[j], RA3d1->GetValue3D(l,k,m));
	       err = j+160;
	       goto Abnormal_End;
	       }
	 }
       delete RA3d1; RA3d1=NULL;

	// test in dimension 3
       RA3d1 = CreateRaster3D(5,3,i,vec[j]);
       if(RA3d1==NULL)
	 {
	 printf("3D raster %d planes fails to create",vec[j]);
	 err = j+140;
	 goto Abnormal_End;
	 }

       for(l=0; l<5; l++)
	 for(m=0; m<3; m++)
	   {
	   for(k=0;k<i;k++)
	     RA3d1->SetValue3D(l,m,k,1);

	   if(RA3d1->GetValue3D(l,m,i+1)!=0)
	     {
	     printf("Strange boundary value read [%d,%d,%d], planes:%d, value expected:0, value read:%ld",
		  l,m,i+1, vec[j], RA2d1->GetValue2D(l,i+1));
	     err = j+150;
	     goto Abnormal_End;
	     }

	   for(k=0;k<i;k++)
	     if(RA3d1->GetValue3D(l,m,k)!=1)
	       {
	       printf("Wrong value read [%d,%d,%d] %ux%ux%u, planes:%d, value expected:1, value read:%ld",
		    l,m,k, RA3d1->Size1D, RA3d1->Size2D, RA3d1->Size3D,
		    vec[j], RA3d1->GetValue3D(l,k,m));
	       err = j+160;
	       goto Abnormal_End;
	       }
	 }
       delete RA3d1; RA3d1=NULL;
       }
#endif  // RASTER_3D


 printf(" RGB get/set pixel");
 for(j=0; j<sizeof(vecRGB); j++)
   {
   printf("%s%d", j==0?" [":",", vecRGB[j]);
   Raster1DAbstractRGB *RA1 = NULL;
   uint32_t RGBval;
   uint32_t Mul = (vecRGB[j]>=16) ? 0x101 : 1;

   RA1 = CreateRaster1DRGB(1000,vecRGB[j]);
   if(RA1==NULL)
     {
     printf("RGB Raster %d planes fails to create",vecRGB[j]);
     goto Abnormal_End;
     }

   for(i=0; i<3000; i++)
     {
     RGBval = (((i+5)%256) | (((i+6)%256)<<8) | (((i+7)%256)<<16)) & 0x00FFFFFF;
     if(vecRGB[j]==5) RGBval &= 0x00F8FCF8;

     RA1->SetValue1D(i%1000, RGBval);
     if(RA1->GetValue1D(i%1000) != RGBval)
       {
       printf("\nWrong value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGB[j], i%1000, RGBval, RA1->GetValue1D(i%1000));
       err = j + 170;
       goto Abnormal_End;
       }

      //if(vecRGB[j]==5) continue;

     RGBval = Mul*((i+5)%256);
     if(vecRGB[j]==5) RGBval &= 0xF8;
     if(RA1->R(i%1000) != RGBval)
       {
       printf("\nWrong R value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGB[j], i%1000, RGBval, RA1->R(i%1000));
       err = j + 171;
       goto Abnormal_End;
       }

     RGBval = Mul*((i+6)%256);
     if(vecRGB[j]==5) RGBval &= 0xFC;
     if(RA1->G(i%1000) != RGBval)
       {
       printf("\nWrong G value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGB[j], i%1000, RGBval, RA1->G(i%1000));
       err = j + 172;
       goto Abnormal_End;
       }

     RGBval = Mul*((i+7)%256);
     if(vecRGB[j]==5) RGBval &= 0xF8;
     if(RA1->B(i%1000) != RGBval)
       {
       printf("\nWrong B value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGB[j], i%1000, RGBval, RA1->B(i%1000));
       err = j + 173;
       goto Abnormal_End;
       }
     }

   delete RA1; RA1=NULL;
   if(heapcheck()<=0)
       {
       printf("Memory corrupted");
       break;
       }
   }
 
 printf("]\n");


	//---------------------------------------------
 printf(" RGBA get/set pixel");
 for(j=0; j<sizeof(vecRGBA); j++)
   {
   printf("%s%d", j==0?" [":",", vecRGBA[j]);
   Raster1DAbstractRGBA *RA1 = NULL;
   uint32_t RGBAval;
   uint32_t Mul = (vecRGBA[j]>=16) ? 0x101 : 1;

   RA1 = CreateRaster1DRGBA(1000,vecRGBA[j]);
   if(RA1==NULL)
     {
     printf("RGBA Raster %d planes fails to create",vecRGBA[j]);
     goto Abnormal_End;
     }

   for(i=0; i<3000; i++)
     {
     RGBAval = (((i+5)%256) | (((i+6)%256)<<8) | (((i+7)%256)<<16) | (((i+9)%256)<<24));
     RA1->SetValue1D(i%1000, RGBAval);
     if(RA1->GetValue1D(i%1000) != RGBAval)
       {
       printf("\nWrong value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGBA[j], i%1000, RGBAval, RA1->GetValue1D(i%1000));
       err = j + 174;
       goto Abnormal_End;
       }
     if(RA1->R(i%1000) != Mul*((i+5)%256))
       {
       printf("\nWrong R value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGBA[j], i%1000, (i+5)%256, RA1->R(i%1000));
       err = j + 175;
       goto Abnormal_End;
       }
     if(RA1->G(i%1000) != Mul*((i+6)%256))
       {
       printf("\nWrong G value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGBA[j], i%1000, (i+6)%256, RA1->G(i%1000));
       err = j + 176;
       goto Abnormal_End;
       }
     if(RA1->B(i%1000) != Mul*((i+7)%256))
       {
       printf("\nWrong B value read, planes:%d, x=%d, value expected:%lXh, value read:%lXh",
		vecRGBA[j], i%1000, (i+6)%256, RA1->B(i%1000));
       err = j + 177;
       goto Abnormal_End;
       }
     }

   delete RA1; RA1=NULL;
   if(heapcheck()<=0)
       {
       printf("Memory corrupted");
       break;
       }
   }
 printf("]\n");


	//---------------------------------------------
 printf(" peel/join 1bit [");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?"":",", vec[j]); fflush(stdout);

   for(i=0; i<1393; i+=((i<21) ? 1 : 7))
     {
     Raster1DAbstract *RA1 = CreateRaster1D(i,1);
     Raster1DAbstract *RA2 = CreateRaster1D(i,vec[j]);
     Raster1DAbstract *RA3 = CreateRaster1D(i,vec[j]);

     memset(RA3->Data1D, 0xAB, (RA3->Size1D*labs(vec[j])+7)/8);
     for(k=0; k<i; k++)
	 {
	 uint32_t value = rand() % val_max[j];
	 RA2->SetValue1D(i-1-k, value);
	 }

     //printf(">>%d<<",i); fflush(stdout);

     for(k=0; k<labs(vec[j]); k++)
     {
       RA2->Peel1Bit(RA1->Data1D,k);

       if(vec[j] >= 0)
       {
         for(unsigned x=0; x<i; x++)
         {
           unsigned Bit1 = RA1->GetValue1D(x);
           unsigned Bit2 = 1 & (RA2->GetValue1D(x) >> k);

           if(Bit1 != Bit2)
           {
             printf("\nPeel1Bit failed, planes:%d, plane:%d, %u!=%u",  vec[j], k, Bit1, Bit2);
             err = j + 180;
             delete RA1;
             delete RA2;
             delete RA3;
             goto Abnormal_End;
           }
         }
       }

       RA3->Join1Bit(RA1->Data1D,k);

       memset(RA1->Data1D,0xFE,(RA1->Size1D+7)/8);
       RA3->Peel1Bit(RA1->Data1D,k);

       if(vec[j] >= 0)		// this check is not applicable for floating point values.
       {
         for(unsigned x=0; x<i; x++)
         {
           unsigned Bit1 = RA1->GetValue1D(x);
           unsigned Bit2 = 1 & (RA2->GetValue1D(x) >> k);
           unsigned Bit3 = 1 & (RA3->GetValue1D(x) >> k);

           if(Bit1 != Bit2)
           {
             printf("\nPeel1Bit after join failed, planes:%d, plane:%d, %u!=%u %u",  vec[j], k, Bit1, Bit2, Bit3);
             err = j + 181;
             delete RA1;
             delete RA2;
             delete RA3;
             goto Abnormal_End;
           }
         }
       }
     }
     
		// Check for full RA2 reconstruction.
     if(vec[j] >= 0)
     {
       for(unsigned x=0; x<i; x++)
       {
         unsigned Px2 = RA2->GetValue1D(x);
         unsigned Px3 = RA3->GetValue1D(x);
         if(Px2 != Px3)
         {
           printf("\njoin 1bit failed, planes:%d, plane:%d, %u!=%u",  vec[j], k, Px2, Px3);
           PrintRasters(RA2);
           PrintRasters(RA3);
           err = j + 182;
           delete RA1;
           delete RA2;
           delete RA3;
           goto Abnormal_End;
         }
       }
     }
     else
     {
       for(unsigned x=0; x<i; x++)
       {
         double Px2 = RA2->GetValue1Dd(x);
         double Px3 = RA3->GetValue1Dd(x);
         if(!CompareDoubles(Px2,Px2)) 
         {
           printf("\njoin 1bit did not reconstruct data, planes:%d, plane:%d, %f!=%f",  vec[j], k, Px2, Px3);
           err = j + 183;
           delete RA1;
           delete RA2;
           delete RA3;
           goto Abnormal_End;
         }
       }
     }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     delete RA3; RA3=NULL;
     }
  }
 printf("]\n");


	//---------------------------------------------
 printf(" peel/join 8bit [");
 for(j=0; j<sizeof(vec); j++)
 {
   if(labs(vec[j]) < 8) continue;
   printf("%s%d", labs(vec[j])<=8?"":",", vec[j]); fflush(stdout);

   for(i=0; i<1393; i+=((i<21) ? 1 : 7))
     {
     Raster1DAbstract *RA1 = CreateRaster1D(i,8);
     Raster1DAbstract *RA2 = CreateRaster1D(i,vec[j]);
     Raster1DAbstract *RA3 = CreateRaster1D(i,vec[j]);

     memset(RA3->Data1D, 0xAB, (RA3->Size1D*labs(vec[j])+7)/8);
     for(k=0; k<i; k++)
	 {
	 uint32_t value = rand() % val_max[j];
	 RA2->SetValue1D(i-1-k, value);
	 }
     //PrintRasters(RA2);

     //printf(">>%d<<",i); fflush(stdout);


     for(k=0; k<vec[j]; k+=8)
     {
       RA2->Peel8Bit(RA1->Data1D,k);
       //PrintRasters(RA1);

       if(vec[j] >= 0)		// This check is not applicable for floating point values.
       {
         for(unsigned x=0; x<i; x++)
         {
           unsigned Byte1 = RA1->GetValue1D(x);
           unsigned Byte2 = 0xFF & (RA2->GetValue1D(x) >> k);

           if(Byte1 != Byte2)
           {
             printf("\nPee18Bit failed, planes:%d, plane:%d, %u!=%u %X,%X",  vec[j], k, Byte1, Byte2, RA1->GetValue1D(x),RA2->GetValue1D(x));
             err = j + 180;
             delete RA1;
             delete RA2;
             delete RA3;
             goto Abnormal_End;
           }
         }
       }       
      
       RA3->Join8Bit(RA1->Data1D,k);
       memset(RA1->Data1D,0xFE,RA1->Size1D);
       RA3->Peel8Bit(RA1->Data1D,k);

       if(vec[j] >= 0)		// This check is not applicable for floating point values.
       {
         for(unsigned x=0; x<i; x++)
         {
           unsigned Byte1 = RA1->GetValue1D(x);
           unsigned Byte2 = 0xFF & (RA2->GetValue1D(x) >> k);
           unsigned Byte3 = 0xFF & (RA3->GetValue1D(x) >> k);

           if(Byte1 != Byte2)
           {
             printf("\nPeel8Bit after join failed, planes:%d, plane:%d, %u!=%u %u",  vec[j], k, Byte1, Byte2, Byte3);
             err = j + 180;
             delete RA1;
             delete RA2;
             delete RA3;
             goto Abnormal_End;
           }
         }
       }
     }
     
		// Check for full RA2 reconstruction.
     if(vec[j] >= 0)
     {
       for(unsigned x=0; x<i; x++)
       {
         unsigned Px2 = RA2->GetValue1D(x);
         unsigned Px3 = RA3->GetValue1D(x);
         if(Px2 != Px3)
         {
           printf("\nFinal join 8bit failed, planes:%d, plane:%d, %u!=%u",  vec[j], k, Px2, Px3);
           PrintRasters(RA2);
           PrintRasters(RA3);
           delete RA1;
           delete RA2;
           delete RA3;
           err = j + 181;
           goto Abnormal_End;
         }
       }
     }
     else
     {
       for(unsigned x=0; x<i; x++)
       {
         double Px2 = RA2->GetValue1Dd(x);
         double Px3 = RA3->GetValue1Dd(x);
         if(!CompareDoubles(Px2,Px2)) 
         {
           printf("\njoin 1bit did not reconstruct data, planes:%d, plane:%d, %f!=%f",  vec[j], k, Px2, Px3);
           err = j + 183;
           delete RA1;
           delete RA2;
           delete RA3;
           goto Abnormal_End;
         }
       }
     }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     delete RA3; RA3=NULL;
     }
  }
 printf("]\n");


	//---------------------------------------------
 printf(" flip 1D-in1D [");
 for(j=0; j<sizeof(vec); j++)
 {
   printf("%s%d", j==0?"":",", vec[j]); fflush(stdout);

   for(i=0; i<5393; i+=((i<21) ? 1 : 7))
   {
     Raster1DAbstract *RA1 = CreateRaster1D(i,vec[j]);
     Raster1DAbstract *RA2 = CreateRaster1D(i,vec[j]);
     if(RA1==NULL || RA2==NULL)
     {
       printf("\nFlip1D raster with depth:%d creation failure, Size1D=%u", vec[j], i);
       err = j + 180;
       goto Abnormal_End;
     }

     for(k=0; k<i; k++)
     {
	uint32_t value = rand() % val_max[j];

	RA1->SetValue1D(k,     value);
	RA2->SetValue1D(i-1-k, value);
     }

     //printf(">>%d<<",i); fflush(stdout);
     Flip1D(RA1);

     if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip1D in 1D failed, planes:%d, Size1D=%u",  vec[j], i);
       PrintRasters(RA1);
       printf("\nExpected:");
       PrintRasters(RA2);
       err = j + 180;
       delete RA1; RA1=NULL;
       delete RA2; RA2=NULL;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     }
  }

  printf(",RGB");
  for(j=0; j<sizeof(vecRGBA); j++)
  {
    printf("%s%d", j==0?"":",", vecRGBA[j]); fflush(stdout);
    RGBQuad q1;

    for(i=0; i<4493; i+=((i<21) ? 1 : 7))
    {
      Raster1DAbstractRGB *RA1 = CreateRaster1DRGB(i,vecRGBA[j]);
      Raster1DAbstractRGB *RA2 = CreateRaster1DRGB(i,vecRGBA[j]);
      if(RA1==NULL || RA2==NULL)
      {
        printf("\nFlip1D RGB raster with depth:%d creation failure, Size1D=%u", vec[j], i);
        err = j + 180;
        goto Abnormal_End;
      }

      for(k=0; k<i; k++)
      {
	uint32_t value = rand() % val_max[j];
        q1.R = rand() % 255;
        q1.G = rand() % 255;
        q1.B = rand() % 255;
        q1.O = (i+k) % 255;

	RA1->Set(k,     &q1);
	RA2->Set(i-1-k, &q1);
      }

      Flip1D(RA1);

      if(!CompareRasters(RA1,RA2))
      {
        printf("\nFlip1D in 1D RGB failed, planes:%d, Size1D=%u",  vec[j], i);
        PrintRasters(RA1);
        printf("\nExpected:");
        PrintRasters(RA2);
        err = j + 180;
        delete RA1; RA1=NULL;
        delete RA2; RA2=NULL;
        goto Abnormal_End;
      }

      delete RA1; RA1=NULL;
      delete RA2; RA2=NULL;
    }
  }

  printf(",RGBA");
  for(j=0; j<sizeof(vecRGBA); j++)
  {
    printf("%s%d", j==0?"":",", vecRGBA[j]); fflush(stdout);
    RGBQuad q1;

    for(i=0; i<4493; i+=((i<21) ? 1 : 7))
    {
      Raster1DAbstractRGBA *RA1 = CreateRaster1DRGBA(i,vecRGBA[j]);
      Raster1DAbstractRGBA *RA2 = CreateRaster1DRGBA(i,vecRGBA[j]);
      if(RA1==NULL || RA2==NULL)
      {
        printf("\nFlip1D RGB raster with depth:%d creation failure, Size1D=%u", vec[j], i);
        err = j + 180;
        goto Abnormal_End;
      }

      for(k=0; k<i; k++)
      {
	uint32_t value = rand() % val_max[j];
        q1.R = rand() % 255;
        q1.G = rand() % 255;
        q1.B = rand() % 255;
        q1.O = rand() % 255;

	RA1->Set(k,     &q1);
	RA2->Set(i-1-k, &q1);
      }

      Flip1D(RA1);

      if(!CompareRasters(RA1,RA2))
      {
        printf("\nFlip1D in 1D RGB failed, planes:%d, Size1D=%u",  vec[j], i);
        PrintRasters(RA1);
        printf("\nExpected:");
        PrintRasters(RA2);
        err = j + 180;
        delete RA1; RA1=NULL;
        delete RA2; RA2=NULL;
        goto Abnormal_End;
      }

      delete RA1; RA1=NULL;
      delete RA2; RA2=NULL;
    }
  }

 printf("]\n");


	//---------------------------------------------
 printf(" flip 2D-in1D [");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?"":",", vec[j]);

   for(i=0; i<1027; i++)
     {
     Raster2DAbstract *RA1 = CreateRaster2D(i,4,vec[j]);
     Raster2DAbstract *RA2 = CreateRaster2D(i,4,vec[j]);

     for(l=0; l<4; l++)
       for(k=0; k<i; k++)
	 {
	 uint32_t value = rand() % val_max[j];

	 RA1->SetValue2D(k,    l, value);
	 RA2->SetValue2D(i-1-k,l, value);
	 }
     Flip1D(RA1);

     if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip1D failed, planes:%d, Size1D=%u",  vec[j], i);
       PrintRasters(RA1);
       PrintRasters(RA2);
       err = j + 190;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     }
  }
 printf("]\n");


#ifdef RASTER_3D
 printf(" flip 3D-in1D [");
 for(j=0; j<sizeof(vec); j++)
   {
   printf("%s%d", j==0?"":",", vec[j]);

   for(i=0; i<837; i++)
     {
     const int TEST_SZ_2D = 3;
     const int TEST_SZ_3D = 4;

     Raster3DAbstract *RA1 = CreateRaster3D(i,TEST_SZ_2D, TEST_SZ_3D, vec[j]);
     Raster3DAbstract *RA2 = CreateRaster3D(i,TEST_SZ_2D, TEST_SZ_3D, vec[j]);

     for(m=0; m<TEST_SZ_3D; m++)
       for(l=0; l<TEST_SZ_2D; l++)
	 for(k=0; k<i; k++)
	   {
	   uint32_t value = rand() % val_max[j];

	   RA1->SetValue3D(k,    l, m, value);
	   RA2->SetValue3D(i-1-k,l, m, value);
	 }
     Flip1D(RA1);

     if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip1D failed on R3D, planes:%d, Size1D=%u",  vec[j], i);
       //PrintRasters(RA1);
       //PrintRasters(RA2);
       err = j + 200;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     }
  }
 printf("]\n");
#endif


 printf(" flip in2D - Ras2D");
 for(i=0; i<1027; i++)
   {
   j = rand() % MAX_K;	// Planes should not be signifficant, select random.
   unsigned Size1D = rand() % 5 + 1;

   Raster2DAbstract *RA1 = CreateRaster2D(Size1D, i, vec[j]);
   Raster2DAbstract *RA2 = CreateRaster2D(Size1D, i, vec[j]);

   for(k=0; k<i; k++)		// 2D
     for(l=0; l<Size1D; l++)
	{
	uint32_t value = rand() % val_max[j];

	RA1->SetValue2D(l, k,     value);
	RA2->SetValue2D(l, i-1-k, value);
	}
   Flip2D(RA1);

   if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip2D in Ras2D failed, planes:%d, Size1D=%u, Size2D=%u", vec[j], Size1D, i);
       PrintRasters(RA1);
       PrintRasters(RA2);
       err = j + 210;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
   }

#ifdef RASTER_3D
 printf(" -Ras3D");

 for(i=0; i<1027; i++)
   {
   j = rand() % MAX_K;	// Planes should not be signifficant, select random.
   unsigned Size1D = rand() % 4 + 1;
   unsigned Size3D = rand() % 4 + 1;

   Raster3DAbstract *RA1 = CreateRaster3D(Size1D, i, Size3D, vec[j]);
   Raster3DAbstract *RA2 = CreateRaster3D(Size1D, i, Size3D, vec[j]);

   for(m=0; m<Size3D; m++)	// 3D
     for(k=0; k<i; k++)		// 2D
       for(l=0; l<Size1D; l++)	// 1D
	 {
	 uint32_t value = rand() % val_max[j];

	 RA1->SetValue3D(l, k,     m, value);
	 RA2->SetValue3D(l, i-1-k, m, value);
	 }
   Flip2D(RA1);

   if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip3D in Ras3D failed, planes:%d, Size1D=%u, Size2D=%u, Size3D=%u",
	 vec[j], Size1D, i, Size3D);
       //PrintRasters(RA1);
       //PrintRasters(RA2);
       err = j + 210;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
 }
 printf("\n");


 printf(" flip in3D - Ras3D");
 for(i=0; i<300; i++)
   {
   j = rand() % MAX_K;	// Planes should not be signifficant, select random.
   unsigned Size1D = rand() % 4 + 1;
   unsigned Size2D = rand() % 4 + 1;

   Raster3DAbstract *RA1 = CreateRaster3D(Size1D, Size2D, i, vec[j]);
   Raster3DAbstract *RA2 = CreateRaster3D(Size1D, Size2D, i, vec[j]);

   for(m=0; m<i; m++)		// 3D
     for(k=0; k<Size2D; k++)	// 2D
       for(l=0; l<Size1D; l++)	// 1D
	 {
	 uint32_t value = rand() % val_max[j];

	 RA1->SetValue3D(l, k,     m, value);
	 RA2->SetValue3D(l, k, i-1-m, value);
	 }
   Flip3D(RA1);

   if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip3D in Ras3D failed, planes:%d, Size1D=%u, Size2D=%u, Size3D=%u",
	 vec[j], Size1D, Size2D, i);
       //PrintRasters(RA1);
       //PrintRasters(RA2);
       err = j + 210;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
 }

#endif
 printf("\n");


	//---------------------------------------------
 printf(" flip 1D-float");
 for(j=0; j<sizeof(vecFlt); j++)
   {
   printf("%s%d", j==0?" [":",", vecFlt[j]);

   for(i=0; i<3759; i+=((i<21) ? 1 : 7))
     {
     Raster1DAbstract *RA1 = CreateRaster1D(i,vecFlt[j]);
     Raster1DAbstract *RA2 = CreateRaster1D(i,vecFlt[j]);

     for(k=0; k<i; k++)
	 {
	 double value = rand() / 10.0;

	 RA1->SetValue1Dd(k,     value);
	 RA2->SetValue1Dd(i-1-k, value);
	 }

     Flip1D(RA1);

     if(!CompareRasters(RA1,RA2))
       {
       printf("\nFlip1D float in 1D failed, planes:%d, Size1D=%u",  vecFlt[j], i);
       PrintRasters(RA1);
       //Flip1D(RA1);PrintRasters(RA1);
       printf("\nExpected:");
       PrintRasters(RA2);
       err = j + 180;
       goto Abnormal_End;
       }

     delete RA1; RA1=NULL;
     delete RA2; RA2=NULL;
     }
  }
 printf("]\n");

//#endif
	//---------------------------------------------
 printf(" flip 1D/2D [");
 for(j=0; j<sizeof(vec); j++)
 {
   printf("%s%d", j==0?"":",", vec[j]);

   for(i=0; i<65; i+=((i<21) ? 1 : 7))
     for(k=0; k<65; k+=((i<21) ? 1 : 7))
     {
       Raster2DAbstract *RA1 = CreateRaster2D(i,k,vec[j]);
       Raster2DAbstract *RA2;
       unsigned x, y;

       for(x=0; x<i; x++)
         for(y=0; y<k; y++)
         {
	   uint32_t value = rand() % val_max[j];
	   RA1->SetValue2D(x,y, value);
         }

       //printf(">>%d<<",i); fflush(stdout);
       RA2 = Flip1D2D(RA1);
       if(RA2==NULL)
       {
         if(RA1->Size1D==0 || RA1->Size2D==0)
         {
           delete RA1; RA1=NULL;
           continue;
         }
         printf("\nRaster roration failed");
         err = j + 190;
         delete RA1; RA1=NULL;
         goto Abnormal_End;
       }
       if(RA2->Size1D!=RA1->Size2D || RA2->Size2D!=RA1->Size1D)
       {
         printf("\nRaster rotation failed [%u;%u]->[%u;%u]", RA1->Size1D, RA1->Size2D, RA2->Size1D, RA2->Size2D);
         err = j + 190;
         delete RA1; RA1=NULL;
         goto Abnormal_End;
       }

       for(x=0; x<i; x++)
         for(y=0; y<k; y++)
         {
	   uint32_t value1 = RA1->GetValue2D(x,y);
           uint32_t value2 = RA2->GetValue2D(y,x);

           if(value1 != value2)
           {
             printf("\nRaster rotation failed Sz:%u;%u [%u;%u]=%u; expected %u", i,k, x,y, value2,value1);
             PrintRasters(RA1);
             PrintRasters(RA2);
             err = j + 190;
             delete RA1; RA1=NULL;
             delete RA2; RA2=NULL;
             goto Abnormal_End;
           }
         }

       delete RA1; RA1=NULL;
       delete RA2; RA2=NULL;
     }
  }
 printf("]\n");
}



 /////////////////////////////////////
 if(heapcheck()>0 && err==0)
 {
  if(Ops==8) Benchmark3();
  if(Ops==4) Benchmark2();
  if(Ops & 2) Benchmark();
 }

 if(heapcheck()<=0)
	 {
	 printf("Bad allocation %d",heapcheck());
	 return(-1);
	 }

Abnormal_End:
 if(err!=0)
   {
   printf("\nUnit Rasters Error %d\n",err);
   if(Pause) getchar();
   return(-1);
   }
 
 puts(" .............. Test passed OK ..............");
 if(Pause) getchar();
return(0);
}


/////////////////////////////////////////////////////////
//////////////////      BENCHMARKS    ///////////////////
/////////////////////////////////////////////////////////

#include "../test/bench.h"


Raster1DAbstract *RA1 = NULL;
Raster1DAbstract *RA2 = NULL;

void SetGetPixel1(long i)
{
int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,1);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,1);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}

void SetGetPixel2(long i)
{
int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,2);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,3);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}


void SetGetPixel4(long i)
{
int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,4);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,15);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}


void SetGetPixel8(long i)
{
int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,8);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,255);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}


void SetGetPixel16(long i)
{
int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,16);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,65535);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}


void SetGetPixel24(long i)
{
long int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,24);

  while(i-->0)
    {
    j = i%1000;
    k = RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,65535);
    k = RA1->GetValue1D(j);
    }
delete RA1;
}


void SetGetPixel32(long i)
{
long int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,32);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,0xFFFFFFFFl);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}


#if defined(uint64_t) || defined(uint64_t_defined)
void SetGetPixel64(long i)
{
long int j,k;
Raster1DAbstract *RA1 = CreateRaster1D(1000,64);

  while(i-->0)
    {
    j=i%1000;
    k=RA1->GetValue1D(j);
    RA1->SetValue1D(j,0);
    RA1->SetValue1D(j,0xFFFFFFFFl);
    k=RA1->GetValue1D(j);
    }
delete RA1;
}
#endif

/*************** 2D ****************/

void SetGetPixel2D1(long i)
{
int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,1);

  while(i-->0)
    {
    j = i%44;
    l = i%33;
    k = RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,1);
    k = RA1->GetValue2D(j,l);
    }
delete RA1;
}

void SetGetPixel2D2(long i)
{
int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,2);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,3);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


void SetGetPixel2D4(long i)
{
int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,4);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,15);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


void SetGetPixel2D8(long i)
{
int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,8);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,255);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


void SetGetPixel2D16(long i)
{
int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,16);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,65535);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


void SetGetPixel2D24(long i)
{
long int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,24);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,65535);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


void SetGetPixel2D32(long i)
{
long int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,32);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,0xFFFFFFFFl);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}


#if defined(uint64_t) || defined(uint64_t_defined)
void SetGetPixel2D64(long i)
{
long int j,k,l;
Raster2DAbstract *RA1 = CreateRaster2D(44,33,64);

  while(i-->0)
    {
    j=i%44;
    l=i%33;
    k=RA1->GetValue2D(j,l);
    RA1->SetValue2D(j,l,0);
    RA1->SetValue2D(j,l,0xFFFFFFFFl);
    k=RA1->GetValue2D(j,l);
    }
delete RA1;
}
#endif



/*************** 3D ****************/
#ifdef RASTER_3D

void SetGetPixel3D1(long i)
{
int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,1);

  while(i-->0)
    {
    j = i%35;
    l = i%33;
    m = i%8;
    k = RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,1);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}

void SetGetPixel3D2(long i)
{
int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,2);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k = RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,3);
    k = RA1->GetValue3D(j,l,m);
    }
delete RA1;
}


void SetGetPixel3D4(long i)
{
int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,4);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,15);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}


void SetGetPixel3D8(long i)
{
int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,8);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,255);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}


void SetGetPixel3D16(long i)
{
int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,16);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,65535);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}


void SetGetPixel3D24(long i)
{
long int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,24);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,65535);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}


void SetGetPixel3D32(long i)
{
long int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,32);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,0xFFFFFFFFl);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}

#if defined(uint64_t) || defined(uint64_t_defined)
void SetGetPixel3D64(long i)
{
long int j,k,l,m;
Raster3DAbstract *RA1 = CreateRaster3D(35,33,8,64);

  while(i-->0)
    {
    j=i%35;
    l=i%33;
    m = i%8;
    k=RA1->GetValue3D(j,l,m);
    RA1->SetValue3D(j,l,m,0);
    RA1->SetValue3D(j,l,m,0xFFFFFFFFl);
    k=RA1->GetValue3D(j,l,m);
    }
delete RA1;
}
#endif

#endif


void ConvertRasterGet(long i)
{
  while(i-->0)
    {
    RA1->Get(*RA2);
    }
}


void ConvertRasterSet(long i)
{
  while(i-->0)
    {
    RA1->Set(*RA2);
    }
}


typedef void(TSetGetPixel)(long i);

TSetGetPixel *SetGetPixel[] = {
   SetGetPixel1,  SetGetPixel2, SetGetPixel4, SetGetPixel8,
   SetGetPixel16, SetGetPixel24, SetGetPixel32
#if defined(uint64_t) || defined(uint64_t_defined)
   ,SetGetPixel64
#endif
   };


TSetGetPixel *SetGetPixel2D[] = {
   SetGetPixel2D1,  SetGetPixel2D2, SetGetPixel2D4, SetGetPixel2D8,
   SetGetPixel2D16, SetGetPixel2D24, SetGetPixel2D32
#if defined(uint64_t) || defined(uint64_t_defined)
   ,SetGetPixel2D64
#endif
   };


#ifdef RASTER_3D
TSetGetPixel *SetGetPixel3D[] = {
   SetGetPixel3D1,  SetGetPixel3D2, SetGetPixel3D4, SetGetPixel3D8,
   SetGetPixel3D16, SetGetPixel3D24, SetGetPixel3D32
#if defined(uint64_t) || defined(uint64_t_defined)
   ,SetGetPixel3D64
#endif
   };
#endif


Raster1DAbstract *gRas1D_1 = NULL;
Raster1DAbstract *gRas1D_2 = NULL;

void BenchFlip1D_1D(long i)
{
  while(i-->0)
  {
    Flip1D(gRas1D_1);
    Flip1D(gRas1D_2);
  }
}


Raster2DAbstract *gRas2D_1 = NULL;

void BenchFlip2D_1D(long i)
{
  while(i-->0)
    {
    Flip1D(gRas2D_1);
    }
}


#ifdef RASTER_3D
Raster3DAbstract *gRas3D_1 = NULL;

void BenchFlip3D_1D(long i)
{
  while(i-->0)
  {
    Flip1D(gRas3D_1);
  }
}
#endif


static unsigned gPeelPlane = 0;
void BenchPeel1Bit(long i)
{
  while(i-->0)
  {
    gRas1D_2->Peel1Bit(gRas1D_1->Data1D,gPeelPlane);
    gRas1D_2->Peel1Bit(gRas1D_1->Data1D,gPeelPlane);
  }
}

void BenchJoin1Bit(long i)
{
  while(i-->0)
  {
    gRas1D_2->Join1Bit(gRas1D_1->Data1D,gPeelPlane);
    gRas1D_2->Join1Bit(gRas1D_1->Data1D,gPeelPlane);
  }
}


void BenchPeel8Bit(long i)
{
  while(i-->0)
  {
    gRas1D_2->Peel8Bit(gRas1D_1->Data1D,gPeelPlane);
    gRas1D_2->Peel8Bit(gRas1D_1->Data1D,gPeelPlane);
  }
}

void BenchJoin8Bit(long i)
{
  while(i-->0)
  {
    gRas1D_2->Join8Bit(gRas1D_1->Data1D,gPeelPlane);
    gRas1D_2->Join8Bit(gRas1D_1->Data1D,gPeelPlane);
  }
}




const char vecPlane[] = {0,1,2,7,8,9,12,15,16,23,24,31};

void Benchmark3(void)
{
float f;
int i,j,k;

 puts(" .............. Benchmarks #3..............");

 printf("Peel 8 bit direction [ns/px]:\n   ");
 for(i=0; i<64; i+=8)
   {
   printf(" %7d ",i);	// print label
   }

 for(j=0; j<sizeof(vec); j++)
 {
   printf("\n%2d  ", vec[j]);
   const unsigned PEEL1_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(PEEL1_SZ_X, 8);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(PEEL1_SZ_X, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   for(k=0; k<64; k+=8)
   {
     gPeelPlane = k;
     f = 1000*AutoMeasure(BenchPeel8Bit) / (2*PEEL1_SZ_X);
     printf("%8.5g ",f);
   }

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
 }


 printf("\nJoin 8 bit direction [ns/px]:\n   ");
  for(i=0; i<64; i+=8)
   {
   printf(" %7d ",i);	// print label
   }
  
 for(j=0; j<sizeof(vec); j++)
 {
   printf("\n%2d  ", vec[j]);
   const unsigned PEEL1_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(PEEL1_SZ_X, 8);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(PEEL1_SZ_X, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   for(k=0; k<64; k+=8)
   {
     gPeelPlane = k;
     f = 1000*AutoMeasure(BenchJoin8Bit) / (2*PEEL1_SZ_X);
     printf("%8.5g ",f);
   }

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
 }


 printf("\nPeel 1 bit direction [ns/px]:\n   ");
 for(i=0; i<sizeof(vecPlane); i++)
   {
   printf(" %7d ",vecPlane[i]);	// print label
   }

 for(j=0; j<sizeof(vec); j++)
 {
   printf("\n%2d  ", vec[j]);
   const unsigned PEEL1_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(PEEL1_SZ_X, 1);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(PEEL1_SZ_X, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   for(k=0; k<sizeof(vecPlane); k++)
   {
     gPeelPlane = vecPlane[k];
     f = 1000*AutoMeasure(BenchPeel1Bit) / (2*PEEL1_SZ_X);
     printf("%8.5g ",f);
   }

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
 }


 printf("\nJoin 1 bit direction [ns/px]:\n   ");
 for(i=0; i<sizeof(vecPlane); i++)
   {
   printf(" %7d ",vecPlane[i]);	// print label
   }
  
 for(j=0; j<sizeof(vec); j++)
 {
   printf("\n%2d  ", vec[j]);
   const unsigned PEEL1_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(PEEL1_SZ_X, 1);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(PEEL1_SZ_X, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   for(k=0; k<sizeof(vecPlane); k++)
   {
     gPeelPlane = vecPlane[k];
     f = 1000*AutoMeasure(BenchJoin1Bit) / (2*PEEL1_SZ_X);
     printf("%8.5g ",f);
   }

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
 }

 printf("\n\n");

}



void Benchmark2(void)
{
float f;
int i,j;

 puts(" .............. Benchmarks #2..............");

 printf("Flip in 1D direction [ns/px]:\n   ");
 for(i=0; i<MAX_K; i++)
   {
   printf(" %7d ",vec[i]);	// print label
   }

 printf("\n1D   ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(FLIP_SZ_X, vec[j]);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(FLIP_SZ_X+4, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   f = 1000*AutoMeasure(BenchFlip1D_1D) / (FLIP_SZ_X+FLIP_SZ_X+4);
   printf("%8.5g ",f);

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
   }

 printf("\n1D+1 ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(FLIP_SZ_X+1, vec[j]);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(FLIP_SZ_X+5, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   f = 1000*AutoMeasure(BenchFlip1D_1D) / (FLIP_SZ_X+1+FLIP_SZ_X+5);
   printf("%8.5g ",f);

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
   }

 printf("\n1D+2 ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(FLIP_SZ_X+2, vec[j]);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(FLIP_SZ_X+6, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   f = 1000*AutoMeasure(BenchFlip1D_1D) / (FLIP_SZ_X+2+FLIP_SZ_X+6);
   printf("%8.5g ",f);

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
   }

 printf("\n1D+3 ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(FLIP_SZ_X+3, vec[j]);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(FLIP_SZ_X+7, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   f = 1000*AutoMeasure(BenchFlip1D_1D) /  (FLIP_SZ_X+3+FLIP_SZ_X+7);
   printf("%8.5g ",f);

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
   }

 printf("\n2D   ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 4321;
   const unsigned FLIP_SZ_Y = 7;

   gRas2D_1 = CreateRaster2D(FLIP_SZ_X, FLIP_SZ_Y, vec[j]);
   if(gRas2D_1==NULL) continue;

   for(unsigned y=0; y<gRas2D_1->Size2D; y++)
     for(unsigned x=0; x<gRas2D_1->Size1D; x++)
       gRas2D_1->SetValue2D(x, y, rand() % val_max[j]);

   f = 1000*AutoMeasure(BenchFlip2D_1D) / (FLIP_SZ_X*FLIP_SZ_Y);
   printf("%8.5g ",f);

   delete gRas2D_1; gRas2D_1=NULL;
   }

 printf("\n2D+1 ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 4321;
   const unsigned FLIP_SZ_Y = 7;

   gRas2D_1 = CreateRaster2D(FLIP_SZ_X+1, FLIP_SZ_Y, vec[j]);
   if(gRas2D_1==NULL) continue;

   for(unsigned y=0; y<gRas2D_1->Size2D; y++)
     for(unsigned x=0; x<gRas2D_1->Size1D; x++)
       gRas2D_1->SetValue2D(x, y, rand() % val_max[j]);

   f = 1000*AutoMeasure(BenchFlip2D_1D) / ((FLIP_SZ_X+1)*FLIP_SZ_Y);
   printf("%8.5g ",f);

   delete gRas2D_1; gRas2D_1=NULL;
   }

#ifdef RASTER_3D
 printf("\n3D   ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 4321;
   const unsigned FLIP_SZ_Y = 4;

   gRas3D_1 = CreateRaster3D(FLIP_SZ_X, FLIP_SZ_Y, 3, vec[j]);
   if(gRas3D_1==NULL) continue;

   for(unsigned z=0; z<gRas3D_1->Size3D; z++)
     for(unsigned y=0; y<gRas3D_1->Size2D; y++)
       for(unsigned x=0; x<gRas3D_1->Size1D; x++)
	 gRas3D_1->SetValue3D(x, y, z, rand() % val_max[j]);

   f = 1000*AutoMeasure(BenchFlip3D_1D) / (FLIP_SZ_X*FLIP_SZ_Y*3);
   printf("%8.5g ",f);

   delete gRas3D_1; gRas3D_1=NULL;
   }
#endif
 printf("\n\n");



}


void Benchmark(void)
{
float f;
int i,j;

 puts(" .............. Benchmarks ..............");


/* RA1 = CreateRaster1D(1000,64);
 RA2 = CreateRaster1D(1000,32);

 RA1->Get(*RA2);
 f = AutoMeasure(ConvertRasterGet);  //RA1->Get(*RA2);
 printf("%8.5g ",f); */


 printf("Flip in 1D direction [us]:\n ");
 for(i=0; i<MAX_K; i++)
   {
   printf(" %7d ",vec[i]);	// print label
   }

 printf("\n1D ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 14321;

   gRas1D_1 = CreateRaster1D(FLIP_SZ_X, vec[j]);	// Test both even and odd size.
   gRas1D_2 = CreateRaster1D(FLIP_SZ_X+1, vec[j]);
   if(gRas1D_1==NULL) continue;
   if(gRas1D_2==NULL) continue;

   for(unsigned x=0; x<gRas1D_1->Size1D; x++)
   {
     gRas1D_1->SetValue1D(x, rand() % val_max[j]);
     gRas1D_2->SetValue1D(x, rand() % val_max[j]);
   }
   gRas1D_2->SetValue1D(gRas1D_2->Size1D-1, rand()%val_max[j]);

   f = AutoMeasure(BenchFlip1D_1D) / 2.0;
   printf("%8.5g ",f);

   delete gRas1D_1; gRas1D_1=NULL;
   delete gRas1D_2; gRas1D_2=NULL;
   }

 printf("\n2D ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 4321;
   const unsigned FLIP_SZ_Y = 7;

   gRas2D_1 = CreateRaster2D(FLIP_SZ_X, FLIP_SZ_Y, vec[j]);
   if(gRas2D_1==NULL) continue;

   for(unsigned y=0; y<gRas2D_1->Size2D; y++)
     for(unsigned x=0; x<gRas2D_1->Size1D; x++)
       gRas2D_1->SetValue2D(x, y, rand() % val_max[j]);

   f = AutoMeasure(BenchFlip2D_1D);
   printf("%8.5g ",f);

   delete gRas2D_1; gRas2D_1=NULL;
   }

#ifdef RASTER_3D
 printf("\n3D ");
 for(j=0; j<MAX_K; j++)
   {
   const unsigned FLIP_SZ_X = 4321;
   const unsigned FLIP_SZ_Y = 4;

   gRas3D_1 = CreateRaster3D(FLIP_SZ_X, FLIP_SZ_Y, 3, vec[j]);
   if(gRas3D_1==NULL) continue;

   for(unsigned z=0; z<gRas3D_1->Size3D; z++)
     for(unsigned y=0; y<gRas3D_1->Size2D; y++)
       for(unsigned x=0; x<gRas3D_1->Size1D; x++)
	 gRas3D_1->SetValue3D(x, y, z, rand() % val_max[j]);

   f = AutoMeasure(BenchFlip3D_1D);
   printf("%8.5g ",f);

   delete gRas3D_1; gRas3D_1=NULL;
   }
#endif
 printf("\n");


 printf("\n RGB ");
 for(i=0; i<sizeof(vecRGB)/sizeof(char); i++)
 {
   printf(" %7d ",vecRGB[i]);	// print label
 }
 printf("RGBA");
 for(i=0; i<sizeof(vecRGBA)/sizeof(char); i++)
 {
   printf("%7d ",vecRGBA[i]);	// print label
 }
 printf("\nSet typed raster vector from another raster vector into RGB container [us]:");
 for(i=0; i<sizeof(vecRGB)/sizeof(char); i++)
 {
   printf("\n[RGB%d] ",vecRGB[i]);
   RA1 = CreateRaster1DRGB(800,vecRGB[i]);
   for(j=0;j<sizeof(vecRGB)/sizeof(char);j++)
   {     
     RA2 = CreateRaster1DRGB(800,vecRGB[j]);
     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);     
     delete RA2;
   }
   for(j=0;j<sizeof(vecRGBA)/sizeof(char);j++)
   {     
     RA2 = CreateRaster1DRGBA(800,vecRGBA[j]);
     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);     
     delete RA2;
   }
   delete RA1;
 }
 for(i=0; i<sizeof(vecRGBA)/sizeof(char); i++)
 {
   printf("\n[RGBA%d] ",vecRGBA[i]);
   RA1 = CreateRaster1DRGBA(800,vecRGBA[i]);
   for(j=0;j<sizeof(vecRGB)/sizeof(char);j++)
   {     
     RA2 = CreateRaster1DRGB(800,vecRGB[j]);
     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);     
     delete RA2;
   }
   for(j=0;j<sizeof(vecRGBA)/sizeof(char);j++)
   {     
     RA2 = CreateRaster1DRGBA(800,vecRGBA[j]);
     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);     
     delete RA2;
   }
   delete RA1;
 }

/*
 printf("\n RGBA ");
 for(i=0; i<sizeof(vecRGBA)/sizeof(char); i++)
 {
   printf(" %7d ",vecRGBA[i]);	// print label
 }
 printf("\nSet typed raster vector from another raster vector into ARGB container [us]:");
 for(i=0; i<sizeof(vecRGBA)/sizeof(char); i++)
 {
   printf("\n[RGBA%d] ",vecRGBA[i]);
   RA1 = CreateRaster1DRGBA(1000,vecRGBA[i]);
   for(j=0;j<sizeof(vecRGBA)/sizeof(char);j++)
   {     
     RA2 = CreateRaster1DRGBA(1000,vecRGBA[j]);
     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);     
     delete RA2;
   }
   delete RA1;
 }
*/

 printf("\n");
 for(i=0; i<MAX_K; i++)
 {
   printf(" %7d ",vec[i]);	// print label
 }
 printf("\nGet vector from another raster vector [us]:");
 for(i=0; i<MAX_K; i++)
   {
   printf("\n[%d] ",vec[i]);
   RA1 = CreateRaster1D(1000,vec[i]);
   for(j=0;j<MAX_K;j++)
   {     
     RA2 = CreateRaster1D(1000,vec[j]);

     f = AutoMeasure(ConvertRasterGet);  //RA1->Get(*RA2);
     printf("%8.5g ",f);     
     delete RA2;
   }
   delete RA1;
 }
 printf("\n");

 printf("\nSet typed raster vector from another raster vector [us]:");
 for(i=0;i<MAX_K;i++)
   {
   printf("\n[%d] ",vec[i]);
   for(j=0;j<MAX_K;j++)
     {
     RA1 = CreateRaster1D(1000,vec[i]);
     RA2 = CreateRaster1D(1000,vec[j]);

     f = AutoMeasure(ConvertRasterSet);
     printf("%8.5g ",f);

     delete RA1;
     delete RA2;
     }
   }
 printf("\n");


 printf("Get/Set pixel [ns]:\n ");
 for(i=0;i<MAX_K;i++)
   {
   printf(" %7d ",vec[i]);	// print label
   }

 printf("\n1D ");
 for(i=0;i<MAX_K;i++)
   {
   f = AutoMeasure(SetGetPixel[i]);
   printf("%8.5g ",1000*f/4);
   }

 printf("\n2D ");
 for(i=0;i<MAX_K;i++)
   {
   f = AutoMeasure(SetGetPixel2D[i]);
   printf("%8.5g ",1000*f/4);
   }

#ifdef RASTER_3D
 printf("\n3D ");
 for(i=0;i<MAX_K;i++)
   {
   f = AutoMeasure(SetGetPixel3D[i]);
   printf("%8.5g ",1000*f/4);
   }
#endif
 printf("\n");
}



void B2(void)
{
 volatile int i, j;
 float f;
 printf("\nGet vector from another raster vector:");
 for(i=0;i<MAX_K;i++)
   {
   printf("\n[%d] ",vec[i]);
   for(j=0;j<MAX_K;j++)
     {
     RA1 = CreateRaster1D(1000,vec[i]);
     RA2 = CreateRaster1D(1000,vec[j]);

     ConvertRasterGet(1);   //RA1->Get(*RA2);
     f = vec[j];
     printf("%8.5g ",f);

     delete RA1;
     delete RA2;
     }
   }
 printf("\n");
}
