⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdfpred.c

📁 一个简单而且快速的无损压缩算法。包含源代码实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	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<rowlen; i++)
	{
		int p=( (int)PIXEL_B + (((int)PIXEL_A-(int)PIXEL_C)>>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<rowlen; i++)
	{
		int p=( (int)PIXEL_B + (((int)PIXEL_A-(int)PIXEL_C)>>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<rowlen; i++)
	{
		const unsigned int s=(unsigned)( (int)currow[i] - (int)((PIXEL_A+PIXEL_B)>>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<rowlen; i++)
	{
		const unsigned int s=(unsigned)( (int)currow[i] - (int)((PIXEL_A+PIXEL_B)>>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<rowlen; i++)
	{
		int p=( (int)(3*(PIXEL_A+PIXEL_B)) - (int)(PIXEL_C<<1) ) >>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<rowlen; i++)
	{
		int p=( (int)(3*(PIXEL_A+PIXEL_B)) - (int)(PIXEL_C<<1) ) >>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<rowlen; i++)
	{
		const unsigned int s=(unsigned)( (int)currow[i] - (int)(MEDIAN(PIXEL_A, PIXEL_B, PIXEL_C))) & pixelbitmask; 
		
		if (s<=pixelbitmaskshr) 
			decorelatedrow[i]=s<<1; 
		else 
			decorelatedrow[i]=((pixelbitmask-s)<<1)+1; 
	}
}


static void decorelate_9_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<rowlen; i++)
	{
		const unsigned int s=(unsigned)( (int)currow[i] - (int)(MEDIAN(PIXEL_A, PIXEL_B, PIXEL_C))) & pixelbitmask; 
		
		decorelatedrow[i]=xlatU2L[s];
	}
}




void decorelaterow(const PIXEL *prevrow, const PIXEL *currow, int row, int rowlen, int bpp,
				   int pred, PIXEL *decorelatedrow)
{
	assert(pred<=MAXpred && pred>=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;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -