/************************************************************
**
** Application: Snapper
**
** Title:       c.im
**
*************************************************************/

/*
*
* Copyright (c) 2017, David Pilling and Chris Johnson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the copyright holder nor the names of their
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


/************************************************************/


/* Include files */

#include "h.includes"

/* from TaskLib */
#include "TaskLib:wimpt.h"
#include "TaskLib:flex.h"
#include "TaskLib:transform.h"
#include "TaskLib:alloc.h"
#include "TaskLib:fsx.h"
#include "TaskLib:etc.h"



/* from application */
#include "xdeb.h"
#include "str.h"
#include "main.h"
#include "im.h"


/*****************************************************************************/
/* return pointers to row data */

os_error * imfind1r(imagestr * ip,int y,int ** data)
{
 *data=ip->data+y*ip->wwidth;
 return(NULL);
}



/************************************************************/

os_error * imfind1w(imagestr * ip,int y,int ** data)
{
 *data=ip->data+y*ip->wwidth;
 return(NULL);
}



#if 0

/*****************************************************************************/
os_error * imfind2rr(imagestr * ip1,int y1,int ** data1,
                     imagestr * ip2,int y2,int ** data2)
{
 *data1=ip1->data+y1*ip1->wwidth;
 *data2=ip2->data+y2*ip2->wwidth;
 return(NULL);
}


/************************************************************/

os_error * imfind2ww(imagestr * ip1,int y1,int ** data1,
                     imagestr * ip2,int y2,int ** data2)
{
 *data1=ip1->data+y1*ip1->wwidth;
 *data2=ip2->data+y2*ip2->wwidth;
 return(NULL);
}

#endif


/* throw away image */

/************************************************************/

os_error * imtrash(imagestr ** imp)
{
 os_error * err;
 imagestr * ip;

 err=NULL;

 ip=*imp;
 if(ip)
 {

  err=sfree((flex_ptr)imp);
 }

 return(err);
}





/************************************************************/

os_error * ximtrash(ximagestr ** ximp)
{
 os_error * err;

          err=imtrash(&((*ximp)->sim[IM]));
 if(!err) err=imtrash(&((*ximp)->sim[AL]));
 if(!err) err=sfree((flex_ptr)ximp);

 return(err);
}




/************************************************************/

/* create a new image */

/* bpp supports 1,2,4,8,24,32 */

os_error * imnew(int xpix,int ypix,int bpp,imagestr ** imp)
{
 os_error   * err;
 int          bitwidth;
 int          size;
 imagestr   * ip;



 bitwidth=(xpix*bpp+31)&(~31);
 bitwidth/=8;
 size=bitwidth*ypix; /* bytes */


 err=salloc((flex_ptr)imp,sizeof(imagestr)+size);

 if(!err)
 {
  ip=*imp;
  ip->wwidth=bitwidth/4; /* words */
  ip->xpix=xpix;
  ip->ypix=ypix;
  ip->bpp=bpp;
 }

 return(err);
}





/************************************************************/

void  shiftline(int * wdata,int xpix,int bpp,int rshift)
{
 unsigned int w;
 unsigned int r;
 int          x;
 int        * rdata;
 int          wshift;

 rdata=wdata;
 r=*rdata++;
 w=0;
 wshift=0;

 for(x=0;x<xpix;x++)
 {
  w|=(r>>rshift)<<wshift;
  rshift+=bpp;
  if(rshift>=32)
  {
   rshift=0;
   r=*rdata++;
  }
  wshift+=bpp;
  if(wshift>=32)
  {
   *wdata++=w;
   wshift=0;
   w=0;
  }
 }
 if(wshift) *wdata=w;
}






/************************************************************/

os_error * ximnew2(int xpix,int ypix,int bpp,int mpp,ximagestr ** imp)
{
 os_error * err;
 ximagestr   * ip;


 err=salloc((flex_ptr)imp, sizeof(ximagestr));
 if(!err)
 {
   err=imnew(xpix,ypix,bpp,&((*imp)->sim[IM]));
   if(!err)
   {
      if (mpp>0)
      {
        err=imnew(xpix,ypix,mpp,&((*imp)->sim[AL]));
      }
      else
      {
        ip=*imp;
        ip->sim[AL] = NULL;
      }
   }
 }

 return(err);
}



/************************************************************/

int greypal(int * pal,int ncolours)
{
 int i;
 int r;
 int g;
 int b;

 for(i=0;i<ncolours;i++)
 {
  r=(pal[i]>>8) & 0xFF;
  g=(pal[i]>>16) & 0xFF;
  b=(pal[i]>>24) & 0xFF;
  if(r!=g || g!=b) return(0);
 }
 return(1);
}


/************************************************************/

int imgrey(imagestr * image)
{
 if(image->bpp>8) return(0);
 return(greypal(image->ipal.word,image->ipal.ncolours));
}





/************************************************************/

void imsetgreypal(imagestr * image,int bpp)
{
 int i;
 int palw;

 image->ipal.ncolours=1<<bpp;

 switch(image->bpp)
 {
  case 8:
         for(i=0;i<256;i++)
         {
          palw=(i<<24)|(i<<16)|(i<<8);
          image->ipal.word[i]=palw;
         }
         break;

  case 1:
         image->ipal.word[0]=0;
         image->ipal.word[1]=0xFFFFFF00;
         break;

  case 2:
         image->ipal.word[0]=0;
         image->ipal.word[1]=0x55555500;
         image->ipal.word[2]=0xAAAAAA00;
         image->ipal.word[3]=0xFFFFFF00;
         break;

  case 4:
         for(i=0;i<16;i++)
         {
          palw=(i<<28)|(i<<24)|(i<<20)|(i<<16)|(i<<12)|(i<<8);
          image->ipal.word[i]=palw;
         }
         break;
 }
}



/************************************************************/

#if 0
int imbpp(int colours)
{
 int bpp;

 bpp=0;

 while(colours/=2) bpp++;

 while(1)
 {
  if(bpp==1 || bpp==2 || bpp==4 || bpp==8 || bpp==24) break;
  else
  if(bpp>=32)
  {
   bpp=32;
   break;
  }
  else  bpp++;
 }
 return(bpp);
}


#endif

/************************************************************/

char bitrev[256]=
{
0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240,8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248,4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244,12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252,2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242,10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250,6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246,14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254,1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241,9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249,5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245,13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253,3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243,11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251,7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247,15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255
};


char nybrev[256]=
{
0,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,1,17,33,49,65,81,97,113,129,145,161,177,193,209,225,241,2,18,34,50,66,82,98,114,130,146,162,178,194,210,226,242,3,19,35,51,67,83,99,115,131,147,163,179,195,211,227,243,4,20,36,52,68,84,100,116,132,148,164,180,196,212,228,244,5,21,37,53,69,85,101,117,133,149,165,181,197,213,229,245,6,22,38,54,70,86,102,118,134,150,166,182,198,214,230,246,7,23,39,55,71,87,103,119,135,151,167,183,199,215,231,247,8,24,40,56,72,88,104,120,136,152,168,184,200,216,232,248,9,25,41,57,73,89,105,121,137,153,169,185,201,217,233,249,10,26,42,58,74,90,106,122,138,154,170,186,202,218,234,250,11,27,43,59,75,91,107,123,139,155,171,187,203,219,235,251,12,28,44,60,76,92,108,124,140,156,172,188,204,220,236,252,13,29,45,61,77,93,109,125,141,157,173,189,205,221,237,253,14,30,46,62,78,94,110,126,142,158,174,190,206,222,238,254,15,31,47,63,79,95,111,127,143,159,175,191,207,223,239,255
};


char dbitrev[256]=
{
0,64,128,192,16,80,144,208,32,96,160,224,48,112,176,240,4,68,132,196,20,84,148,212,36,100,164,228,52,116,180,244,8,72,136,200,24,88,152,216,40,104,168,232,56,120,184,248,12,76,140,204,28,92,156,220,44,108,172,236,60,124,188,252,1,65,129,193,17,81,145,209,33,97,161,225,49,113,177,241,5,69,133,197,21,85,149,213,37,101,165,229,53,117,181,245,9,73,137,201,25,89,153,217,41,105,169,233,57,121,185,249,13,77,141,205,29,93,157,221,45,109,173,237,61,125,189,253,2,66,130,194,18,82,146,210,34,98,162,226,50,114,178,242,6,70,134,198,22,86,150,214,38,102,166,230,54,118,182,246,10,74,138,202,26,90,154,218,42,106,170,234,58,122,186,250,14,78,142,206,30,94,158,222,46,110,174,238,62,126,190,254,3,67,131,195,19,83,147,211,35,99,163,227,51,115,179,243,7,71,135,199,23,87,151,215,39,103,167,231,55,119,183,247,11,75,139,203,27,91,155,219,43,107,171,235,59,123,187,251,15,79,143,207,31,95,159,223,47,111,175,239,63,127,191,255
};





/*************  End of c.im  ***********************/


