📄 blit_soft.c
字号:
DstRect->x += ShrinkX;
DstRect->Width = SrcAdjWidth;
}
else //adjust source position
{
ShrinkX = 0;
SrcRect->x += ((SrcAdjWidth - DstRect->Width) << 15) / ScaleX;
SrcRect->Width = -1;
}
ShrinkY = DstRect->Height - SrcAdjHeight;
if (ShrinkY>0) //shrink Dst?
{
ShrinkY >>= 1;
DstRect->y += ShrinkY;
DstRect->Height = SrcAdjHeight;
}
else //adjust source position
{
ShrinkY = 0;
SrcRect->y += ((SrcAdjHeight - DstRect->Height) << 15) / ScaleY;
SrcRect->Height = -1;
}
// final alignment
i = DstRect->Width & (DstAlignSize-1);
DstRect->Width -= i;
i >>= 1;
ShrinkX += i;
DstRect->x += i;
i = DstRect->Height & (DstAlignSize-1);
DstRect->Height -= i;
i >>= 1;
ShrinkY += i;
DstRect->y += i;
i = DstRect->x & (DstAlignPos-1);
if (i && ShrinkX < i)
{
DstRect->Width -= DstAlignPos - i;
DstRect->Width &= ~(DstAlignSize-1);
DstRect->x += DstAlignPos - i;
}
else
DstRect->x -= i;
i = DstRect->y & (DstAlignPos-1);
if (i && ShrinkY < i)
{
DstRect->Height -= DstAlignPos - i;
DstRect->Height &= ~(DstAlignSize-1);
DstRect->y += DstAlignPos - i;
}
else
DstRect->y -= i;
SrcRect->x &= ~1;
SrcRect->y &= ~1;
if (SrcRect->Width < 0)
SrcRect->Width = ((DstRect->Width << 16) / ScaleX +1) & ~1;
if (SrcRect->Height < 0)
SrcRect->Height = ((DstRect->Height << 16) / ScaleY +1) & ~1;
if (FX->Direction & DIR_SWAPXY)
SwapRect(SrcRect);
if (SrcRect->x + SrcRect->Width > SrcRight)
SrcRect->Width = SrcRight - SrcRect->x;
if (SrcRect->y + SrcRect->Height > SrcBottom)
SrcRect->Height = SrcBottom - SrcRect->y;
return ERR_NONE;
}
static INLINE void SurfacePtr(uint8_t** Ptr, const planes Planes, const video* Format, int BPP, int x, int y, int Pitch)
{
int Adj = (x & 1) << 1;
Ptr[0] = (uint8_t*)Planes[0] + ((x * BPP) >> 3) + y * Pitch;
if (Format->Pixel.Flags & (PF_YUV420|PF_YUV422|PF_YUV444|PF_YUV410))
{
if (Format->Pixel.Flags & PF_YUV420)
{
Ptr[1] = (uint8_t*)Planes[1] + (x >> 1) + (y >> 1) * (Pitch >> 1);
Ptr[2] = (uint8_t*)Planes[2] + (x >> 1) + (y >> 1) * (Pitch >> 1);
}
else
if (Format->Pixel.Flags & PF_YUV422)
{
Ptr[1] = (uint8_t*)Planes[1] + (x >> 1) + y * (Pitch >> 1);
Ptr[2] = (uint8_t*)Planes[2] + (x >> 1) + y * (Pitch >> 1);
}
else
if (Format->Pixel.Flags & PF_YUV444)
{
Ptr[1] = (uint8_t*)Planes[1] + x + y * Pitch;
Ptr[2] = (uint8_t*)Planes[2] + x + y * Pitch;
}
else
if (Format->Pixel.Flags & PF_YUV410)
{
Ptr[1] = (uint8_t*)Planes[1] + (x >> 2) + (y >> 2) * (Pitch >> 2);
Ptr[2] = (uint8_t*)Planes[2] + (x >> 2) + (y >> 2) * (Pitch >> 2);
}
}
else
if (Format->Pixel.Flags & PF_FOURCC)
switch (Format->Pixel.FourCC)
{
case FOURCC_IMC2:
Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * Pitch;
Ptr[1] = Ptr[1] + (Pitch >> 1);
break;
case FOURCC_IMC4:
Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * Pitch;
Ptr[2] = Ptr[1] + (Pitch >> 1);
break;
case FOURCC_I420:
case FOURCC_IYUV:
Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * (Pitch >> 1);
Ptr[2] = Ptr[1] + ((Format->Height * Pitch) >> 2);
break;
case FOURCC_YV16:
Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + y * (Pitch >> 1);
Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 1);
break;
case FOURCC_YVU9:
Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 2) + (y >> 2) * (Pitch >> 2);
Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 4);
break;
case FOURCC_YUV9:
Ptr[1] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 2) + (y >> 2) * (Pitch >> 2);
Ptr[2] = Ptr[1] + ((Format->Height * Pitch) >> 4);
break;
case FOURCC_YV12:
Ptr[2] = (uint8_t*)Planes[0] + Format->Height * Pitch + (x >> 1) + (y >> 1) * (Pitch >> 1);
Ptr[1] = Ptr[2] + ((Format->Height * Pitch) >> 2);
break;
case FOURCC_YUY2:
case FOURCC_YUNV:
case FOURCC_V422:
case FOURCC_YUYV:
Ptr[1] = Ptr[0]+1-Adj;
Ptr[2] = Ptr[0]+3-Adj;
break;
case FOURCC_YVYU:
Ptr[1] = Ptr[0]+3-Adj;
Ptr[2] = Ptr[0]+1-Adj;
break;
case FOURCC_UYVY:
case FOURCC_Y422:
case FOURCC_UYNV:
Ptr[1] = Ptr[0]-Adj;
Ptr[2] = Ptr[0]+2-Adj;
Ptr[0]++;
break;
case FOURCC_VYUY:
Ptr[2] = Ptr[0]-Adj;
Ptr[1] = Ptr[0]+2-Adj;
Ptr[0]++;
break;
}
}
void BlitImage(blitpack* Pack, const planes Dst, const constplanes Src, const constplanes SrcLast, int DstPitch, int SrcPitch)
{
uint8_t* DstPtr[MAXPLANES];
uint8_t* SrcPtr[MAXPLANES];
bool_t OnlyDiff;
int Width,Height;
blit_soft* p;
uintptr_t Src2SrcLast;
int DstStepX;
int DstStepY;
int DstX;
int DstY;
int SrcY;
// nothing to do?
if (!Pack || Pack->DstRect.Width<=0 || Pack->DstRect.Height<=0)
return;
OnlyDiff = (Pack->FX.Flags & BLITFX_ONLYDIFF) && SrcLast && SrcLast[0] != NULL;
p = &Pack->Code[OnlyDiff];
// calculate the Src and Dst pointers
// Src: always upperleft corner
// Dst: according to swapxy and mirroring
Width = Pack->DstRect.Width;
Height = Pack->DstRect.Height;
if (p->SwapXY)
SwapInt(&Width,&Height);
if (DstPitch < 0)
DstPitch = Pack->Dst.Pitch;
if (SrcPitch < 0)
SrcPitch = Pack->Src.Pitch;
SrcY = Pack->SrcRect.y;
if (p->SrcUpDown)
SrcY += Pack->SrcRect.Height-1;
SurfacePtr(SrcPtr,*(const planes*)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 = malloc(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->c.r-v[0])*(q->c.r-v[0])+
(q->c.g-v[1])*(q->c.g-v[1])+
(q->c.b-v[2])*(q->c.b-v[2]);
if (Diff < BestDiff)
{
BestMatch = i;
BestDiff = Diff;
}
}
q = p->DstPalette + BestMatch;
if (YUV)
{
v[0] = ((2105 * q->c.r) + (4128 * q->c.g) + (802 * q->c.b))/0x2000 + 16;
v[1] = (-(1212 * q->c.r) - (2384 * q->c.g) + (3596 * q->c.b))/0x2000 + 128;
v[2] = ((3596 * q->c.r) - (3015 * q->c.g) - (582 * q->c.b))/0x2000 + 128;
v[0]=SAT(v[0]);
v[1]=SAT(v[1]);
v[2]=SAT(v[2]);
}
else
{
v[0] = q->c.r;
v[1] = q->c.g;
v[2] = q->c.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;
}
}
}
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 == 32/16/8
// RScaleY == 32/16/8
// SrcUVX2 == DstUVX2
// SrcUVY2 == DstUVY2
static void Blit_PYUV_PYUV_2Plane(const uint8_t* Src,uint8_t* Dst,int Width,int Height,int SrcPitch,int DstPitch,int ScaleX,int ScaleY)
{
int y;
for (y=0;y<Height;++y)
{
const uint8_t* s = Src;
uint8_t* d = Dst;
uint8_t* de = Dst + Width;
switch (ScaleX)
{
case 4:
while (d<de)
{
d[0] = d[1] = d[2] = d[3] = *s;
++s;
d+=4;
}
break;
case 8:
while (d<de)
{
d[0] = *s;
d[1] = *s;
++s;
d+=2;
}
break;
case 16:
memcpy(d,s,Width);
break;
case 32:
while (d<de)
{
*d = *s;
++d;
s+=2;
}
break;
case 64:
while (d<de)
{
*d = *s;
++d;
s+=4;
}
break;
}
Dst += DstPitch;
switch (ScaleY)
{
case 4:
if ((y&3)==3) Src += SrcPitch;
break;
case 8:
if (y&1) Src += SrcPitch;
break;
case 16:
Src += SrcPitch;
break;
case 32:
Src += SrcPitch*2;
break;
case 64:
Src += SrcPitch*4;
break;
}
}
}
// needed for half/quarter software idct mode changes
static void STDCALL Blit_PYUV_PYUV_2(blit_soft* This, uint8_t** DstPtr,uint8_t** SrcPtr,int DstPitch,int SrcPitch,
int Width,int Height,uintptr_t Src2SrcLast)
{
Blit_PYUV_PYUV_2Plane(SrcPtr[0],DstPtr[0],Width,Height,SrcPitch,DstPitch,This->RScaleX,This->RScaleY);
Width >>= This->SrcUVX2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -