📄 blit_soft.c
字号:
SurfacePtr(SrcPtr,Src,&Pack->Src,p->SrcBPP,Pack->SrcRect.x,SrcY,SrcPitch);
if (p->SrcUpDown)
SrcPitch = -SrcPitch;
Src2SrcLast = 0;
if (OnlyDiff)
Src2SrcLast = (uint8_t*)SrcLast[0] - (uint8_t*)Src[0];
DstStepX = p->DstBPP;
DstStepY = DstPitch*8;
DstX = Pack->DstRect.x;
DstY = Pack->DstRect.y;
if (p->DstLeftRight)
{
DstX += Pack->DstRect.Width-1;
DstStepX = -DstStepX;
}
if (p->DstUpDown)
{
DstY += Pack->DstRect.Height-1;
DstStepY = -DstStepY;
}
if (p->SwapXY)
SwapInt(&DstStepX,&DstStepY);
SurfacePtr(DstPtr,Dst,&Pack->Dst,p->DstBPP,DstX,DstY,DstPitch);
if (p->DstUpDown)
DstPitch = -DstPitch;
if (p->Slices)
{
const int DstBlock2 = 5;
const int DstBlock = 32;
int SrcBlock = (DstBlock * p->RScaleX) >> 4; //SrcBlock has to be even because of YUV
int DstNext = (DstBlock * DstStepX) >> 3;
int DstNextUV = DstNext >> (p->SwapXY ? p->DstUVPitch2+p->DstUVY2 : p->DstUVX2);
int SrcNext = (SrcBlock * p->SrcBPP) >> 3;
int SrcNextUV = SrcNext >> p->SrcUVX2;
if (Width > DstBlock && p->SlicesReverse) // reverse order?
{
int Quot = Width >> DstBlock2;
int Rem = Width & (DstBlock-1);
DstPtr[0] += Quot*DstNext;
DstPtr[1] += Quot*DstNextUV;
DstPtr[2] += Quot*DstNextUV;
SrcPtr[0] += Quot*SrcNext;
SrcPtr[1] += Quot*SrcNextUV;
SrcPtr[2] += Quot*SrcNextUV;
if (Rem)
{
p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,Rem,Height,Src2SrcLast);
Width -= Rem;
}
DstNext = -DstNext;
DstNextUV = -DstNextUV;
SrcNext = -SrcNext;
SrcNextUV = -SrcNextUV;
DstPtr[0] += DstNext;
DstPtr[1] += DstNextUV;
DstPtr[2] += DstNextUV;
SrcPtr[0] += SrcNext;
SrcPtr[1] += SrcNextUV;
SrcPtr[2] += SrcNextUV;
}
for (;Width > DstBlock;Width -= DstBlock)
{
p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,DstBlock,Height,Src2SrcLast);
DstPtr[0] += DstNext;
DstPtr[1] += DstNextUV;
DstPtr[2] += DstNextUV;
SrcPtr[0] += SrcNext;
SrcPtr[1] += SrcNextUV;
SrcPtr[2] += SrcNextUV;
}
}
p->Entry(p,DstPtr,SrcPtr,DstPitch,SrcPitch,Width,Height,Src2SrcLast);
}
void BuildPalLookUp(blit_soft* p,bool_t YUV)
{
//create a palette lookup with 3x3 bits RGB input
int a,b,c;
int Size = 1 << p->Dst.BitCount;
uint8_t* LookUp;
p->LookUp_Data = Alloc(16*16*16*4);
if (p->LookUp_Data)
{
LookUp = (uint8_t*) p->LookUp_Data;
for (a=16;a<512;a+=32)
for (b=16;b<512;b+=32)
for (c=16;c<512;c+=32)
{
const rgb* q = p->DstPalette;
int BestMatch = 0;
int BestDiff = 0x7FFFFFFF;
int i,v[3];
v[0] = a;
v[1] = b;
v[2] = c;
if (v[0] >= 384) v[0] -= 512;
if (v[1] >= 384) v[1] -= 512;
if (v[2] >= 384) v[2] -= 512;
if (YUV)
{
int w[3];
w[0] = (v[0]*p->_YMul + v[2]*p->_RVMul + p->_RAdd) >> 16;
w[1] = (v[0]*p->_YMul + v[1]*p->_GUMul + v[2]*p->_GVMul + p->_GAdd) >> 16;
w[2] = (v[0]*p->_YMul + v[1]*p->_BUMul + p->_BAdd) >> 16;
v[0]=w[0];
v[1]=w[1];
v[2]=w[2];
}
for (i=0;i<Size;++i,++q)
{
int Diff = (q->r-v[0])*(q->r-v[0])+
(q->g-v[1])*(q->g-v[1])+
(q->b-v[2])*(q->b-v[2]);
if (Diff < BestDiff)
{
BestMatch = i;
BestDiff = Diff;
}
}
q = p->DstPalette + BestMatch;
if (YUV)
{
v[0] = ( (2105 * q->r) + (4128 * q->g) + ( 802 * q->b))/0x2000 + 16;
v[1] = (-(1212 * q->r) - (2384 * q->g) + (3596 * q->b))/0x2000 + 128;
v[2] = ( (3596 * q->r) - (3015 * q->g) - ( 582 * q->b))/0x2000 + 128;
v[0]=SAT(v[0]);
v[1]=SAT(v[1]);
v[2]=SAT(v[2]);
}
else
{
v[0] = q->r;
v[1] = q->g;
v[2] = q->b;
}
LookUp[0] = (uint8_t)BestMatch;
#if defined(SH3)
LookUp[3] = (uint8_t)(v[0] >> 1);
LookUp[1] = (uint8_t)(v[1] >> 1);
LookUp[2] = (uint8_t)(v[2] >> 1);
#else
LookUp[1] = (uint8_t)v[0];
LookUp[2] = (uint8_t)v[1];
LookUp[3] = (uint8_t)v[2];
#endif
LookUp += 4;
}
}
}
#if defined(_M_IX86)
int UniversalType( const pixel* p, bool_t YUV )
{
if (PlanarYUV(p,NULL,NULL,NULL)) return YUV ? 12:10;
if (PackedYUV(p)) return YUV ? 13:11;
if (p->Flags & PF_PALETTE)
{
if (p->BitCount==1) return 1;
if (p->BitCount==2) return 2;
if (p->BitCount==4) return 3;
if (p->BitCount==8) return YUV ? 14:4;
}
if (p->Flags & PF_RGB)
{
if (p->BitCount==8) return 5;
if (p->BitCount==16) return 6;
if (p->BitCount==24) return 7;
if (p->BitCount==32) return 8;
}
return -1;
}
// !SwapXY
// !DstLeftRight
// SrcType == 12
// DstType == 12
// RScaleX == 16 && RScaleY == 16
// SrcUVX2 == DstUVX2
void Blit_PYUV_PYUV(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
int Width,int Height,int Src2SrcLast)
{
uint8_t* Src[3];
uint8_t* Dst[3];
int UVY = 1 << This->DstUVY2;
int UVDup = 1;
int SrcPitchUV = SrcPitch >> This->SrcUVPitch2;
int DstPitchUV = DstPitch >> This->DstUVPitch2;
int WidthUV = Width >> This->SrcUVX2;
int YAdd = This->FX.Brightness;
int x,y,i;
for (i=0;i<3;++i)
{
Src[i] = SrcPtr[i];
Dst[i] = DstPtr[i];
}
// skip some UV lines?
if (This->DstUVY2 > This->SrcUVY2)
SrcPitchUV <<= This->DstUVY2 - This->SrcUVY2;
else
UVDup = 1 << (This->SrcUVY2 - This->DstUVY2);
Height >>= This->DstUVY2;
for (y=0;y<Height;++y)
{
for (i=0;i<UVY;++i)
{
if (YAdd)
{
uint8_t* s = Src[0];
uint8_t* d = Dst[0];
for (x=0;x<Width;++x,++s,++d)
{
int Y = *s + YAdd;
Y = SAT(Y);
*d = (uint8_t)Y;
}
}
else
memcpy(Dst[0],Src[0],Width);
Src[0] += SrcPitch;
Dst[0] += DstPitch;
}
for (i=0;i<UVDup;++i)
{
memcpy(Dst[1],Src[1],WidthUV);
memcpy(Dst[2],Src[2],WidthUV);
Dst[1] += DstPitchUV;
Dst[2] += DstPitchUV;
}
Src[1] += SrcPitchUV;
Src[2] += SrcPitchUV;
}
}
void BlitUniversal(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
int Width,int Height,int Src2SrcLast)
{
//this will be very-very slow, only for compability and testing
int i,j,x,y;
uint8_t* Src[3];
uint8_t* Dst[3];
int SrcType = This->SrcType;
int DstType = This->DstType;
int DstMask[3],DstPos[3];
int SrcMask[3],SrcPos[3];
int DitherMask[3];
uint8_t* PalLookUp = (uint8_t*)This->LookUp_Data;
uint8_t* wp;
int Flags = This->FX.Flags;
bool_t Dither = (Flags & BLITFX_DITHER) != 0 && !(This->Dst.Flags & PF_FOURCC);
bool_t PalDither = Dither && (This->Dst.Flags & PF_PALETTE);
const rgb* SrcPalette = This->SrcPalette;
int SrcStepX[16];
int SrcStepY[16];
int RScaleX = This->RScaleX;
int RScaleY = This->RScaleY;
int SrcUVPitch2 = This->SrcUVPitch2;
int SrcUVX2 = This->SrcUVX2;
int SrcUVY2 = This->SrcUVY2;
int DstUVX2 = This->DstUVX2;
int DstUVY2 = This->DstUVY2;
int DstStepX = This->DstBPP;
int DstStepX2 = This->DstBPP;
int DstStepY = DstPitch << 3;
int DstStepY2 = DstStepY >> This->DstUVPitch2;
int dy = 0;
int dy2 = 0;
int cR,cG,cB;
int Y,U,V;
int sy0;
int sy=0;
int YAdd = This->FX.Brightness;
uint32_t SrcInvert = 0;
uint32_t DstInvert = 0;
SrcMask[0] = This->Src.RBitMask;
SrcMask[1] = This->Src.GBitMask;
SrcMask[2] = This->Src.BBitMask;
DstMask[0] = This->Dst.RBitMask;
DstMask[1] = This->Dst.GBitMask;
DstMask[2] = This->Dst.BBitMask;
for (i=0;i<3;++i)
{
DitherMask[i] = Dither ? (1 << (8 - BitMaskSize(DstMask[i]))) - 1 : 0;
SrcPos[i] = BitMaskPos(SrcMask[i]) + BitMaskSize(SrcMask[i]);
DstPos[i] = BitMaskPos(DstMask[i]) + BitMaskSize(DstMask[i]);
SrcMask[i] <<= 8;
DstMask[i] <<= 8;
Src[i] = SrcPtr[i];
Dst[i] = DstPtr[i];
}
if (This->DstPalette)
{
DstPos[0] = 11;
DstPos[1] = 7;
DstPos[2] = 3;
DstMask[0] = 0xF0000;
DstMask[1] = 0x0F000;
DstMask[2] = 0x00F00;
}
for (j=0;j<16;++j)
{
SrcStepX[j] = ((RScaleX * (j+1)) >> 4) - ((RScaleX * j) >> 4);
SrcStepY[j] = ((RScaleY * (j+1)) >> 4) - ((RScaleY * j) >> 4);
}
if (This->DstLeftRight)
{
DstStepX = -DstStepX;
DstStepX2 = -DstStepX2;
if (This->DstBPP < 8)
dy = 8 - This->DstBPP;
}
if (This->SwapXY)
{
SwapInt(&DstUVX2,&DstUVY2);
SwapInt(&DstStepX,&DstStepY);
SwapInt(&DstStepX2,&DstStepY2);
}
cR = (DitherMask[0] >> 1);
cG = (DitherMask[1] >> 1);
cB = (DitherMask[2] >> 1);
Y=U=V=0;
if (This->Src.Flags & PF_INVERTED)
SrcInvert = (This->Src.BitCount>=32?0:(1 << This->Src.BitCount))-1;
if (This->Dst.Flags & PF_INVERTED)
DstInvert = (This->Dst.BitCount>=32?0:(1 << This->Dst.BitCount))-1;
for (y=0;y<Height;++y)
{
int dx=dy;
int dx2=dy2;
int sx=0;
for (x=0;x<Width;sx+=SrcStepX[x&15],++x,dx+=DstStepX)
{
uint8_t* q;
const rgb* p;
uint32_t v,w;
switch (SrcType)
{
case 10: //Planar YUV->RGB
cR += ((Src[0][sx]+YAdd-16)*0x2568 + 0x3343*(Src[2][sx>>SrcUVX2]-128)) /0x2000;
cG += ((Src[0][sx]+YAdd-16)*0x2568 - 0x0c92*(Src[1][sx>>SrcUVX2]-128) - 0x1a1e*(Src[2][sx>>SrcUVX2]-128)) /0x2000;
cB += ((Src[0][sx]+YAdd-16)*0x2568 + 0x40cf*(Src[1][sx>>SrcUVX2]-128)) /0x2000;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 11: //Packed YUV->RGB
cR += ((Src[0][sx*2]+YAdd-16)*0x2568 + 0x3343*(Src[2][4*(sx>>1)]-128)) /0x2000;
cG += ((Src[0][sx*2]+YAdd-16)*0x2568 - 0x0c92*(Src[1][4*(sx>>1)]-128) - 0x1a1e*(Src[2][4*(sx>>1)]-128)) /0x2000;
cB += ((Src[0][sx*2]+YAdd-16)*0x2568 + 0x40cf*(Src[1][4*(sx>>1)]-128)) /0x2000;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 12: //Planar YUV->YUV
Y += Src[0][sx];
U += Src[1][sx>>SrcUVX2];
V += Src[2][sx>>SrcUVX2];
//Y=SAT(Y);
//U=SAT(U);
//V=SAT(V);
break;
case 13: //Packed YUV->YUV
Y += Src[0][sx*2];
U += Src[1][4*(sx>>1)];
V += Src[2][4*(sx>>1)];
//Y=SAT(Y);
//U=SAT(U);
//V=SAT(V);
break;
case 1: //Pal1->RGB
p = &SrcPalette[ ((Src[0][sx>>3] >> ((~sx)&7)) & 1) ^ SrcInvert];
cR += p->r; cG += p->g; cB += p->b;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 2: //Pal2->RGB
p = &SrcPalette[ ((Src[0][sx>>2] >> (((~sx)&3)*2)) & 3) ^ SrcInvert];
cR += p->r; cG += p->g; cB += p->b;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 3: //Pal4->RGB
p = &SrcPalette[ ((Src[0][sx>>1] >> (((~sx)&1)*4)) & 15) ^ SrcInvert];
cR += p->r; cG += p->g; cB += p->b;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 4: //Pal8->RGB
p = &SrcPalette[Src[0][sx] ^ SrcInvert];
cR += p->r; cG += p->g; cB += p->b;
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 5: //RGB8->RGB
v = Src[0][sx];
v ^= SrcInvert;
v <<= 8;
cR += (v & SrcMask[0]) >> SrcPos[0];
cG += (v & SrcMask[1]) >> SrcPos[1];
cB += (v & SrcMask[2]) >> SrcPos[2];
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 6: //RGB16->RGB
v = ((uint16_t*)Src[0])[sx];
v ^= SrcInvert;
v <<= 8;
cR += (v & SrcMask[0]) >> SrcPos[0];
cG += (v & SrcMask[1]) >> SrcPos[1];
cB += (v & SrcMask[2]) >> SrcPos[2];
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
case 7: //RGB24->RGB
v = Src[0][sx*3] | (Src[0][sx*3+1] << 8) | (Src[0][sx*3+2] << 16);
v ^= SrcInvert;
v <<= 8;
cR += (v & SrcMask[0]) >> SrcPos[0];
cG += (v & SrcMask[1]) >> SrcPos[1];
cB += (v & SrcMask[2]) >> SrcPos[2];
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
default: //RGB32->RGB
v = ((uint32_t*)Src[0])[sx];
v ^= SrcInvert;
v <<= 8;
cR += (v & SrcMask[0]) >> SrcPos[0];
cG += (v & SrcMask[1]) >> SrcPos[1];
cB += (v & SrcMask[2]) >> SrcPos[2];
cR=SAT(cR);
cG=SAT(cG);
cB=SAT(cB);
break;
}
q = Dst[0]+(dx >> 3);
switch (DstType)
{
case 10: //RGB->Planar YUV
Y = ( (2105 * cR) + (4128 * cG) + ( 802 * cB))/0x2000 + 16;
U = (-(1212 * cR) - (2384 * cG) + (3596 * cB))/0x2000 + 128;
V = ( (3596 * cR) - (3015 * cG) - ( 582 * cB))/0x2000 + 128;
*q = (uint8_t)Y;
Dst[1][dx2 >> 3] = (uint8_t)U;
Dst[2][dx2 >> 3] = (uint8_t)V;
if ((x & 1) || DstUVX2==0)
dx2+=DstStepX2;
cR=cG=cB=0;
break;
case 11: //RGB->Packed YUV
Y = ( (2105 * cR) + (4128 * cG) + ( 802 * cB))/0x2000 + 16;
U = (-(1212 * cR) - (2384 * cG) + (3596 * cB))/0x2000 + 128;
V = ( (3596 * cR) - (3015 * cG) - ( 582 * cB))/0x2000 + 128;
Y=SAT(Y);
U=SAT(U);
V=SAT(V);
*q = (uint8_t)Y;
Dst[1][4*(dx >> 5)] = (uint8_t)U;
Dst[2][4*(dx >> 5)] = (uint8_t)V;
cR=cG=cB=0;
break;
case 12: //YUV->Planar YUV
Y += YAdd;
Y=SAT(Y);
*q = (uint8_t)Y;
Dst[1][dx2 >> 3] = (uint8_t)U;
Dst[2][dx2 >> 3] = (uint8_t)V;
if ((x & 1) || DstUVX2==0)
dx2+=DstStepX2;
Y=U=V=0;
break;
case 13: //YUV->Packed YUV
Y += YAdd;
Y=SAT(Y);
*q = (uint8_t)Y;
Dst[1][4*(dx >> 5)] = (uint8_t)U;
Dst[2][4*(dx >> 5)] = (uint8_t)V;
Y=U=V=0;
break;
case 1: //RGB->Pal1
w = ((cR << DstPos[0]) & DstMask[0]) |
((cG << DstPos[1]) & DstMask[1]) |
((cB << DstPos[2]) & DstMask[2]);
wp = PalLookUp + (w >> 8)*4;
w = wp[0];
w ^= DstInvert;
*q &= ~(1 << ((~dx)&7));
*q |= (w << ((~dx)&7));
if (PalDither)
{
cR -= wp[1];
cG -= wp[2];
cB -= wp[3];
}
else
cR=cG=cB=0;
break;
case 2: //RGB->Pal2
w = ((cR << DstPos[0]) & DstMask[0]) |
((cG << DstPos[1]) & DstMask[1]) |
((cB << DstPos[2]) & DstMask[2]);
wp = PalLookUp + (w >> 8)*4;
w = wp[0];
w ^= DstInvert;
*q &= ~(3 << ((~dx)&6));
*q |= (w << ((~dx)&6));
if (PalDither)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -