📄 open.c
字号:
}
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 + -