/*********************************************************
* unit:    raster            release 0.13                *
* purpose: general manipulation n dimensional matrices   *
*          n = 1, 2 and 3.			         *
* licency:     GPL or LGPL                               *
**********************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include "types.h"
#include "common.h"

#include "raster.h"


void Conv8_1(BYTE *Dest, const BYTE *Src, unsigned Size1D)
{
BYTE Mask;

  while(Size1D>0)
    {
    *Dest = 0;
    for(Mask=0x80; Mask!=0; Mask>>=1)
      {
      if(*Src++>=0x80) *Dest |= Mask;
      if(--Size1D<=0) return;
      }
    Dest++;
    }
}

void Conv8_16(WORD *Dest, const BYTE *Src, unsigned Size1D)
{
  while(Size1D-->0)
  {
    *Dest++ = *Src++ * 0x101;
  }
}

void Conv8_32(DWORD *Dest, const BYTE *Src, unsigned Size1D)
{
  while(Size1D-->0)
  {
    *Dest++ = *Src++ * 0x1010101;
  }
}


void Conv16_1(BYTE *Dest, const WORD *Src, unsigned Size1D)
{
BYTE Mask;

  while(Size1D>0)
    {
    *Dest = 0;
    for(Mask=0x80; Mask!=0; Mask>>=1)
      {
      if(*Src++>=0x8000) *Dest |= Mask;
      if(--Size1D<=0) return;
      }
    Dest++;
    }
}

void Conv16_8(BYTE *Dest, const WORD *Src, unsigned Size1D)
{
  while(Size1D-->0)
    {
    *Dest++ = *Src++ >> 8;
    }
}

void Conv16_32(DWORD *Dest, const WORD *Src, unsigned Size1D)
{
  while(Size1D-->0)
    {
    *Dest++ = *Src++ * 0x10001;
    }
}

void Conv32_8(BYTE *Dest, const DWORD *Src, unsigned Size1D)
{
  while(Size1D-->0)
    {
    *Dest++ = *Src++ >> 24;
    }
}

void Conv32_16(WORD *Dest, const DWORD *Src, unsigned Size1D)
{
  while(Size1D-->0)
    {
    *Dest++ = *Src++ >> 16;
    }
}



unsigned NearAvailPlanes(unsigned n)
{
  if(n<1) return(n);
  if(n<=1) return(1);
  if(n<=2) return(2);
  if(n<=4) return(4);
  if(n<=8) return(8);
  if(n<=16) return(16);
  if(n<=24) return(24);
  if(n<=32) return(32);
  if(n<=64) return(64);
  return(n);
}


void SetValue1(BYTE *b, unsigned x, DWORD NewValue)
{
 b+= x >> 3;
 if(NewValue==0) *b = *b & ~(0x80 >>(x & 0x07));
	    else *b = *b |  (0x80 >>(x & 0x07));
}


DWORD GetValue1(const BYTE *b, unsigned x)
{
 if(b==NULL) return(0);
 b+= x >> 3;
 if((*b & (0x80 >>(x & 0x07))) != 0) return(1);
 return(0);
}


void SetValue2(BYTE *b, unsigned x, DWORD NewValue)
{
BYTE v;

 v = NewValue;
 if(NewValue>3) v=3;
 b+= x >> 2;
 switch(x & 3)
   {
   case 0: v=v << 6; *b=*b & 0x3F;	break;
   case 1: v=v << 4; *b=*b & 0xCF;	break;
   case	2: v=v << 2; *b=*b & 0xF3;	break;
   case	3: *b=*b & 0xFC;
   }
 *b=*b | v;
}


DWORD GetValue2(const BYTE *b, unsigned x)
{
 if(b==NULL) return 0;
 b+= x >> 2;
 switch(x & 3)
   {
   case 0:return( (*b >> 6)&3 );
   case 1:return( (*b >> 4)&3 );
   case	2:return( (*b >> 2)&3 );
   case	3:return( *b & 3 );
   }
return 0;
}


/* ------------- 4 bit planes ------------- */

void SetValue4(BYTE *b, unsigned x, DWORD NewValue)
{
 if(b==NULL) return;
 b+= x >> 1;
 if (x & 1) *b=(*b & 0xF0) | (NewValue & 0x0F);
       else *b=(*b & 0x0F) | ((NewValue << 4) & 0xF0);
}


DWORD GetValue4(const BYTE *b, unsigned x)
{
 if(b==NULL) return 0;
 b+= x >> 1;
 if(x & 1) return(*b & 0x0F);
      else return(*b >> 4);
}


/* -------------- 8 bit planes ---------------- */


void SetValue8(BYTE *b, unsigned x, DWORD NewValue)
{
 if(b==NULL) return;
 if(NewValue>0xFF) b[x] = 0xFF;
              else b[x] = NewValue;
}


DWORD GetValue8(const BYTE *b, unsigned x)
{
 if(b==NULL) return 0;
 return b[x]; 
}


/* ------------- 16 bit planes -------------- */

void SetValue16(BYTE *b, unsigned x, DWORD NewValue)
{
 if(b==NULL) return;
 ((WORD *)b)[x] = NewValue; 
}


DWORD GetValue16(const BYTE *b, unsigned x)
{
 if(b==NULL) return 0;
 return ((WORD *)b)[x]; 
}


/* ------------ 24 bit planes Gray ------------ */

/*
void Raster1D_24Bit::SetValue1D(int x, DWORD NewValue)
{
BYTE *BuffPos;

 if(x>=Size1D) return;
 BuffPos=((BYTE *)Data1D)+(3*x);
 *BuffPos++=NewValue & 0xFF;
 NewValue >>= 8;
 *BuffPos++=NewValue & 0xFF;
 NewValue >>= 8;
 *BuffPos=NewValue & 0xFF;
}


DWORD Raster1D_24Bit::GetValue1D(int x) const
{
BYTE *b;

 if(x>=Size1D || Data1D==NULL) return(0);
 b = (BYTE *)Data1D + 3*x;
 return((DWORD)*b | (DWORD)b[1]<<8 | (DWORD)b[2]<<16);
}
*/
