www.pudn.com > sfalic-03-src.rar.rar > cdfpred.c


#include "cdftypes.h" 
#include "cdfpred.h" 
#include "bppmask.h" 
#include "assert.h" 
#include  
 
 
/* zwroc mediane */ 
#define MEDIAN(A, B, C)								\ 
		( (B)>=(C) ?								\ 
		  (C)>=(A) ? (C) : (A)>=(B) ? (B) : (A) :	\ 
		  (C)<=(A) ? (C) : (A)<=(B) ? (B) : (A)		\ 
		)											\ 
 
 
/* automatyczne tlumaczenie rozkladu U na L, wypelniane przez decorelateinit() dla 8bpp i mniej*/ 
static unsigned int xlatU2L[256];  
 
 
/* kompresja kodu zrodlowego */ 
#define PIXEL_A ((unsigned int)currow[i-1]) 
#define PIXEL_B ((unsigned int)prevrow[i]) 
#define PIXEL_C ((unsigned int)prevrow[i-1]) 
 
 
/* pomocnicze do dekorelowania pojedynczych pikseli */ 
/*  0  */ 
static void decorelate_onepixel_0(const PIXEL * const currow, PIXEL * const decorelatedrow,  
		    					  const unsigned int pixelbitmask) 
{ 
	const unsigned int s=*currow;  
		 
	if (s<=(pixelbitmask>>1))  
		*decorelatedrow=s<<1;  
	else  
		*decorelatedrow=((pixelbitmask-s)<<1)+1;  
} 
 
 
static void decorelate_onepixel_0_8bpp(const BYTE * const currow, BYTE * const decorelatedrow,  
		    						   const unsigned int pixelbitmask) 
{ 
	const unsigned int s=*currow;  
		 
	*decorelatedrow=xlatU2L[s]; 
} 
 
 
static void decorelate_onepixel_2(const PIXEL * const prevrow, const PIXEL * const currow,  
								  PIXEL * const decorelatedrow, const unsigned int pixelbitmask) 
{ 
	const unsigned int s=(unsigned)( (int)(*currow) - (int)(*prevrow) ) & pixelbitmask;  
		 
	if (s<=(pixelbitmask>>1))  
		*decorelatedrow=s<<1;  
	else  
		*decorelatedrow=((pixelbitmask-s)<<1)+1;  
} 
 
 
static void decorelate_onepixel_2_8bpp(const BYTE * const prevrow, const BYTE * const currow,  
									   BYTE * const decorelatedrow, const unsigned int pixelbitmask) 
{ 
	const unsigned int s=(unsigned)( (int)(*currow) - (int)(*prevrow) ) & pixelbitmask;  
		 
	*decorelatedrow=xlatU2L[s]; 
} 
 
 
/* dekorelowanie calych wierszy */ 
 
 
/*  0  */ 
static void decorelate_0(const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	for (i=0; i>1; 
	unsigned int i; 
 
	for (i=0; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_0(currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_0_8bpp(currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1; 
	unsigned int i; 
 
	for (i=0; i>1; 
	unsigned int i; 
 
	for (i=0; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; ipixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			if (s<=pixelbitmaskshr)  
				decorelatedrow[i]=s<<1;  
			else  
				decorelatedrow[i]=((pixelbitmask-s)<<1)+1;  
		} 
	} 
} 
 
 
static void decorelate_4_8bpp(const BYTE prevrow[], const BYTE currow[], const unsigned int rowlen, const int bpp, 
						      BYTE decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; ipixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			decorelatedrow[i]=xlatU2L[s]; 
		} 
	} 
} 
 
 
/*  a+(b-c)/2  */ 
static void decorelate_5(const PIXEL prevrow[], const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ) ; 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			if (s<=pixelbitmaskshr)  
				decorelatedrow[i]=s<<1;  
			else  
				decorelatedrow[i]=((pixelbitmask-s)<<1)+1;  
		} 
	} 
} 
 
 
static void decorelate_5_8bpp(const BYTE prevrow[], const BYTE currow[], const unsigned int rowlen, const int bpp, 
							  BYTE decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ) ; 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			decorelatedrow[i]=xlatU2L[s]; 
		} 
	} 
} 
 
 
/*  b+(a-c)/2  */ 
static void decorelate_6(const PIXEL prevrow[], const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ); 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			if (s<=pixelbitmaskshr)  
				decorelatedrow[i]=s<<1;  
			else  
				decorelatedrow[i]=((pixelbitmask-s)<<1)+1;  
		} 
	} 
} 
 
 
static void decorelate_6_8bpp(const BYTE prevrow[], const BYTE currow[], const unsigned int rowlen, const int bpp, 
							  BYTE decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ); 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			decorelatedrow[i]=xlatU2L[s]; 
		} 
	} 
} 
 
 
/*  (a+b)/2  */ 
static void decorelate_7(const PIXEL prevrow[], const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ) & pixelbitmask;  
		 
		if (s<=pixelbitmaskshr)  
			decorelatedrow[i]=s<<1;  
		else  
			decorelatedrow[i]=((pixelbitmask-s)<<1)+1;  
	} 
} 
 
 
static void decorelate_7_8bpp(const BYTE prevrow[], const BYTE currow[], const unsigned int rowlen, const int bpp, 
							  BYTE decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1) ) & pixelbitmask;  
		 
		decorelatedrow[i]=xlatU2L[s]; 
	} 
} 
 
 
/*  .75a+.75b-.5c  */ 
static void decorelate_8(const PIXEL prevrow[], const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>2  ; 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			if (s<=pixelbitmaskshr)  
				decorelatedrow[i]=s<<1;  
			else  
				decorelatedrow[i]=((pixelbitmask-s)<<1)+1;  
		} 
	} 
} 
 
 
static void decorelate_8_8bpp(const BYTE prevrow[], const BYTE currow[], const unsigned int rowlen, const int bpp, 
							  BYTE decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>2  ; 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		{ 
			const unsigned int s=(unsigned)( (int)currow[i] - p ) & pixelbitmask;  
			 
			decorelatedrow[i]=xlatU2L[s]; 
		} 
	} 
} 
 
 
/*  median(a, b, c)  */ 
static void decorelate_9(const PIXEL prevrow[], const PIXEL currow[], const unsigned int rowlen, const int bpp, 
						 PIXEL decorelatedrow[]) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i>1; 
	unsigned int i; 
 
	assert(rowlen);	// osobne wywolanie dla pierwszego piksela, bo on nie ma lewego sasiada i komplikowalby ponizsza petle - nie daloby sie zrobic unrolling 
	decorelate_onepixel_2_8bpp(prevrow, currow, decorelatedrow, pixelbitmask); 
	for (i=1; i=MINpred); 
	assert(rowlen>0); 
	assert(row>=0); 
 
	if (pred==-1) /* copy */ 
	{ 
		memcpy(decorelatedrow, currow, sizeof(PIXEL)*rowlen); 
		return; 
	} 
 
	if (row==0 && pred!=0) /* dla wiersza zerowego wszystkie predyktory, oprocz 0, przechodza w 1 */ 
		pred=1; 
 
	switch (pred) 
	{ 
	case 0: decorelate_0(currow, rowlen, bpp, decorelatedrow); return; 
	case 1: decorelate_1(currow, rowlen, bpp, decorelatedrow); return; 
	case 2: decorelate_2(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 3: decorelate_3(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 4: decorelate_4(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 5: decorelate_5(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 6: decorelate_6(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 7: decorelate_7(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 8: decorelate_8(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 9: decorelate_9(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	default: assert(0); 
	} 
} 
 
 
void decorelaterow8bpp(const BYTE *prevrow, const BYTE *currow, int row, int rowlen, int bpp, 
				       int pred, BYTE *decorelatedrow) 
{ 
	assert(bpp<=8); 
	assert(pred<=MAXpred && pred>=MINpred); 
	assert(rowlen>0); 
	assert(row>=0); 
 
	if (pred==-1) /* copy */ 
	{ 
		memcpy(decorelatedrow, currow, rowlen); 
		return; 
	} 
 
	if (row==0 && pred!=0) /* dla wiersza zerowego wszystkie predyktory, oprocz 0, przechodza w 1 */ 
		pred=1; 
 
	switch (pred) 
	{ 
	case 0: decorelate_0_8bpp(currow, rowlen, bpp, decorelatedrow); return; 
	case 1: decorelate_1_8bpp(currow, rowlen, bpp, decorelatedrow); return; 
	case 2: decorelate_2_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 3: decorelate_3_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 4: decorelate_4_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 5: decorelate_5_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 6: decorelate_6_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 7: decorelate_7_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 8: decorelate_8_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	case 9: decorelate_9_8bpp(prevrow, currow, rowlen, bpp, decorelatedrow); return; 
	default: assert(0); 
	} 
} 
 
 
void decorelateinit8bpp(int bpp) 
{ 
	const unsigned int pixelbitmask=bppmask[bpp]; 
	const unsigned int pixelbitmaskshr=pixelbitmask>>1; 
	unsigned int s; 
 
	assert(bpp<=8); 
 
	for (s=0; s<=pixelbitmask; s++) 
		if (s<=pixelbitmaskshr)  
			xlatU2L[s]=s<<1;  
		else  
			xlatU2L[s]=((pixelbitmask-s)<<1)+1;  
} 
 
 
 
static PIXEL xlatL2U(register PIXEL s, register const unsigned int pixelbitmask) 
{ 
	if (s & 0x01) 
		return pixelbitmask-(s>>1); 
	return s>>1; 
} 
 
 
/* do zoptymalizowania po zoptymalizowaniu decorelate_* i sprawdzeniu, ze nadal odtwarzalne przez ta funkcje */ 
void corelaterow(const PIXEL *prevrow, PIXEL *currow, int row, int rowlen, int bpp, 
				   int pred, const PIXEL *decorelatedrow) 
{ 
	int a, /*b,*/ c; /* piksele L, G, LG */ 
	    /*s,*/       /* symbol residuum */ 
	    /*p,*/	/* wartosc predyktora */ 
		/*x;*/  /* odtworzony piksel */ 
	unsigned int pixelbitmask; 
 
	assert(pred<=MAXpred && pred>=MINpred); 
	assert(rowlen>0); 
	assert(row>=0); 
 
	if (pred==-1) /* copy */ 
	{ 
		while(rowlen--)	 
			*currow++=*decorelatedrow++; 
		return; 
	} 
 
	if (row==0 && pred!=0) /* dla wiersza zerowego wszystkie predyktory, oprocz 0, przechodza w 1 */ 
		pred=1; 
 
	pixelbitmask=bppmask[bpp]; 
 
	if (pred>1)  
		a=c=*prevrow;      /* 0 i 1 nie wyk. prev_row */ 
	else  
		a=0; 
 
	while (rowlen--) 
	{ 
		const int b=*prevrow++; 
		int p, x; 
 
		const int s=xlatL2U(*decorelatedrow++, pixelbitmask); 
 
		switch (pred) 
		{ 
		case 0: p=0; break; 
		case 1: p=a; break; 
		case 2: p=b; break; 
		case 3: p=c; break; 
		case 4: p=a+b-c; break; 
		case 5: p=(2*a+b-c)/2; break;  /* a+(b-c)/2 bylo zle !!! */ 
		case 6: p=(2*b+a-c)/2; break;  /* b+(a-c)/2 bylo zle !!! */ 
		case 7: p=(a+b)/2; break; 
		case 8: p=(3*a+3*b-2*c)/4; break; 
		case 9: p=MEDIAN(a, b, c); break; 
		default: assert(0); 
		} 
 
		if (p<0) 
			p=0; 
		else if ((unsigned)p>pixelbitmask) 
			p=pixelbitmask; 
 
		x=(s+p) & pixelbitmask; 
		*currow++=(PIXEL)x; 
		a=x; 
		c=b; 
	} 
}