/***************************************************************
* Unit:    raster image      release 0.38                      *
* Purpose: Test of functionality of raster container library.  *
* Licency: GPL (only)                                          *
* Copyright: (c) 1998-2025 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"
#include "../img_tool.h"


#ifndef MIN
 #define MIN(__a,__b) ((__a)<(__b) ? (__a) : (__b))
#endif
#ifndef ABS
 #define ABS(__a) (((__a)>=0) ? (__a) : -(__a))
#endif



void Benchmark(void);
void B2(void);

FILE *TempF;
const signed char vec[] = {1,2,4,8,16,24,32
#ifdef QWORD
		,64
#endif
		,-32,-64
		};
unsigned long val_max[] = {2,4,16,256,65536,0x1000000,0xFFFFFFFF
#ifdef QWORD
		,0xFFFFFFFF
#endif
		,0xFFFFFFFF,0xFFFFFFFF};

signed char vecRGB[] = {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->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;
}


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

  printf("\n[");
  for(unsigned sz1D=0; sz1D<RA->Size1D; sz1D++)
    {
    printf("%d, ", 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("]");
}


void FeedBuffer(unsigned char *Buffer, int Op)
{
int i;
  switch(Op)
  {
    case 0:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 0;
        Buffer[4*i+1] = 128;		// U
        Buffer[4*i+2] = 0;
        Buffer[4*i+3] = i;		// V
      }
      break;
   case 1:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 0;
        Buffer[4*i+1] = i;		// U
        Buffer[4*i+2] = 0;
        Buffer[4*i+3] = 128;		// V
      }
      break;
    case 2:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 255;
        Buffer[4*i+1] = 128;		// U
        Buffer[4*i+2] = 255;
        Buffer[4*i+3] = i;		// V
      }
      break;
    case 3:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 255;
        Buffer[4*i+1] = i;		// U
        Buffer[4*i+2] = 255;
        Buffer[4*i+3] = 128;		// V
      }
      break;
    case 4:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 255;
        Buffer[4*i+1] = i;		// U
        Buffer[4*i+2] = 255;
        Buffer[4*i+3] = i;		// V
      }
      break;
    case 5:
      for(i=0; i<256; i++)
      {
        Buffer[4*i] = 0;
        Buffer[4*i+1] = i;		// U
        Buffer[4*i+2] = 0;
        Buffer[4*i+3] = i;		// V
      }
      break;
  }
}


int main(int argc, char *argv[])
{
int i, j, Err;
bool Pause = false;
int Ops;

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

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

 //B2();
 if(argc>1)
 {
   Ops=0;
   for(i=1;i<argc;i++)
   {
     if(argv[i][0]!=0 && argv[i][1]!=0 && (argv[i][0]=='-' || argv[i][0]=='/'))
     {
       if(!strcmp(argv[i]+1,"bench"))     Ops|=3;       
       if(!strcmp(argv[i]+1,"demo"))      Ops|=4;
       if(!strcmp(argv[i]+1,"test"))      Ops|=1;
       if(!strcmp(argv[i]+1,"benchonly")) Ops|=2;       
       if(!strcmp(argv[i]+1,"pause"))     Pause=true;
       if(!strcmp(argv[i]+1,"help"))
       {
         printf("Command line parameters:\n-bench -benchonly -demo -pause -help -test\n");
         return 1;
       }
     }
   }
   if(Ops==0) Ops=3;
 }
 else
   Ops=3;


 Err = 0;
 if(Ops & 1)
 {
#define TestSize 1030
   unsigned char *Buffer = (unsigned char*)malloc(TestSize+2*16);
   unsigned char *Buffer2 = (unsigned char*)malloc(TestSize+2*16);   


		/// ************** UNARY *************
/*
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   memcpy(Buffer2,Buffer,TestSize+32);

   printf(" Abs 32\n");
   for(j=0; j<TestSize/4; j++)
   {
     Abs_u32((uint32_t*)(Buffer+16), (uint32_t*)(Buffer2+16), j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Abs I32 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=16; i<4*j+16; i+=4)
     {
       int32_t val = (int32_t)LD_UINT32_CPU(Buffer+i);
       int32_t val2 = (int32_t)LD_UINT32_CPU(Buffer2+i);
       if(ABS(val2) != val)
       {
         printf("Abs I32 failed on pos %d %u!=%u, block size %d", i, val, val2, j);
         Err = -1;
         goto Abnormal_End;
       }
       Buffer[i] = i & 0xFF;
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Abs I32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
   }
*/

   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }

   printf(" Not R\n");
   for(j=0; j<TestSize; j++)
   {
     NotR((char*)Buffer+16,j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Invert corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=16; i<j+16; i++)
     {
       if(Buffer[i] != (~i&0xFF))
       {
         printf("Invert failed on pos %d %u!=%u, block size %d", i, Buffer[i], (~i&0xFF), j);
         Err = -1;
         goto Abnormal_End;
       }
       Buffer[i] = i & 0xFF;
     }
     for(i=j+16; i<j+32; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Invert corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
   }


   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }

   printf(" Swab 16");
   for(i=0; i<TestSize/2; i++)
   {
     swab16((unsigned char*)Buffer+16,i);

     for(j=0; j<16; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("Swab16 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(j=0; j<i; j++)
     {
       unsigned char x1 = (2*j+16) & 0xFF;
       unsigned char x2 = (2*j+17) & 0xFF;
       if(Buffer[2*j+16] != x2)
       {
         printf("Swab16 failed on pos %d %u!=%u, block size %d", j, Buffer[2*j+16], x2, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[2*j+17] != x1)
       {
         printf("Swab16 failed on pos %d %u!=%u, block size %d", j, Buffer[2*j+17], x1, i);
         Err = -1;
         goto Abnormal_End;
       }
     }
     for(j=2*i+16; j<2*i+32; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("Swab16 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }

     swab16((unsigned char*)Buffer+16,i);
   }
   printf(" 32");
   for(i=0; i<TestSize/4; i++)
   {
     swab32((unsigned char*)Buffer+16,i);

     for(j=0; j<16; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("Swab32 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(j=0; j<i; j++)
     {
       unsigned char x1 = (4*j+16) & 0xFF;
       unsigned char x2 = (4*j+17) & 0xFF;
       unsigned char x3 = (4*j+18) & 0xFF;
       unsigned char x4 = (4*j+19) & 0xFF;
       if(Buffer[4*j+16] != x4)
       {
         printf("Swab32 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+16], x2, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[4*j+17] != x3)
       {
         printf("Swab32 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+17], x1, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[4*j+18] != x2)
       {
         printf("Swab32 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+18], x1, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[4*j+19] != x1)
       {
         printf("Swab32 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+19], x1, i);
         Err = -1;
         goto Abnormal_End;
       }
     }
     for(j=4*i+16; j<4*i+32; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("Swab32 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }

     swab32((unsigned char*)Buffer+16,i);
   }
   printf(" 64");
   for(i=0; i<TestSize/8; i++)
   {
     swab64((unsigned char*)Buffer+16,i);

     for(j=0; j<16; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("\nSwab64 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(j=0; j<i; j++)
     {
       unsigned char x1 = (8*j+16) & 0xFF;
       unsigned char x2 = (8*j+17) & 0xFF;
       unsigned char x3 = (8*j+18) & 0xFF;
       unsigned char x4 = (8*j+19) & 0xFF;
       unsigned char x5 = (8*j+20) & 0xFF;
       unsigned char x6 = (8*j+21) & 0xFF;
       unsigned char x7 = (8*j+22) & 0xFF;
       unsigned char x8 = (8*j+23) & 0xFF;
       if(Buffer[8*j+16] != x8)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+16], x8, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+17] != x7)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+17], x7, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+18] != x6)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+18], x6, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+19] != x5)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+19], x5, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+20] != x4)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+20], x4, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+21] != x3)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+21], x3, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+22] != x2)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+22], x2, i);
         Err = -1;
         goto Abnormal_End;
       }
       if(Buffer[8*j+23] != x1)
       {
         printf("\nSwab64 failed on pos %d %u!=%u, block size %d", j, Buffer[4*j+23], x1, i);
         Err = -1;
         goto Abnormal_End;
       }
     }
     for(j=8*i+16; j<8*i+32; j++)
     {
       if(Buffer[j] != (j&0xFF))
       {
         printf("\nSwab64 corrupted memory behind block pos %d %u!=%u, block size %d", j, Buffer[j], (j&0xFF), i);
	 Err = -2;
         goto Abnormal_End;
       }
     }

     swab64((unsigned char*)Buffer+16,i);
   }
   printf("\n");


   printf(" Shl R\n");
   for(j=0; j<TestSize/3; j++)
   {
     bool Flag = (((j-1)^j) & 0x1) != 0;
     for(i=j-1; i>=0; i--)
     {
       Buffer[i] = (i^j) & 0xFF;
       Buffer2[i] = Buffer[i]<<1;
       if(Flag) Buffer2[i]|=0x01;
       Flag = (Buffer[i] & 0x80) != 0;
     }
     for(i=j; i<j+32; i++)
     {
       Buffer[i] = (i^j) & 0xFF;
     }

     ShlR(Buffer, j, 1);

     for(i=0; i<j; i++)
     {
       if(Buffer[i] != Buffer2[i])
       {
         printf("ShlR failed on pos %d %X!=%Xh, block size %d", i, Buffer[i], Buffer2[i], j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+32; i++)
     {
       const unsigned char Expected = (i^j) & 0xFF;
       if(Buffer[i] != Expected)
       {
         printf("ShlR corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], Expected, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }


   printf(" Shr R\n");
   for(j=0; j<TestSize/3; j++)
   {
     bool Flag = ((0^j) & 0x80) != 0;
     for(i=0; i<j+32; i++)
     {
       Buffer[i] = (i^j) & 0xFF;
       Buffer2[i] = Buffer[i]>>1;
       if(Flag) Buffer2[i]|=0x80;
       Flag = (Buffer[i] & 1) != 0;
     }
     ShrR(Buffer, j);

     for(i=0; i<j; i++)
     {
       if(Buffer[i] != Buffer2[i])
       {
         printf("ShrR failed on pos %d %X!=%Xh, block size %d", i, Buffer[i], Buffer2[i], j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+32; i++)
     {
       const unsigned char Expected = (i^j) & 0xFF;
       if(Buffer[i] != Expected)
       {
         printf("ShrR corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], Expected, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }


   printf(" Diff Hor1_u32\n");
   for(j=0; j<TestSize/4; j++)
   {
     for(i=0; i<4*j+32; i++)
     {
       Buffer2[i] = Buffer[i] = (i^j) & 0xFF;       
     }

     DiffHor1_u32((uint32_t*)(Buffer+16), (const uint32_t*)(Buffer+16), j);

     const int Max_j = 16 - 4 + 4*j;
     for(i=16; i<=Max_j; i+=4)
     {
       const uint32_t val1 = *(uint32_t*)(Buffer2 + ((i<=16)?16:(i-4)));
       const uint32_t val2 = *(uint32_t*)(Buffer2 + ((i>=Max_j)?Max_j:(i+4)));
       const uint32_t val3 = *(uint32_t*)(Buffer+i);       
       const uint32_t val4 = (val2>>1)+0x80000000 -  (val1>>1);
       if(val3 != val4)
       {
         printf("DiffHor1_u32 failed on pos %d %X!=%Xh, block size %d", i, val3, val4, j);
         Err = -21;
         goto Abnormal_End;
       }
     }

     for(i=0; i<16; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("DiffHor1_u32 failed on pos %d %X!=%Xh, block size %d", i, Buffer[i], val, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("DiffHor1_u32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], val, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }


   printf(" Gaus1D_u32\n");   
   for(j=0; j<TestSize/4; j++)
   {
     for(i=0; i<4*j+32; i++)
     {
       Buffer2[i] = (i^j) & 0xFF;       
     }

     memcpy(Buffer,Buffer2,4*j+32);
     Gaus1D_u32((uint32_t*)(Buffer+16), j, 1);

     const int Max_j = 16 - 4 + 4*j;
     for(i=16; i<=Max_j; i+=4)
     {
       const uint32_t val1 = *(uint32_t*)(Buffer2 + ((i<=16)?16:(i-4)));
       const uint32_t val2 = *(uint32_t*)(Buffer2+i); 
       const uint32_t val3 = *(uint32_t*)(Buffer2 + ((i>=Max_j)?Max_j:(i+4)));
       const uint32_t val4 = *(uint32_t*)(Buffer+i);       
       const uint32_t val5 = (val1>>2) + (val2>>1) + (val3>>2);
       if(val4 != val5)
       {
	 if(j==1)		// size 1
         {
           if(val2 != val4)
           {
             printf("Gaus1D_u32 1G failed on block with sz 1:  %Xh!=%Xh\n", val4, val2);
             Err = -21;
             goto Abnormal_End;
           }
         }
         else if((val4&0xFFFFFFFE) != (val5&0xFFFFFFFE))	// Last bit could get lost during rounding.
         {
           printf("Gaus1D_u32 1G failed on pos %d %X!=%Xh, block size %d\n", i-15, val4, val5, j);
           printf("Val1:%X; Val2:%X; Val3:%X; Val4:%X; Val5:%X\n", val1, val2, val3, val4, val5);
           Err = -21;
           goto Abnormal_End;
         }
       }
     }

     for(i=0; i<16; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("Gaus1D_u32 corrupted memory before block on pos %d %X!=%Xh, block size %d", i, Buffer[i], val, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("Gaus1D_u32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], val, j);
         Err = -22;
         goto Abnormal_End;
       }
     }

     Gaus1D_u32((uint32_t*)(Buffer2+16), j, 2);

     for(i=16; i<=Max_j; i+=4)
     {
       const uint32_t val1 = *(uint32_t*)(Buffer + ((i<=16)?16:(i-4)));
       const uint32_t val2 = *(uint32_t*)(Buffer+i); 
       const uint32_t val3 = *(uint32_t*)(Buffer + ((i>=Max_j)?Max_j:(i+4)));
       const uint32_t val4 = *(uint32_t*)(Buffer2+i);       
       const uint32_t val5 = (val1>>2) + (val2>>1) + (val3>>2);
       if(val4 != val5)
       {
         if(j==1)		// size 1
         {
           if(val2 != val4)
           {
             printf("Gaus1D_u32 2G failed on block with sz 1:  %Xh!=%Xh\n", val4, val2);
             Err = -21;
             goto Abnormal_End;
           }
         }
         else if((val4&0xFFFFFFFE) != (val5&0xFFFFFFFE))	// Last bit could get lost during rounding.
         {
           printf("Gaus1D_u32 2G failed on pos %d %X!=%Xh, block size %d", i, val4, val5, j);
           Err = -21;
           goto Abnormal_End;
         }
       }
     }

     for(i=0; i<16; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer2[i] != val)
       {
         printf("Gaus1D_u32 failed on pos %d %X!=%Xh, block size %d", i, Buffer[i], val, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer2[i] != val)
       {
         printf("Gaus1D_u32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], val, j);
         Err = -22;
         goto Abnormal_End;
       }
     }

   }

	/// ************** BINARY *************

   for(i=0; i<TestSize+32; i++)
   {
     Buffer2[i] = i & 0xFF; 
   }
   memcpy(Buffer, Buffer2, TestSize+32);

   printf(" AbsDiff 32\n");
   for(j=0; j<TestSize/4; j++)
   {
     for(i=0; i<j; i++)
     {
       ST_UINT32_CPU(Buffer+4*i+16, 17*i);
       if(i%3 == 1)
           ST_UINT32_CPU(Buffer2+4*i+16, 13*i);
       else
           ST_UINT32_CPU(Buffer2+4*i+16, 19*i);
     }

     AbsDiffCopy_u32((uint32_t*)(Buffer+16), (uint32_t*)(Buffer+16), (uint32_t*)(Buffer2+16), j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("AbsDiffCopy U32 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=0; i<j; i++)
     {
       int32_t diff = (int32_t)LD_UINT32_CPU(Buffer+4*i+16);
       int32_t val1 = 17*i;
       int32_t val2 = (int32_t)LD_UINT32_CPU(Buffer2+4*i+16);
       if(diff != ABS(val2-val1))
       {	
         printf("AbsDiffCopy U32 failed on pos %d %d!=%d, block size %d", i, diff, ABS(val2-val1), j);
         Err = -1;
         goto Abnormal_End;
       }
       Buffer[i] = i & 0xFF;
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("AbsDiffCopy U32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }

	// -------------------------------------
     for(i=0; i<j; i++)
     {
       ST_UINT32_CPU(Buffer+4*i+16, 17*i);
       if(i%3 == 1)
           ST_UINT32_CPU(Buffer2+4*i+16, 13*i);
       else
           ST_UINT32_CPU(Buffer2+4*i+16, 19*i);
     }

     AbsDiff_u32((uint32_t*)(Buffer+16), (uint32_t*)(Buffer2+16), j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("AbsDiff I32 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=0; i<j; i++)
     {
       int32_t diff = (int32_t)LD_UINT32_CPU(Buffer+4*i+16);
       int32_t val1 = 17*i;
       int32_t val2 = (int32_t)LD_UINT32_CPU(Buffer2+4*i+16);
       if(diff != ABS(val2-val1))
       {
         printf("AbsDiff I32 failed on pos %d %d!=%d (%d - %d), block size %d",
              i, diff, ABS(val2-val1), val1, val2, j);
         Err = -1;
         goto Abnormal_End;
       }
       Buffer[i] = i & 0xFF;
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("AbsDiff I32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
   }


   //if(Buffer3==NULL) Buffer3 =  (unsigned char*)malloc(TestSize+2*16);
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   printf(" Min U8");
   for(j=0; j<TestSize; j++)
   {
     for(i=0; i<j+16; i++)
     {
       Buffer[i+16] = (5*i ^ j) & 0xFF;
       Buffer2[i+16] = (3*i ^ j) & 0xFF;
     }
     
     MinU8(Buffer+16,Buffer2+16,j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Min U8 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+16; i++)
     {
       if(Buffer[i+16] != ((5*i ^ j) & 0xFF))
       {
         printf("Min U8 corrupted memory after block on pos %d %u!=%u, block size %d", i, Buffer[i], (~i&0xFF), j);
         Err = -1;
         goto Abnormal_End;
       }       
     }

     for(i=0; i<j; i++)
     {
       const unsigned char Val1 = (5*i ^ j) & 0xFF;
       const unsigned char Expected = (Buffer2[i+16]<Val1) ? Buffer2[i+16] : Val1;
       if(Buffer[i+16] != Expected)
       {
         printf("\nMinU8 failed on pos %d %u!=%u, block size %d", i, Buffer2[i+16], Expected, j);
         Err = -11;
         goto Abnormal_End;
       }
     }
   }

   printf(", U16");
   for(j=0; j<TestSize/2; j++)
   {
     for(i=0; i<j+8; i++)
     {
       ST_UINT16_CPU((Buffer+16+2*i), (11*i ^ j) & 0xFFFF);
       ST_UINT16_CPU((Buffer2+16+2*i), (13*i ^ j) & 0xFFFF);
     }
     
     MinU16(Buffer+16,Buffer2+16,j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Min U16 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+8; i++)
     {
       uint16_t Val1 = (11*i ^ j) & 0xFFFF;
       if(LD_UINT16_CPU((Buffer+2*i+16)) != Val1)
       {
         printf("Min U16 corrupted memory after block on pos %d %u!=%u, block size %d", i, LD_UINT16_CPU((Buffer+2*i+16)), Val1, j);
         Err = -1;
         goto Abnormal_End;
       }       
     }

     for(i=0; i<j; i++)
     {
       uint16_t Val1 = (11*i ^ j) & 0xFFFF;
       uint16_t Val2 = (13*i ^ j) & 0xFFFF;
       const uint16_t Expected = (Val2<Val1) ? Val2 : Val1;
       if(LD_UINT16_CPU((Buffer+2*i+16)) != Expected)
       {
         printf("\nMinU16 failed on pos %d %u!=%u, block size %d", i, LD_UINT16_CPU(Buffer+2*i+16), Expected, j);
         Err = -11;
         goto Abnormal_End;
       }
     }
   }
   printf("\n");

    //----------------------------------------------

   printf(" Max U8");
   for(j=0; j<TestSize; j++)
   {
     for(i=0; i<j+16; i++)
     {
       Buffer[i+16] = (5*i ^ j) & 0xFF;
       Buffer2[i+16] = (3*i ^ j) & 0xFF;
     }
     
     MaxU8(Buffer+16,Buffer2+16,j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Max U8 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+16; i++)
     {
       if(Buffer[i+16] != ((5*i ^ j) & 0xFF))
       {
         printf("Max U8 corrupted memory after block on pos %d %u!=%u, block size %d", i, Buffer[i], (~i&0xFF), j);
         Err = -1;
         goto Abnormal_End;
       }       
     }

     for(i=0; i<j; i++)
     {
       const unsigned char Val1 = (5*i ^ j) & 0xFF;
       const unsigned char Expected = (Buffer2[i+16]>Val1) ? Buffer2[i+16] : Val1;
       if(Buffer[i+16] != Expected)
       {
         printf("\nMaxU8 failed on pos %d %u!=%u, block size %d", i, Buffer2[i+16], Expected, j);
         Err = -11;
         goto Abnormal_End;
       }
     }
   }

   printf(", U16");
   for(j=0; j<TestSize/2; j++)
   {
     for(i=0; i<j+8; i++)
     {
       ST_UINT16_CPU((Buffer+16+2*i), (11*i ^ j) & 0xFFFF);
       ST_UINT16_CPU((Buffer2+16+2*i), (13*i ^ j) & 0xFFFF);
     }
     
     MaxU16(Buffer+16,Buffer2+16,j);

     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("Max U16 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -2;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+8; i++)
     {
       uint16_t Val1 = (11*i ^ j) & 0xFFFF;
       if(LD_UINT16_CPU((Buffer+2*i+16)) != Val1)
       {
         printf("Max U16 corrupted memory after block on pos %d %u!=%u, block size %d", i, LD_UINT16_CPU((Buffer+2*i+16)), Val1, j);
         Err = -1;
         goto Abnormal_End;
       }       
     }

     for(i=0; i<j; i++)
     {
       uint16_t Val1 = (11*i ^ j) & 0xFFFF;
       uint16_t Val2 = (13*i ^ j) & 0xFFFF;
       const uint16_t Expected = (Val2>Val1) ? Val2 : Val1;
       if(LD_UINT16_CPU((Buffer+2*i+16)) != Expected)
       {
         printf("\nMaxU16 failed on pos %d %u!=%u, block size %d", i, LD_UINT16_CPU(Buffer+2*i+16), Expected, j);
         Err = -11;
         goto Abnormal_End;
       }
     }
   }
   printf("\n");

    //----------------------------------------------

   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }

   printf(" And R\n");
   for(j=0; j<TestSize; j++)
   {
     for(i=0; i<j+32; i++)
     {
       Buffer2[i] = (3*i ^ j) & 0xFF;
     }

     AndR(Buffer2, Buffer, j);

     for(i=0; i<j; i++)
     {
       const unsigned char Expected = (i&(3*i ^ j)) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("And failed on pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -11;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+32; i++)
     {
       const unsigned char Expected = (3*i ^ j) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("And corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -12;
         goto Abnormal_End;
       }
     }
   }

   printf(" Or R\n");
   for(j=0; j<TestSize; j++)
   {
     for(i=0; i<j+32; i++)
     {
       Buffer2[i] = (3*i ^ j) & 0xFF;
     }

     OrR(Buffer2, Buffer, j);

     for(i=0; i<j; i++)
     {
       const unsigned char Expected = (i|(3*i ^ j)) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("Or failed on pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+32; i++)
     {
       const unsigned char Expected = (3*i ^ j) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("Or corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }


/*
   printf(" Xor R\n");
   for(j=0; j<TestSize; j++)
   {
     for(i=0; i<j+32; i++)
     {
       Buffer2[i] = (3*i ^ j) & 0xFF;
     }

     XorR(Buffer2, Buffer, j);

     for(i=0; i<j; i++)
     {
       const unsigned char Expected = (i ^ (3*i ^ j)) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("Xor failed on pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=j; i<j+32; i++)
     {
       const unsigned char Expected = (3*i ^ j) & 0xFF;
       if(Buffer2[i] != Expected)
       {
         printf("Xor corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer2[i], Expected, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }
*/

   printf(" Diff Ver1_u32\n");
   for(j=0; j<TestSize/4; j++)
   {
     bool Flag = (((j-1)^j) & 0x1) != 0;
     for(i=0; i<4*j+32; i++)
     {
       Buffer[i] = (i^j) & 0xFF;
       Buffer2[i] = Buffer[i]>>1;
       if(Flag) Buffer2[i]|=0x80;
       Flag = (Buffer[i] & 1) != 0;
     }

     DiffVer1_u32((uint32_t*)(Buffer+16), (const uint32_t*)(Buffer+16), (const uint32_t*)(Buffer2+16), j);

     for(i=16; i<16+4*j; i+=4)
     {
       const uint8_t BytesVal1[4] = {((i^j)&0xFF), (((i+1)^j)&0xFF), (((i+2)^j)&0xFF), (((i+3)^j)&0xFF)};
       const uint32_t val1 = *(uint32_t*)BytesVal1;
       //const uint32_t val1 = ((i^j)&0xFF) | ((((i+1)^j)&0xFF)<<8) | ((((i+2)^j)&0xFF)<<16) | ((((i+3)^j)&0xFF)<<24);
       const uint32_t val2 = *(uint32_t*)(Buffer+i);
       const uint32_t val3 = *(uint32_t*)(Buffer2+i);
       const uint32_t val4 = (val1>>1)+0x80000000 -  (val3>>1);
       if(val4 != val2)
       {
         printf("DiffVer1_u32 failed on pos %d %X!=%Xh, block size %d", i, val2, val4, j);
         Err = -22;
         goto Abnormal_End;
       }
     }

     for(i=0; i<16; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("DiffVer1_u32 failed on pos %d %X!=%Xh, block size %d", i, Buffer[i], val, j);
         Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       uint8_t val = (i^j) & 0xFF;
       if(Buffer[i] != val)
       {
         printf("DiffVer1_u32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], val, j);
         Err = -22;
         goto Abnormal_End;
       }
     }
   }


   printf(" RGB_BGR\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/3; j++)
   {
     RGB_BGR2((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);
     RGB_BGR((char*)Buffer+16,j);

     for(i=16; i<3*j+16; i+=3)
     {
       if(Buffer[i] != ((i+2)&0xFF))
       {
         printf("RGB_BGR failed R on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer[i+1] != ((i+1)&0xFF))
       {
         printf("RGB_BGR failed G on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -11;
         goto Abnormal_End;
       }
       if(Buffer[i+2] != ((i)&0xFF))
       {
         printf("RGB_BGR failed B on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -12;
         goto Abnormal_End;
       }

       Buffer[i] = i;
       Buffer[i+1] = i+1;
       Buffer[i+2] = i+2;


       if(Buffer2[i] != ((i+2)&0xFF))
       {
         printf("RGB_BGR2 failed R on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -13;
         goto Abnormal_End;
       }
       if(Buffer2[i+1] != ((i+1)&0xFF))
       {
         printf("RGB_BGR2 failed G on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -14;
         goto Abnormal_End;
       }
       if(Buffer2[i+2] != ((i)&0xFF))
       {
         printf("RGB_BGR2 failed B on pos %d %u!=%u, block size %d", i, Buffer[i], ((i+2)&0xFF), j);
	 Err = -15;
         goto Abnormal_End;
       }
     }
     for(i=3*j+16; i<3*j+32; i++)
     {
       if(Buffer[i] != (i&0xFF))
       {
         printf("RGB_BGR corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" RGB_Gray\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/3; j++)
   {
     memset(Buffer2+16+j, j&0xFF, 16);
     RGB_Gray((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     for(i=0; i<j; i++)
     {
       const unsigned k = 3*i+16;
       uint8_t GrayVal = (Buffer[k]+Buffer[k+1]+Buffer[k+2]) / 3;

       if(Buffer2[i+16] != GrayVal)
       {
         printf("RGB_Gray failed on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }

     }
     for(i=j+16; i<j+32; i++)
     {
       if(Buffer2[i] != (j&0xFF))
       {
         printf("RGB_Gray corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" RGB32_Gray\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/4; j++)
   {
     memset(Buffer2+16+j, j&0xFF, 16);
     RGB32_Gray((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     for(i=0; i<j; i++)
     {
       const unsigned k = 4*i+16;
       uint8_t GrayVal = (Buffer[k]+Buffer[k+1]+Buffer[k+2]) / 3;

       if(Buffer2[i+16] != GrayVal)
       {
         printf("RGB32_Gray failed on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }

     }
     for(i=j+16; i<j+32; i++)
     {
       if(Buffer2[i] != (j&0xFF))
       {
         printf("RGB32_Gray corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" RGB_Gray24\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/3; j++)
   {
     memset(Buffer2+16+3*j, j&0xFF, 16);
     RGB_Gray24((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     for(i=0; i<j; i++)
     {
       const unsigned k = 3*i+16;
       uint8_t GrayVal = (Buffer[k]+Buffer[k+1]+Buffer[k+2]) / 3;

       if(Buffer2[3*i+16] != GrayVal)
       {
         printf("RGB_Gray24 failed R on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+17] != GrayVal)
       {
         printf("RGB_Gray24 failed G on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+18] != GrayVal)
       {
         printf("RGB_Gray24 failed B on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }

     }
     for(i=3*j+16; i<3*j+32; i++)
     {
       if(Buffer2[i] != (j&0xFF))
       {
         printf("RGB_Gray24 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" BGR_Gray24precise\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/3; j++)
   {
     memset(Buffer2+16+3*j, j&0xFF, 16);
     BGR_Gray24precise((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     for(i=0; i<j; i++)
     {
       const unsigned k = 3*i+16;
       uint8_t GrayVal = (Buffer[k]*4731 + Buffer[k+1]*46871 + Buffer[k+2]*13932)/65536;

       if(Buffer2[3*i+16] != GrayVal)
       {
         printf("BGR_Gray24precise failed R on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+17] != GrayVal)
       {
         printf("BGR_Gray24precise failed G on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+18] != GrayVal)
       {
         printf("BGR_Gray24precise failed B on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }

     }
     for(i=3*j+16; i<3*j+32; i++)
     {
       if(Buffer2[i] != (j&0xFF))
       {
         printf("BGR_Gray24precise corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" BGR32_Gray24\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   for(j=0; j<TestSize/4; j++)
   {
     memset(Buffer2+16+3*j, j&0xFF, 16);
     BGR32_Gray24((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     for(i=0; i<j; i++)
     {
       const unsigned k = 4*i+16;
       uint8_t GrayVal = (Buffer[k]*4731 + Buffer[k+1]*46871 + Buffer[k+2]*13932)/65536;

       if(Buffer2[3*i+16] != GrayVal)
       {
         printf("BGR32_Gray24 failed R on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+17] != GrayVal)
       {
         printf("BGR32_Gray24 failed G on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }
       if(Buffer2[3*i+18] != GrayVal)
       {
         printf("BGR32_Gray24 failed B on pos %d %u!=%u, block size %d", i, Buffer2[i+16], GrayVal, j);
	 Err = -10;
         goto Abnormal_End;
       }

     }
     for(i=3*j+16; i<3*j+32; i++)
     {
       if(Buffer2[i] != (j&0xFF))
       {
         printf("BGR32_Gray24 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], (i&0xFF), j);
	 Err = -16;
         goto Abnormal_End;
       }
     }
     
   }


   printf(" RGB32_BGR24\n");
   for(i=0; i<TestSize+32; i++)
   {
     Buffer[i] = i & 0xFF;
   }
   memset(Buffer2,0x5A,TestSize);
   for(j=0; j<TestSize/4; j++)
   {
     RGB32_BGR24((unsigned char*)Buffer2+16, (unsigned char*)Buffer+16, j);

     unsigned char *ConvBuffer = Buffer2 + 16;
     for(i=16; i<4*j+16; i+=4)
     {
       if(ConvBuffer[0] != ((i+2)&0xFF))
       {
         printf("RGB32_BGR24 failed R on pos %d %u!=%u, block size %d", i, ConvBuffer[0], ((i+2)&0xFF), j);
	 Err = -21;
         goto Abnormal_End;
       }
       if(ConvBuffer[1] != ((i+1)&0xFF))
       {
         printf("RGB32_BGR24 failed G on pos %d %u!=%u, block size %d", i, ConvBuffer[1], ((i+2)&0xFF), j);
	 Err = -22;
         goto Abnormal_End;
       }
       if(ConvBuffer[2] != ((i)&0xFF))
       {
         printf("RGB32_BGR24 failed B on pos %d %u!=%u, block size %d", i, ConvBuffer[2], ((i+2)&0xFF), j);
	 Err = -23;
         goto Abnormal_End;
       }
       ConvBuffer += 3;
     }
     for(i=0; i<16; i++)
     {
       if(ConvBuffer[i] != 0x5A)
       {
         printf("RGB32_BGR24 corrupted memory behind block pos %d %u!=%u, block size %d", i, ConvBuffer[i], 0x5A, j);
	 Err = -24;
         goto Abnormal_End;
       }
     }
     
   }

   free(Buffer);
   free(Buffer2); Buffer2=NULL;



   printf(" RGBA32_BGRiA32\n");
   Buffer = (uint8_t*)malloc(TestSize+2*16);
   for(j=0; j<TestSize/4; j++)
   {
     for(i=0; i<4*j+32; i++)
     {
       Buffer[i] = i & 0xFF;
     }
     RGBA32_BGRiA32((unsigned char*)(Buffer+16),j);
     for(i=0; i<j; i++)
     {
       uint8_t *k = Buffer+16+4*i;
       uint8_t val = 16+4*i+2;
       if(k[0] != val)
       {
         printf("RGBA32_BGRiA32 failed R on pos %d %u!=%u, block size %d", i, k[0], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = 16+4*i+1;
       if(k[1] != val)
       {
         printf("RGBA32_BGRiA32 failed G on pos %d %u!=%u, block size %d", i, k[1], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = 16+4*i;
       if(k[2] != val)
       {
         printf("RGBA32_BGRiA32 failed B on pos %d %u!=%u, block size %d", i, k[2], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = ~(16+4*i+3);
       if(k[3] != val)
       {
         printf("RGBA32_BGRiA32 failed A on pos %d %u!=%u, block size %d", i, k[3], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
     }
     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i & 0xFF))
       {
         printf("RGBA32_BGRiA32 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], i&0xFF, j);
	 Err = -24;
         goto Abnormal_End;
       }
     }
     for(i=4*j+16; i<4*j+32; i++)
     {
       if(Buffer[i] != (i & 0xFF))
       {
         printf("RGBA32_BGRiA32 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], i&0xFF, j);
	 Err = -24;
         goto Abnormal_End;
       }
     }
   }
   free(Buffer);


   printf(" RGBA64_BGRiA64\n");
   Buffer = (uint8_t*)malloc(TestSize+2*16);
   for(j=0; j<TestSize/8; j++)
   {
     for(i=0; i<8*j+32; i++)
     {
       Buffer[i] = i & 0xFF;
     }
     RGBA64_BGRiA64((unsigned char*)(Buffer+16),j);
     for(i=0; i<j; i++)
     {
       uint8_t *k = Buffer+16+8*i;
       uint8_t val = 16+i*8+4;
       if(k[0] != val)
       {
         printf("RGBA64_BGRiA64 failed R1 on pos %d %u!=%u, block size %d", i, k[0], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = 16+i*8+5;
       if(k[1] != val)
       {
         printf("RGBA64_BGRiA64 failed R2 on pos %d %u!=%u, block size %d", i, k[1], val, j);
	 Err = -21;
         goto Abnormal_End;
       }

       val = 16+8*i+2;
       if(k[2] != val)
       {
         printf("RGBA64_BGRiA64 failed G1 on pos %d %u!=%u, block size %d", i, k[2], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = 16+8*i+3;
       if(k[3] != val)
       {
         printf("RGBA64_BGRiA64 failed G2 on pos %d %u!=%u, block size %d", i, k[3], val, j);
	 Err = -21;
         goto Abnormal_End;
       }

       val = 16+8*i;
       if(k[4] != val)
       {
         printf("RGBA64_BGRiA64 failed B1 on pos %d %u!=%u, block size %d", i, k[4], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = 16+8*i+1;
       if(k[5] != val)
       {
         printf("RGBA64_BGRiA64 failed B2 on pos %d %u!=%u, block size %d", i, k[5], val, j);
	 Err = -21;
         goto Abnormal_End;
       }

       val = ~(16+8*i+6);
       if(k[6] != val)
       {
         printf("RGBA64_BGRiA64 failed A1 on pos %d %u!=%u, block size %d", i, k[6], val, j);
	 Err = -21;
         goto Abnormal_End;
       }
       val = ~(16+8*i+7);
       if(k[7] != val)
       {
         printf("RGBA64_BGRiA64 failed A2 on pos %d %u!=%u, block size %d", i, k[7], val, j);
	 Err = -21;
         goto Abnormal_End;
       }

     }
     for(i=0; i<16; i++)
     {
       if(Buffer[i] != (i & 0xFF))
       {
         printf("RGBA64_BGRiA64 corrupted memory before block pos %d %u!=%u, block size %d", i, Buffer[i], i&0xFF, j);
	 Err = -24;
         goto Abnormal_End;
       }
     }
     for(i=8*j+16; i<8*j+32; i++)
     {
       if(Buffer[i] != (i & 0xFF))
       {
         printf("RGBA64_BGRiA64 corrupted memory behind block pos %d %u!=%u, block size %d", i, Buffer[i], i&0xFF, j);
	 Err = -24;
         goto Abnormal_End;
       }
     }
   }
   free(Buffer);


   printf(" RGB_YUV\n");

   Buffer = (unsigned char*)malloc(512);
   Buffer2 = (unsigned char*)malloc(3*512);
   unsigned char *U = (unsigned char*)malloc(256);
   unsigned char *V = (unsigned char*)malloc(256);
   
   for(i=0; i<256; i++)
   {
     Buffer[i] = i;
   }
   memset(U,128,128);
   memset(V,128,128);

   YUV_RGB(Buffer2, Buffer, U, V, 256);

   for(i=0; i<256; i++)
   {
     if(Buffer2[3*i] != i)
     {
       printf("RGB_YUV wrong R compound %u!=%u", i, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+1] != i)
     {
       printf("RGB_YUV wrong G compound %u!=%u", i, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+2] != i)
     {
       printf("RGB_YUV wrong B compound %u!=%u", i, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[i] = i/2;
   }
   memset(U,128-10,256);
   memset(V,128,256);

   YUV_RGB(Buffer2, Buffer, U, V, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("RGB_YUV wrong R compound U=-10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 102*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("RGB_YUV wrong G compound U=-10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) - 521*10) / 256;
     if(B<0) B=0;
     if(Buffer2[3*i+2] != B)
     {
       printf("RGB_YUV wrong B compound U=-10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   memset(U,128+10,256);
   memset(V,128,256);

   YUV_RGB(Buffer2, Buffer, U, V, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("RGB_YUV wrong R compound U=10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 102*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("RGB_YUV wrong G compound U=10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) + 521*10) / 256;
     if(B>255) B=255;
     if(Buffer2[3*i+2] != B)
     {
       printf("RGB_YUV wrong B compound U=10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   memset(U,128,256);
   memset(V,128-10,256);

   YUV_RGB(Buffer2, Buffer, U, V, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) - 291*10) / 256;
     if(R<0) R=0;
     if(Buffer2[3*i] != R)
     {
       printf("RGB_YUV wrong R compound U=0,V=-10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 148*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("RGB_YUV wrong G compound U=0,V=-10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("RGB_YUV wrong B compound U=0,V=-10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   memset(U,128,256);
   memset(V,128+10,256);

   YUV_RGB(Buffer2, Buffer, U, V, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) + 291*10) / 256;
     if(R>255) R=255;
     if(Buffer2[3*i] != R)
     {
       printf("RGB_YUV wrong R compound U=0,V=10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 148*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("RGB_YUV wrong G compound U=0,V=10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("RGB_YUV wrong B compound U=0,V=10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   free(U);
   free(V);
   free(Buffer);
   free(Buffer2);

	/////////////////////

   printf(" YUYV_RGB\n");
   
   Buffer = (unsigned char*)malloc(4*512);
   Buffer2 = (unsigned char*)malloc(3*512);

   for(i=0; i<256; i++)
   {
     Buffer[2*i] = i;
   }
   for(i=0; i<128; i++)
   {
     Buffer[4*i+1] = 128;
     Buffer[4*i+3] = 128;
   }

   YUYV_RGB(Buffer2, Buffer, 256);

   for(i=0; i<256; i++)
   {
     if(Buffer2[3*i] != i)
     {
       printf("YUYV_RGB wrong R compound %u!=%u", i, Buffer2[3*i]);
       Err = -41;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+1] != i)
     {
       printf("YUYV_RGB wrong G compound %u!=%u", i, Buffer2[3*i+1]);
       Err = -42;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+2] != i)
     {
       printf("YUYV_RGB wrong B compound %u!=%u", i, Buffer2[3*i+2]);
       Err = -43;
       goto Abnormal_End;
     }
   }

	// Overflow test.
   for(j=0; j<6; j++)
   {
     FeedBuffer(Buffer,j);

     YUYV_RGB(Buffer2, Buffer, 512);

     for(i=0; i<256; i++)
     {
       int32_t Y = Buffer[4*i];
       int32_t Y2 = Buffer[4*i+2];
       int32_t U = Buffer[4*i+1] - 128;
       int32_t V = Buffer[4*i+3] - 128;
       uint8_t R1 = Buffer2[6*i];
       uint8_t R2 = Buffer2[6*i+3];
       uint8_t G1 = Buffer2[6*i+1];
       uint8_t G2 = Buffer2[6*i+4];
       uint8_t B1 = Buffer2[6*i+2];
       uint8_t B2 = Buffer2[6*i+5];

       int32_t X = (256*Y + 291*V) >> 8;	// Y + 1.137*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != R1)
       {
         printf("YUYV_RGB wrong R1 compound %u!=%u", X, R1);
         Err = -41;
         goto Abnormal_End;
       }
     
       X = (256*Y2 + 291*V) >> 8;		// Y + 1.137*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != R2)
       {
         printf("YUYV_RGB wrong R2 compound %u!=%u", X, R2);
         Err = -41;
         goto Abnormal_End;
       }

       X = (256*Y -102*U - 148*V) >> 8; // Y - 0.397*U - 0.58*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != G1)
       {
         printf("YUYV_RGB wrong G1 compound %u!=%u", X, G1);
         Err = -41;
         goto Abnormal_End;
       }     
       X = (256*Y2 -102*U - 148*V) >> 8; // Y - 0.397*U - 0.58*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != G2)
       {
         printf("YUYV_RGB wrong G2 compound %u!=%u", X, G2);
         Err = -41;
         goto Abnormal_End;
       }

       X = (256*Y + 521*U) >> 8;	// Y + 2.034*U;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != B1)
       {
         printf("YUYV_RGB wrong B1 compound %u!=%u", X, B1);
         Err = -41;
         goto Abnormal_End;
       }     
       X = (256*Y2 + 521*U) >> 8;	// Y + 2.034*U;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != B2)
       {
         printf("YUYV_RGB wrong B2 compound %u!=%u", X, B2);
         Err = -41;
         goto Abnormal_End;
       }
     }
   }


   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+1] = 128 - 10;
     Buffer[4*i+3] = 128;
   }
   YUYV_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("YUYV_RGB wrong R compound U=-10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 102*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("YUYV_RGB wrong G compound U=-10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) - 521*10) / 256;
     if(B<0) B=0;
     if(Buffer2[3*i+2] != B)
     {
       printf("YUYV_RGB wrong B compound U=-10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+1] = 128 + 10;
     Buffer[4*i+3] = 128;
   }
   YUYV_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("YUYV_RGB wrong R compound U=10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 102*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("YUYV_RGB wrong G compound U=10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) + 521*10) / 256;
     if(B>255) B=255;
     if(Buffer2[3*i+2] != B)
     {
       printf("YUYV_RGB wrong B compound U=10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+1] = 128;
     Buffer[4*i+3] = 128 - 10;
   }
   YUYV_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) - 291*10) / 256;
     if(R<0) R=0;
     if(Buffer2[3*i] != R)
     {
       printf("YUYV_RGB wrong R compound U=0,V=-10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 148*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("YUYV_RGB wrong G compound U=0,V=-10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("YUYV_RGB wrong B compound U=0,V=-10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }


   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+1] = 128;
     Buffer[4*i+3] = 128 + 10;
   }
   YUYV_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) + 291*10) / 256;
     if(R>255) R=255;
     if(Buffer2[3*i] != R)
     {
       printf("YUYV_RGB wrong R compound U=0,V=10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 148*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("YUYV_RGB wrong G compound U=0,V=10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("YUYV_RGB wrong B compound U=0,V=10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   free(Buffer);
   free(Buffer2);



	/////////////////////

   printf(" YVYU_RGB\n");
   
   Buffer = (unsigned char*)malloc(4*512);
   Buffer2 = (unsigned char*)malloc(3*512);

   for(i=0; i<256; i++)
   {
     Buffer[2*i] = i;
   }
   for(i=0; i<128; i++)
   {
     Buffer[4*i+1] = 128;
     Buffer[4*i+3] = 128;
   }

   YVYU_RGB(Buffer2, Buffer, 256);

   for(i=0; i<256; i++)
   {
     if(Buffer2[3*i] != i)
     {
       printf("YVYU_RGB wrong R compound %u!=%u", i, Buffer2[3*i]);
       Err = -41;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+1] != i)
     {
       printf("YVYU_RGB wrong G compound %u!=%u", i, Buffer2[3*i+1]);
       Err = -42;
       goto Abnormal_End;
     }
     if(Buffer2[3*i+2] != i)
     {
       printf("YVYU_RGB wrong B compound %u!=%u", i, Buffer2[3*i+2]);
       Err = -43;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+3] = 128 - 10;
     Buffer[4*i+1] = 128;
   }
   YVYU_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("YVYU_RGB wrong R compound U=-10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 102*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("YVYU_RGB wrong G compound U=-10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) - 521*10) / 256;
     if(B<0) B=0;
     if(Buffer2[3*i+2] != B)
     {
       printf("YVYU_RGB wrong B compound U=-10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+3] = 128 + 10;
     Buffer[4*i+1] = 128;
   }
   YVYU_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     if(Buffer2[3*i] != i/2)
     {
       printf("YVYU_RGB wrong R compound U=10,V=0 %u!=%u", i/2, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 102*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("YVYU_RGB wrong G compound U=10,V=0 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }
     int B = (256*(i/2) + 521*10) / 256;
     if(B>255) B=255;
     if(Buffer2[3*i+2] != B)
     {
       printf("YVYU_RGB wrong B compound U=10,V=0 %u!=%u", B, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+3] = 128;
     Buffer[4*i+1] = 128 - 10;
   }
   YVYU_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) - 291*10) / 256;
     if(R<0) R=0;
     if(Buffer2[3*i] != R)
     {
       printf("YVYU_RGB wrong R compound U=0,V=-10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) + 148*10) / 256;
     if(G>255) G=255;
     if(Buffer2[3*i+1] != G)
     {
       printf("YVYU_RGB wrong G compound U=0,V=-10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("YVYU_RGB wrong B compound U=0,V=-10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }


   for(i=0; i<512; i++)
   {
     Buffer[2*i] = i/2;
   }
   for(i=0; i<256; i++)
   {
     Buffer[4*i+3] = 128;
     Buffer[4*i+1] = 128 + 10;
   }
   YVYU_RGB(Buffer2, Buffer, 512);

   for(i=0; i<512; i++)
   {
     int R = (256*(i/2) + 291*10) / 256;
     if(R>255) R=255;
     if(Buffer2[3*i] != R)
     {
       printf("YVYU_RGB wrong R compound U=0,V=10 %u!=%u", R, Buffer2[3*i]);
       Err = -31;
       goto Abnormal_End;
     }
     int G = (256*(i/2) - 148*10) / 256;
     if(G<0) G=0;
     if(Buffer2[3*i+1] != G)
     {
       printf("YVYU_RGB wrong G compound U=0,V=10 %u!=%u", G, Buffer2[3*i+1]);
       Err = -32;
       goto Abnormal_End;
     }     
     if(Buffer2[3*i+2] != i/2)
     {
       printf("YVYU_RGB wrong B compound U=0,V=10 %u!=%u", i/2, Buffer2[3*i+2]);
       Err = -33;
       goto Abnormal_End;
     }
   }

	// Overflow test.
   for(j=0; j<6; j++)
   {
     FeedBuffer(Buffer,j);

     YVYU_RGB(Buffer2, Buffer, 512);

     for(i=0; i<256; i++)
     {
       int32_t Y = Buffer[4*i];
       int32_t Y2 = Buffer[4*i+2];
       int32_t V = Buffer[4*i+1] - 128;
       int32_t U = Buffer[4*i+3] - 128;
       uint8_t R1 = Buffer2[6*i];
       uint8_t R2 = Buffer2[6*i+3];
       uint8_t G1 = Buffer2[6*i+1];
       uint8_t G2 = Buffer2[6*i+4];
       uint8_t B1 = Buffer2[6*i+2];
       uint8_t B2 = Buffer2[6*i+5];

       int32_t X = (256*Y + 291*V) >> 8;	// Y + 1.137*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != R1)
       {
         printf("YVYU_RGB wrong R1 compound %u!=%u", X, R1);
         Err = -41;
         goto Abnormal_End;
       }
     
       X = (256*Y2 + 291*V) >> 8;		// Y2 + 1.137*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != R2)
       {
         printf("YVYU_RGB wrong R2 compound %u!=%u", X, R2);
         Err = -41;
         goto Abnormal_End;
       }

       X = (256*Y -102*U - 148*V) >> 8; // Y - 0.397*U - 0.58*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != G1)
       {
         printf("YVYU_RGB wrong G1 compound %u!=%u", X, G1);
         Err = -41;
         goto Abnormal_End;
       }     
       X = (256*Y2 -102*U - 148*V) >> 8; // Y2 - 0.397*U - 0.58*V;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != G2)
       {
         printf("YVYU_RGB wrong G2 compound %u!=%u", X, G2);
         Err = -41;
         goto Abnormal_End;
       }

       X = (256*Y + 521*U) >> 8;	// Y + 2.034*U;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != B1)
       {
         printf("YVYU_RGB wrong B1 compound %u!=%u", X, B1);
         Err = -41;
         goto Abnormal_End;
       }     
       X = (256*Y2 + 521*U) >> 8;	// Y2 + 2.034*U;
       if(X<0) X=0;
       if(X>255) X=255;
       if(X != B2)
       {
         printf("YVYU_RGB wrong B2 compound %u!=%u", X, B2);
         Err = -41;
         goto Abnormal_End;
       }
     }
   }

   free(Buffer);
   free(Buffer2);
 }



 /////////////////////////////////////
 if(heapcheck()>0)
     if(Err==0 && (Ops & 2)) Benchmark();

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

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


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

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


Raster1DAbstract *RA1 = NULL;
Raster1DAbstract *RA2 = NULL;
Raster1DAbstract *RU = NULL;
Raster1DAbstract *RV = NULL;


void BenchAbsDiff32(long i)
{
  while(i-->0)
  {
    AbsDiff_u32((uint32_t*)RA1->GetRow(),(uint32_t*)RA1->GetRow(),RA1->GetSize1D());
    AbsDiff_u32((uint32_t*)RA2->GetRow(),(uint32_t*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchAbsDiffCopy32(long i)
{
  while(i-->0)
  {
    AbsDiffCopy_u32((uint32_t*)RA1->GetRow(), (uint32_t*)RA1->GetRow(),(uint32_t*)RA1->GetRow(),RA1->GetSize1D());
    AbsDiffCopy_u32((uint32_t*)RA2->GetRow(), (uint32_t*)RA2->GetRow(),(uint32_t*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchNotR(long i)
{
  while(i-->0)
  {
    NotR((char*)RA1->GetRow(),RA1->GetSize1D());
    NotR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchSwab16(long i)
{
  while(i-->0)
  {
    swab16((unsigned char*)RA1->GetRow(),RA1->GetSize1D());
    //NotR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchSwab32(long i)
{
  while(i-->0)
  {
    swab32((unsigned char*)RA1->GetRow(),RA1->GetSize1D());
    //NotR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchSwab64(long i)
{
  while(i-->0)
  {
    swab64((unsigned char*)RA1->GetRow(),RA1->GetSize1D());
    //NotR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchRGBA64_BGRiA64(long i)
{
  while(i-->0)
  {
    RGBA64_BGRiA64((unsigned char*)RA1->GetRow(),RA1->GetSize1D());
    //NotR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchShrR(long i)
{
  while(i-->0)
  {
    ShrR((char*)RA1->GetRow(),RA1->GetSize1D());
    ShrR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


void BenchShlR(long i)
{
  while(i-->0)
  {
    ShlR((char*)RA1->GetRow(),RA1->GetSize1D(),1);
    ShlR((char*)RA2->GetRow(),RA2->GetSize1D(),4);
  }
}


static void BenchRGB_BGR(long i)
{
  while(i-->0)
  {
    RGB_BGR((char*)RA1->GetRow(),RA1->GetSize1D());
    RGB_BGR((char*)RA2->GetRow(),RA2->GetSize1D());
  }
}


static void BenchRGB_Gray(long i)
{
  while(i-->0)
  {
    RGB_Gray((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
    RGB_Gray((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
  }
}


static void BenchRGB32_Gray(long i)
{
  while(i-->0)
  {
    RGB32_Gray((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
    RGB32_Gray((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
  }
}


static void BenchAddLu32u8(long i)
{
  while(i-->0)
  {
    AddLu32u8(RA1->Size1D, (uint32_t*)RA2->GetRow(),(unsigned char*)RA1->GetRow());
    AddLu32u8(RA1->Size1D, (uint32_t*)RA2->GetRow(),(unsigned char*)RA1->GetRow());
  }
}


static void BenchSubLu32u8(long i)
{
  while(i-->0)
  {
    SubLu32u8(RA1->Size1D, (uint32_t*)RA2->GetRow(),(unsigned char*)RA1->GetRow());
    SubLu32u8(RA1->Size1D, (uint32_t*)RA2->GetRow(),(unsigned char*)RA1->GetRow());
  }
}


static void BenchRGB_Gray24(long i)
{
  while(i-->0)
  {
    RGB_Gray24((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
    RGB_Gray24((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
  }
}


static void BenchBGR_Gray24precise(long i)
{
  while(i-->0)
  {
    BGR_Gray24precise((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);
    BGR_Gray24precise((unsigned char*)RA1->GetRow(),(unsigned char*)RA2->GetRow(),RA1->Size1D);    
  }
}


static void BenchRGB_BGR2(long i)
{
  while(i-->0)
  {
    RGB_BGR2((unsigned char *)RA1->GetRow(),(unsigned char *)RA2->GetRow(),RA1->GetSize1D());
  }
}


void BenchRGB32_BGR24(long i)
{
  while(i-->0)
  {
    RGB32_BGR24((unsigned char *)RA1->GetRow(),(unsigned char *)RA2->GetRow(),RA1->Size1D);
    RGB32_BGR24((unsigned char *)RA1->GetRow(),(unsigned char *)RA2->GetRow(),RA1->Size1D);
  }
}


void BenchBGR32_Gray24(long i)
{
  while(i-->0)
  {
    BGR32_Gray24((unsigned char *)RA1->GetRow(), (unsigned char *)RA2->GetRow(), RA1->Size1D);
    BGR32_Gray24((unsigned char *)RA1->GetRow(), (unsigned char *)RA2->GetRow(), RA1->Size1D);
  }
}



void BenchYUV_RGB(long i)
{
  while(i-->0)
  {
    YUV_RGB((unsigned char *)RA1->GetRow(),
	    (unsigned char *)RA2->GetRow(),
	    (unsigned char *)RU->GetRow(),
	    (unsigned char *)RV->GetRow(),
	    RA2->GetSize1D());
  }
}


void BenchYUYV_RGB(long i)
{
  while(i-->0)
  {
    YUYV_RGB((unsigned char *)RA1->GetRow(),
	    (unsigned char *)RA2->GetRow(),
	    RA1->GetSize1D());
  }
}


void BenchYVYU_RGB(long i)
{
  while(i-->0)
  {
    YVYU_RGB((unsigned char *)RA1->GetRow(),
	    (unsigned char *)RA2->GetRow(),
	    RA1->GetSize1D());
  }
}


/*
void BenchYUV_RGB2(long i)
{
  while(i-->0)
  {
    YUV_RGB2((unsigned char *)RA1->GetRow(),
	    (unsigned char *)RA2->GetRow(),
	    (unsigned char *)RU->GetRow(),
	    (unsigned char *)RV->GetRow(),
	    RA2->GetSize1D());
  }
}
*/


void BenchOrR(long i)
{
  const unsigned size = MIN(RA1->GetSize1D(), RA2->GetSize1D());
  while(i-->0)
  {
    OrR((char*)RA1->GetRow(),(char*)RA2->GetRow(),size);
    OrR((char*)RA2->GetRow(),(char*)RA2->GetRow(),size);
  }
}


void BenchAndR(long i)
{
  const unsigned size = MIN(RA1->GetSize1D(), RA2->GetSize1D());
  while(i-->0)
  {
    AndR((char*)RA1->GetRow(),(char*)RA2->GetRow(),size);
    AndR((char*)RA2->GetRow(),(char*)RA2->GetRow(),size);
  }
}



void Benchmark(void)
{
float f;

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


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

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

 RA1 = CreateRaster1D(3001,32);
 RA2 = CreateRaster1D(16385,32);

 printf("\nAbsDiff U32 [us]:");
 f = AutoMeasure(BenchAbsDiff32);
 printf("%8.5g throwput %f [MB/s]", f, (double)4000000*(RA1->Size1D+RA2->Size1D) / (f*1000000.0));

 printf("\nAbsDiffCopy U32 [us]:");
 f = AutoMeasure(BenchAbsDiffCopy32);
 printf("%8.5g throwput %f [MB/s]", f, (double)4000000*(RA1->Size1D+RA2->Size1D) / (f*1000000.0));


 RA1 = CreateRaster1D(3001,8);
 RA2 = CreateRaster1D(16385,8);

 printf("\nNotR [us]:");
 f = AutoMeasure(BenchNotR);
 printf("%8.5g throwput %f [MB/s]", f, (double)1000000*(RA1->Size1D+RA2->Size1D) / (f*1000000.0));

 printf("\nShrR [us]:");
 f = AutoMeasure(BenchShrR);
 printf("%8.5g ", f/2);

 printf("\nShlR [us]:");
 f = AutoMeasure(BenchShlR);
 printf("%8.5g ", f/2);

 delete RA1;
 delete RA2;


 RA1 = CreateRaster1D(16385,16);

 printf("\nSwab 16 [us]:");
 f = AutoMeasure(BenchSwab16);
 printf("%8.5g estimated throwput %f [Mpx/s]", f, (double)1000000*(RA1->Size1D) / (f*1000000.0));

 delete RA1;

 RA1 = CreateRaster1D(16387,32);

 printf("\nSwab 32 [us]:");
 f = AutoMeasure(BenchSwab32);
 printf("%8.5g estimated throwput %f [Mpx/s]", f, (double)1000000*(RA1->Size1D) / (f*1000000.0));

 delete RA1;

 RA1 = CreateRaster1D(16387,64);

 printf("\nSwab 64 [us]:");
 f = AutoMeasure(BenchSwab64);
 printf("%8.5g estimated throwput %f [Mpx/s]", f, (double)1000000*(RA1->Size1D) / (f*1000000.0));

 printf("\nRGBA64_BGRiA64 [us]:");
 f = AutoMeasure(BenchRGBA64_BGRiA64);
 printf("%8.5g estimated throwput %f [Mpx/s]", f, (double)1000000*(RA1->Size1D) / (f*1000000.0));

 delete RA1;
 

 RA1 = CreateRaster1D(16387,8);
 RA2 = CreateRaster1D(16387,8);

for(unsigned i=0; i<RA2->Size1D; i++)
 {
   RA1->SetValue1D(i,(i/256) & 0xFF);
   RA2->SetValue1D(i,((i+5)/256) & 0xFF);
 }

 printf("\nAndR [us]:");
 f = AutoMeasure(BenchAndR);
 printf("%8.5g ", f/2);
 printf("\nOrR [us]:");
 f = AutoMeasure(BenchOrR);

 delete RA1;
 delete RA2;


 RA1 = CreateRaster1D(3001,24);
 RA2 = CreateRaster1D(16387,24);

 printf("\nRGB_BGR [us]:");
 f = AutoMeasure(BenchRGB_BGR);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %f [Mpx/s]", f/2, (double)1000000*(RA2->Size1D+RA1->Size1D) / (f*1000000.0));

 delete RA1;
 delete RA2;



 RA1 = CreateRaster1D(16387,8);
 RA2 = CreateRaster1D(16387,32);

 printf("\nRGB32_Gray [us]:");
 f = AutoMeasure(BenchRGB32_Gray);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %f [Mpx/s]", f/2, (double)1000000*(2*RA1->Size1D) / (f*1000000.0));


 printf("\nAddLu32u8 [us]:");
 f = AutoMeasure(BenchAddLu32u8);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %f [Mpx/s]", f/2, (double)1000000*(2*RA1->Size1D) / (f*1000000.0));

 printf("\nSubLu32u8 [us]:");
 f = AutoMeasure(BenchSubLu32u8);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %f [Mpx/s]", f/2, (double)1000000*(2*RA1->Size1D) / (f*1000000.0));

 delete RA1;
 delete RA2;



 RA1 = CreateRaster1D(16387,8);
 RA2 = CreateRaster1D(16387,24);

 printf("\nRGB_Gray [us]:");
 f = AutoMeasure(BenchRGB_Gray);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %f [Mpx/s]", f/2, (double)1000000*2*RA2->Size1D / (f*1000000.0));

 delete RA1;
 delete RA2;


 RA1 = CreateRaster1D(16389,24);
 RA2 = CreateRaster1D(16389,24);

 printf("\nRGB_Gray24 [us]:");
 f = AutoMeasure(BenchRGB_Gray24);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %.2f [Mpx/s]", f/2, (double)1000000*2*RA2->Size1D / (f*1000000.0));

 printf("\nBGR_Gray24precise [us]:");
 f = AutoMeasure(BenchBGR_Gray24precise);  //RA1->Get(*RA2);
 printf("%8.5g 	estimated throwput %.2f [Mpx/s]", f/2, (double)1000000*2*RA2->Size1D / (f*1000000.0));

 printf("\nRGB_BGR2 [us]:");
 f = AutoMeasure(BenchRGB_BGR2);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f, (double)1000000*RA2->Size1D / (f*1000000.0));

 delete RA1;
 delete RA2;


 RA1 = CreateRaster1D(16389,24);	// output.
 RA2 = CreateRaster1D(16389,32);

 printf("\nRGB32_BGR24 [us]:");
 f = AutoMeasure(BenchRGB32_BGR24);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f/2, (double)1000000*2*RA2->Size1D / (f*1000000.0));

 printf("\nBGR32_GRAY24 [us]:");
 f = AutoMeasure(BenchBGR32_Gray24);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f/2, (double)1000000*2*RA1->Size1D / (f*1000000.0));

 delete RA1;
 delete RA2;


 RA1 = CreateRaster1D(16389,24);
 RA2 = CreateRaster1D(16389,8);
 RU = CreateRaster1D(16389,8);
 RV = CreateRaster1D(16389,8);

 for(unsigned i=0; i<RA2->Size1D; i++)
 {
   RA2->SetValue1D(i,i & 0xFF);
   RU->SetValue1D(i,(i/256) & 0xFF);
   RV->SetValue1D(i,((i+5)/256) & 0xFF);
 }

 printf("\nYUV_RGB [us]:");
 f = AutoMeasure(BenchYUV_RGB);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f, (double)1000000*RA2->Size1D / (f*1000000.0));

 delete RA1;
 delete RA2;
 delete RU;
 delete RV;

 RA1 = CreateRaster1D(16388,24); 
 RA2 = CreateRaster1D(16388/2,32);
 for(unsigned i=0; i<RA2->Size1D; i++)
 {
   int x = (i&0xFF) | ((i&0xFF)<<16) | (i & 0xFF00) | (((i+1) & 0xFF00)<<16);
   RA2->SetValue1D(i,x);
 }

 printf("\nYUYV_RGB [us]:");
 f = AutoMeasure(BenchYUYV_RGB);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f, (double)1000000*RA1->Size1D / (f*1000000.0));

 printf("\nYVYU_RGB [us]:");
 f = AutoMeasure(BenchYVYU_RGB);  //RA1->Get(*RA2);
 printf("%8.5g	estimated throwput %.2f [Mpx/s]", f, (double)1000000*RA1->Size1D / (f*1000000.0));

 delete RA1;
 delete RA2;

 printf("\n");
}
