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

📄 open.c

📁 从sourceforge下的图像压缩源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}
	else
		return(1); // 1 = nepodporovana metoda

	ret = compress(&bstrm, (char *)&(methd), sizeof(uint8)*1, descriptor);
	if(ret)
	{
		eprintf("Internal error/methd!");
		return(ret);
	}

	// pomocne pole
	TYBlock *yuv;
	TYBlock tran;

	TLinBlock linY;
	TLinBlock linU;
	TLinBlock linV;
	
	// pro kazdy ctverecek
	for(uint32 _w=0; _w<w8/LENGTH; _w++) // radky
	{
		for(uint32 _h=0; _h<h8/LENGTH; _h++) // cely sloupec
		{
			// prevod barev
			yuv = rgb2yuv(framebuffer,_w*LENGTH,_h*LENGTH);

			// transformace
			f_t(yuv->y,tran.y);
			f_t(yuv->u,tran.u);
			f_t(yuv->v,tran.v);

			// kvantizace+linearizace+diff. DC koef.
			quant(tran.y,qm_y,&linY);
			quant(tran.u,qm_c,&linU);
			quant(tran.v,qm_c,&linV);

			// zapis do streamu (bzip2)
			ret = compress(&bstrm, (char *)&(linY.lin), LENGTH*LENGTH*sizeof(uint16), descriptor);
			if(ret)
			{
				eprintf("Internal error/5!");
				return(ret);
			}
			ret = compress(&bstrm, (char *)&(linU.lin), LENGTH*LENGTH*sizeof(uint16), descriptor);
			if(ret)
			{
				eprintf("Internal error/6!");
				return(ret);
			}
			ret = compress(&bstrm, (char *)&(linV.lin), LENGTH*LENGTH*sizeof(uint16), descriptor);
			if(ret)
			{
				eprintf("Internal error/7!");
				return(ret);
			}
		}
	}

	// ukoncit kompresi
	ret = compress_flush(&bstrm, descriptor);
	if(ret)
	{
		eprintf("Internal error/4!");
		return(ret);
	}

	BZ2_bzCompressEnd(&bstrm);

	dprintf("OpenCompress() exit\n");
	return(0);
}

/***
 * dekomprimuje pozadovany blok dat (dle velikosti) z BZ2 streamu
 */ 
int decompress(bz_stream *bstrm, char *addr, unsigned size)
{
	bstrm->avail_out = size;
	bstrm->next_out = (char *)addr;
	int ret = BZ2_bzDecompress(bstrm);
	if(ret != BZ_STREAM_END && ret != BZ_OK)
	{
		eprintf("BZ2_bzDecompress() fails!");
		return(3);
	}
	if( 0 != bstrm->avail_out )
	{
		eprintf("BZ2_bzDecompress() size error!");
		return(3);
	}	
	return(0);
}

/***
 * delinearizuje/dekvantizuje blok koeficientu dle QM
 */ 
void dequant(double m[LENGTH][LENGTH], TQuantMat qm, TLinBlock *lin)
{	
	for(int ib=0; ib<64; ib++)
	{
		int j = zigzag[ib];
		int x = j % 8;
		int y = j / 8;
		// dekodovat signed z unsigned
		int16 tmp = (lin->lin[ib]%2==0)?(((int16)lin->lin[ib])/2):((((int16)lin->lin[ib])+1)/(-2));
		// vynasobit QM
		m[y][x] = (double)tmp*qm[y][x];
	}
	return;
}

/***
 * prevede blok 8x8 YCbCr na RGB do FB (nezapisuje za okraj)
 */ 
void yuv2rgb(PFrameBuff fbuff, uint32 x, uint32 y, TYBlock *yuv)
{
	uint32 w = fbuff->w;
	uint32 h = fbuff->h;
	
	for(uint32 _y=0; _y<LENGTH; _y++)
		for(uint32 _x=0; _x<LENGTH; _x++)
		{
			if( ((y+_y) < h) && ((x+_x) < w) )
			{
				unsigned i  = (y+_y)*w+(x+_x);
				double Y  = yuv->y[_y][_x];
				double Cb = yuv->u[_y][_x];
				double Cr = yuv->v[_y][_x];

				fbuff->buff[i].r = fmax(fmin(round(Y + 1.402*(Cr-128)),255),0);
				fbuff->buff[i].g = fmax(fmin(round(Y - 0.34414*(Cb-128) - 0.71414*(Cr-128)),255),0);
				fbuff->buff[i].b = fmax(fmin(round(Y + 1.772*(Cb-128)),255),0);				
			}
			else
			{
				//za okrajem
			}
		}
}

/***
 * dekomprimuje obrazek ze souboru (r) do FB (vytvori)
 */ 
int openDecompress(FILE *descriptor, PFrameBuff *framebuffer)
{
	dprintf("OpenDecompress()\n");
	// nacist bz2 do pameti
	long int pos0 = ftell(descriptor);
	fseek(descriptor, 0, SEEK_END);
	long int pos1 = ftell(descriptor);
	long int size = pos1 - pos0;
	fseek(descriptor, pos0, SEEK_SET);

	uint8 *file = malloc( size );
	if(NULL == file)
	{
		eprintf("malloc() fails!");
		return(2); // malloc
	}
	if(1 != fread(file, size, 1, descriptor))
	{
		eprintf("fread() fails!");
		return(10); // internal/unknown
	}

	// vytvorit FB
	PFrameBuff fbuff = malloc(sizeof(TFrameBuff));
	*framebuffer = fbuff;

	// vse default
	bz_stream bstrm;
	bstrm.bzalloc = NULL;
	bstrm.bzfree = NULL;
	bstrm.opaque = NULL;
	int ret = BZ2_bzDecompressInit(&bstrm,0,0);
	if(ret != BZ_OK)
	{
		eprintf("BZ2_bzDecompressInit() fails!");
		return(3); // BZ2
	}

	// zdroj = soubor v pameti
	bstrm.next_in = (char *)file;
	bstrm.avail_in = size;

	// nacist hlavicku, alokovat fb
	ret = decompress(&bstrm, (char *)&(fbuff->w), sizeof(uint32));
	if(0 != ret)
	{
		eprintf("Internal error/decompress/1!");
		return(ret);
	}
	ret = decompress(&bstrm, (char *)&(fbuff->h), sizeof(uint32));
	if(0 != ret)
	{
		eprintf("Internal error/decompress/2!");
		return(ret);
	}
	uint8 q8;
	ret = decompress(&bstrm, (char *)&(q8), sizeof(uint8));
	if(0 != ret)
	{
		eprintf("Internal error/decompress/3!");
		return(ret);
	}		
	
	uint8 methd;
	ret = decompress(&bstrm, (char *)&(methd), sizeof(uint8));
	if(0 != ret)
	{
		eprintf("Internal error/decompress/methd!");
		return(ret);
	}
	
	uint32 w = fbuff->w;
	uint32 h = fbuff->h;
	
	fbuff->buff = malloc( sizeof(TPixel)*w*h );
	if( NULL == fbuff->buff )
	{
		eprintf("malloc() fails!");
		return(2); // malloc
	}
	//memset(fbuff->buff, 0, sizeof(TPixel)*w*h );

	if(q8 < 1)
		q8 = 1;
	if(q8 > 100)
		q8 = 100;
	
	dprintf("w=%u h=%u q8=%i m=%i\n",w,h,q8,methd);

	void (*i_t)(double [LENGTH][LENGTH], double [LENGTH][LENGTH]);

	TQuantMat qm_y, qm_c;

	// zjistit pouzitou metodu, vypocitat QM
	if(0 == methd)
	{ // DCT
		// --- Q.M. ---
		int q = q8;
		if(q < 50)
			q = 5000/q;
		else
			q = 200-q*2;
		q*=6;
		
		int tmp;
		for(int x=0; x<LENGTH; x++)
		for(int y=0; y<LENGTH; y++)
		{
			// Y
			tmp = (QM[y][x]*q+50)/100;
			if(tmp < 1)
				tmp = 1;
			if(tmp > 32767)
				tmp = 32767;
			qm_y[y][x] = tmp;
			// CbCr
			tmp = (QMc[y][x]*q+50)/100;
			if(tmp < 1)
				tmp = 1;
			if(tmp > 32767)
				tmp = 32767;
			qm_c[y][x] = tmp;
		}
		// --- Q.M. ---
		// prirazeni funkci
		i_t = &ict2D;
	}
	else
	if(1 == methd)
	{ // DWT
		int q = q8;
		// --- Q.M. ---
		q = (101-q)*1;
		
		int tmp;
		for(int x=0; x<LENGTH; x++)
		for(int y=0; y<LENGTH; y++)
		{
			// Y
			tmp = (QM[y][x]*q+50)/100;
			if(tmp < 1)
				tmp = 1;
			if(tmp > 32767)
				tmp = 32767;
			qm_y[y][x] = tmp;
			// CbCr
			tmp = (QMc[y][x]*q+50)/100;
			if(tmp < 1)
				tmp = 1;
			if(tmp > 32767)
				tmp = 32767;
			qm_c[y][x] = tmp;
		}
		// --- Q.M. ---
		// prirazeni funkci
		i_t = &iwt2D;
	}
	else
		return(1); // 1 = nepodporovana metoda

	uint32 w8 = (w/LENGTH + ((w%LENGTH!=0)?1:0))*LENGTH;
	uint32 h8 = (h/LENGTH + ((h%LENGTH!=0)?1:0))*LENGTH;

	TLinBlock linY;
	TLinBlock linU;
	TLinBlock linV;

	TYBlock tran;
	TYBlock yuv;

	// pro kazdy ctverecek
	for(uint32 _w=0; _w<w8/LENGTH; _w++) // radky
	{
		for(uint32 _h=0; _h<h8/LENGTH; _h++) // cely sloupec
		{
			ret = decompress(&bstrm, (char *)&(linY.lin), LENGTH*LENGTH*sizeof(uint16));
			if(ret)
			{
				eprintf("Internal error/decompress/linY!");
				return(ret);
			}
			ret = decompress(&bstrm, (char *)&(linU.lin), LENGTH*LENGTH*sizeof(uint16));
			if(ret)
			{
				eprintf("Internal error/decompress/linU!");
				return(ret);
			}
			ret = decompress(&bstrm, (char *)&(linV.lin), LENGTH*LENGTH*sizeof(uint16));
			if(ret)
			{
				eprintf("Internal error/decompress/linV!");
				return(ret);
			}			
			dequant((tran.y),qm_y,&linY);
			dequant((tran.u),qm_c,&linU);
			dequant((tran.v),qm_c,&linV);

			i_t(tran.y,yuv.y);
			i_t(tran.u,yuv.u);
			i_t(tran.v,yuv.v);
		
			yuv2rgb(fbuff, _w*LENGTH, _h*LENGTH, &yuv);
		}
	}	

	dprintf("OpenDecompress() exit\n");
	return(0);
}

⌨️ 快捷键说明

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