//	This source and File 16-bit bitparity patterns method apply to GNU General Public License. 
//			Copyright (C) 2015  Jasenko Dzinleski 

//	This source applies to the GNU General Public License as
//	published by the Free Software Foundation 
//	and can not be used, copied, sold, redistributed or 
//	used in any other way but only by written permission by Jasenko Dzinleski . 
//	Copyright (C) from 2001 - 2013 and later by Jasenko Dzinleski 

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

//	You should have received a copy of the GNU General Public License along
//	with this program; if not, write to the Free Software Foundation, Inc.,
//	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

//
//		16-bit bitparity patterns
//		written by Dzinleski Jasenko March , 2015
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

FILE		*f1,*f2;

char		infn[256];
char		ofn[256]="_cbp.mar";

int		b16o,b16e;


char		sqa[0xffff][6];
int		sqai=0,sqai_;

int		sqa__[0xffff][4];
int		sqa_[2*2*8*16];

int		ba16_[256][256][1+4];int ba16_i=0; 

int main(int argc,char *argv[])
{

int	a,b,c,d,e;
int	i,j,k,l,m=-1;

int	b1_,b2_,b3_;
int	b1,b2,b3;
int	d1,d2,d3,d4;
int	d1_,d2_,d3_;
int	mc=0,unmc=0;


	printf("\n\n\t16-bit bitparity patterns\n");
	printf("\twritten by Dzinleski Jasenko March , 2015\n\n");

	if(argv[1]==NULL){return(0);}else{
		strcpy(infn,argv[1]);f1=fopen(infn,"rb");
		if(f1==NULL){printf("No file...\n");return(0);}else{fclose(f1);}
	}

	for(i=0;i<0xffff;++i){sqa__[i][0]=0;sqa__[i][1]=0;sqa__[i][2]=0;sqa__[i][3]=0;}

	b16o=0;
	b16o|=1<<0;
	b16o|=1<<2;
	b16o|=1<<4;
	b16o|=1<<6;
	b16o|=1<<8;
	b16o|=1<10;
	b16o|=1<<12;
	b16o|=1<<14;

	b16e=0;
	b16e|=1<<1;
	b16e|=1<<3;
	b16e|=1<<5;
	b16e|=1<<7;
	b16e|=1<<9;
	b16e|=1<<11;
	b16e|=1<<13;
	b16e|=1<<15;

	f1=fopen(infn,"rb");
   
	b1_=(getc(f1)<<8)|getc(f1);
	b2_=(getc(f1)<<8)|getc(f1);
	b3_=(getc(f1)<<8)|getc(f1);
 
	while(!feof(f1))
	{

		if(sqai==0)
		{
			sqa[sqai][0]=(b1_&0xff00)>>8;
			sqa[sqai][1]=(b1_&0x00ff)>>0;
			sqa[sqai][2]=(b2_&0xff00)>>8;
			sqa[sqai][3]=(b2_&0x00ff)>>0;
			sqa[sqai][4]=(b3_&0xff00)>>8;
			sqa[sqai][5]=(b3_&0x00ff)>>0;
			sqai_=sqai;
			++sqai;
		}else{
			for(i=0;i<sqai;++i)
			{
				if
				(
				sqa[i][0]==(b1_&0xff00)>>8&&
				sqa[i][1]==(b1_&0x00ff)>>0&&
				sqa[i][2]==(b2_&0xff00)>>8&&
				sqa[i][3]==(b2_&0x00ff)>>0&&
				sqa[i][4]==(b3_&0xff00)>>8&&
				sqa[i][5]==(b3_&0x00ff)>>0
				){sqai_=i;break;}
			}
			if(i==sqai)
			{
				sqa[sqai][0]=(b1_&0xff00)>>8;
				sqa[sqai][1]=(b1_&0x00ff)>>0;
				sqa[sqai][2]=(b2_&0xff00)>>8;
				sqa[sqai][3]=(b2_&0x00ff)>>0;
				sqa[sqai][4]=(b3_&0xff00)>>8;
				sqa[sqai][5]=(b3_&0x00ff)>>0;
				sqai_=sqai;
				++sqai;
			}
		}

		for(i=0;i<256;++i){for(j=0;j<256;++j){ba16_[i][j][0]=-1;ba16_[i][j][1]=0;ba16_[i][j][2]=0;ba16_[i][j][3]=0;ba16_[i][j][4]=0;}}
		sqa_[0]=1;

        	i=0;
        	while(i<8)
        	{
			j=0;
            		while(j<16)
            		{
	
				b1=b1_<<i;
				b2=b2_<<i;
				b3=b3_<<i;
	
				d1=((((b1&b16e)>>i)^(b2&b16o))|((b1&b16e)^((b2&b16o)<<j)));	
				d2=((((b1&b16e)>>i)^(b3&b16o))|((b1&b16e)^((b3&b16o)<<j)));

				if((d1>0)&&(d2>0))
				{
				sqa_[sqa_[0]]=d1;++sqa_[0];
				sqa_[sqa_[0]]=d2;++sqa_[0];
				if(ba16_[(d1&0xff00)>>8][d1&0x00ff][0]==-1)
				{
					ba16_[(d1&0xff00)>>8][d1&0x00ff][0]=ba16_i;++ba16_i;
					ba16_[(d1&0xff00)>>8][d1&0x00ff][1]=1;
				}else{++ba16_[(d1&0xff00)>>8][d1&0x00ff][1];}
				
				if(ba16_[(d2&0xff00)>>8][d2&0x00ff][0]==-1)
				{
					ba16_[(d2&0xff00)>>8][d2&0x00ff][0]=ba16_i;++ba16_i;
					ba16_[(d2&0xff00)>>8][d2&0x00ff][2]=1;
				}else{++ba16_[(d2&0xff00)>>8][d2&0x00ff][2];}

				}

				d1=((((b2&b16e)>>i)^(b1&b16o))|((b2&b16e)^((b1&b16o)<<j)));	
				d2=((((b2&b16e)>>i)^(b3&b16o))|((b2&b16e)^((b3&b16o)<<j)));

				if((d1>0)&&(d2>0))
				{
				sqa_[sqa_[0]]=d1;++sqa_[0];
				sqa_[sqa_[0]]=d2;++sqa_[0];
				if(ba16_[(d1&0xff00)>>8][d1&0x00ff][0]==-1)
				{
					ba16_[(d1&0xff00)>>8][d1&0x00ff][0]=ba16_i;++ba16_i;
					ba16_[(d1&0xff00)>>8][d1&0x00ff][3]=1;
				}else{++ba16_[(d1&0xff00)>>8][d1&0x00ff][3];}
				
				if(ba16_[(d2&0xff00)>>8][d2&0x00ff][0]==-1)
				{
					ba16_[(d2&0xff00)>>8][d2&0x00ff][0]=ba16_i;++ba16_i;
					ba16_[(d2&0xff00)>>8][d2&0x00ff][4]=1;
				}else{++ba16_[(d2&0xff00)>>8][d2&0x00ff][4];}
				}

				++j; 
			}
			++i;
		}

		j=0;k=0;
        	for(i=1;i<sqa_[0];++i)
		{
		if(ba16_[(sqa_[i]&0xff00)>>8][sqa_[i]&0x00ff][1]==1){++i;if(ba16_[(sqa_[i]&0xff00)>>8][sqa_[i]&0x00ff][2]==1){++j;}}else{++i;}
		++i;
		if(ba16_[(sqa_[i]&0xff00)>>8][sqa_[i]&0x00ff][3]==1){++i;if(ba16_[(sqa_[i]&0xff00)>>8][sqa_[i]&0x00ff][4]==1){++k;}}else{++i;}
		}
		if (j>=1){++sqa__[sqai_][0];sqa__[sqai_][1]=j;if(m==-1){m=j;}else{if(m<j){m=j;}}}if (k>=1){++sqa__[sqai_][2];sqa__[sqai_][3]=k;if(m==-1){m=k;}else{if(m<k){m=k;}}}

	    	b1_=b2_;
	    	b2_=b3_;
	    	b3_=(getc(f1)<<8)|getc(f1);

	}
	fclose(f1);

	printf("\tin : %s\n",infn);	
	j=strlen(infn);for(i=0;i<strlen(ofn);++i){infn[j]=ofn[i];++j;}
	printf("\tout: %s\n",infn);

	f2=fopen(infn,"w");
	for(i=0;i<0xffff;++i)
	{
		if((sqa__[i][0]>=1)||(sqa__[i][2]>=1))
		{
		if(sqa__[i][0]>=1){
		fprintf(f2,"%c%c%c%c%c%c\t%d\t%e\n",sqa[i][0],sqa[i][1],sqa[i][2],sqa[i][3],sqa[i][4],sqa[i][5],sqa__[i][0],((double)sqa__[i][1]/(double)m));
		}else{
		if(sqa__[i][2]>=1){
		fprintf(f2,"%c%c%c%c%c%c\t%d\t%e\n",sqa[i][0],sqa[i][1],sqa[i][2],sqa[i][3],sqa[i][4],sqa[i][5],sqa__[i][2],((double)sqa__[i][3]/(double)m));
		}}
		}
	}

	fclose(f2);


    return(0);

}