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