📄 tffpict.cpp
字号:
clear(Trect(rectClipx+rectClipdx,rectClipy,rectFulldx-(rectClipx+rectClipdx),rectClipdy),i);
}
}
void TffPict::copyBorder(const TffPict &src,unsigned int plane)
{
if (rectFull==rectClip) return;
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
if (plane==PLANE_ALL || i==plane)
{
//copy(data[i],stride[i],src.data[i],src.stride[i],src.rectFull.dx>>cspInfo.shiftX[i],src.rectFull.dy>>cspInfo.shiftY[i]);
const int rectFulldx=rectFull.dx>>cspInfo.shiftX[i],rectFulldy=rectFull.dy>>cspInfo.shiftY[i];
const int rectClipx =rectClip.x >>cspInfo.shiftX[i],rectClipy =rectClip.y >>cspInfo.shiftY[i];
const int rectClipdx=rectClip.dx>>cspInfo.shiftX[i],rectClipdy=rectClip.dy>>cspInfo.shiftY[i];
copyRect(src,Trect(0,0,rectFulldx,rectClipy),i);
copyRect(src,Trect(0,rectClipy+rectClipdy,rectFulldx,rectFulldy-(rectClipy+rectClipdy)),i);
copyRect(src,Trect(0,rectClipy,rectClipx,rectClipdy),i);
copyRect(src,Trect(rectClipx+rectClipdx,rectClipy,rectFulldx-(rectClipx+rectClipdx),rectClipdy),i);
}
}
void TffPict::copyRect(const TffPict &src,const Trect &r,unsigned int plane)
{
if (r.dx!=0 && r.dy!=0)
copy(data[plane]+r.y*stride[plane]+cspInfo.Bpp*r.x,stride[plane],
src.data[plane]+r.y*src.stride[plane]+cspInfo.Bpp*r.x,src.stride[plane],
cspInfo.Bpp*r.dx,r.dy);
}
void TffPict::setRO(bool Iro)
{
for (unsigned int i=0;i<cspInfo.numPlanes;i++) ro[i]=Iro;
}
void TffPict::histogram(unsigned int histogram[256],int full,int half) const
{
memset(histogram,0,256*sizeof(unsigned int));
if (csp_isYUVplanar(csp))
{
Trect r=getRect(full,half);
stride_t diff[4];calcDiff(cspInfo,r,stride,diff);
for (const unsigned char *src=data[0]+diff[0],*srcEnd=src+r.dy*stride[0];src!=srcEnd;src+=stride[0])
for (unsigned int x=0;x<r.dx;x++)
histogram[src[x]]++;
}
else if ((csp&FF_CSPS_MASK)&FF_CSPS_MASK_YUV_PACKED)
{
Trect r=getRect(full,half);
stride_t diff[4];calcDiff(cspInfo,r,stride,diff);
int lumaoffset=cspInfo.packedLumaOffset;
for (const unsigned char *src=data[0]+diff[0],*srcEnd=src+r.dy*stride[0];src!=srcEnd;src+=stride[0])
for (unsigned int x=0;x<r.dx;x+=2)
histogram[src[2*x+lumaoffset]]++;
}
}
void TffPict::calcDiff(const TcspInfo &cspInfo,const Trect &rectClip,const stride_t stride[4],stride_t diff[4])
{
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
diff[i]=cspInfo.Bpp*(rectClip.x>>cspInfo.shiftX[i])+(rectClip.y>>cspInfo.shiftY[i])*stride[i];
}
void TffPict::calcDiff(void)
{
calcDiff(cspInfo,rectClip,stride,diff);
}
void TffPict::copyFrom(const TffPict &p,Tbuffer &buf,const Trect *rectCopy)
{
if (!rectCopy)
{
rectFull=p.rectFull;
rectClip=p.rectClip;
}
else
rectFull=rectClip=*rectCopy;
convertCSP(p.csp&FF_CSPS_MASK,buf);
if (!rectCopy)
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
copy(data[i],stride[i],p.data[i],p.stride[i],cspInfo.Bpp*(rectFull.dx>>cspInfo.shiftX[i]),rectFull.dy>>cspInfo.shiftY[i]);
else
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
copy(data[i],stride[i],p.data[i]+p.stride[i]*(rectCopy->y>>p.cspInfo.shiftY[i])+(rectCopy->x>>p.cspInfo.shiftX[i]),p.stride[i],cspInfo.Bpp*(rectFull.dx>>cspInfo.shiftX[i]),rectFull.dy>>cspInfo.shiftY[i]);
}
void TffPict::setCSP(int Icsp)
{
cspInfo=*csp_getInfo(csp=Icsp);
}
void TffPict::convertCSP(int Icsp,Tbuffer &buf,Tconvert *convert,int edge)
{
if (csp&FF_CSP_FLAGS_YUV_ADJ)
{
csp_yuv_adj_to_plane(csp,&cspInfo,rectFull.dy,data,stride);
calcDiff();
}
if (csp&FF_CSP_FLAGS_YUV_ORDER) csp_yuv_order(csp,data,stride);
int csp0=csp;
const unsigned char *data0[4]={data[0],data[1],data[2],data[3]};
stride_t stride0[4]={stride[0],stride[1],stride[2],stride[3]};
Tpalette palette0=palette;
convertCSP(Icsp,buf,edge);
convert->convert(csp0|((fieldtype&FIELD_TYPE::MASK_INT)?FF_CSP_FLAGS_INTERLACED:0),data0,stride0,csp,data,stride,&palette0);
}
void TffPict::convertCSP(int Icsp,Tbuffer &buf,int edge)
{
cspInfo=*csp_getInfo(csp=Icsp);
if (csp_isYUVplanar(csp))
{
if (csp&FF_CSP_FLAGS_YUV_ADJ)
{
stride[0]=rectFull.dx>>cspInfo.shiftX[0];
stride[1]=(stride[0]>>cspInfo.shiftX[1])+edge;//((rectFull.dx>>shiftX[1])/16+2)*16;
stride[2]=(stride[0]>>cspInfo.shiftX[2])+edge;//((rectFull.dx>>shiftX[2])/16+2)*16;
stride[3]=(stride[0]>>cspInfo.shiftX[3])+edge;//((rectFull.dx>>shiftX[3])/16+2)*16;
stride[0]+=edge;
}
else
{
stride[0]=(((rectFull.dx>>cspInfo.shiftX[0])+edge)/16+2)*16;
stride[1]=(((rectFull.dx>>cspInfo.shiftX[1])+edge)/16+2)*16;
stride[2]=(((rectFull.dx>>cspInfo.shiftX[2])+edge)/16+2)*16;
stride[3]=(((rectFull.dx>>cspInfo.shiftX[3])+edge)/16+2)*16;
}
size_t size=0;
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
size+=stride[i]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[i])+edge); // rectFull.dy should be added by 1 when rectFull.dy is odd number.
buf.allocZ(size,128);
data[0]=buf;
data[1]=data[0]+stride[0]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[0])+edge);
data[2]=data[1]+stride[1]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[1])+edge);
data[3]=data[2]+stride[2]*((ODD2EVEN(rectFull.dy)>>cspInfo.shiftY[2])+edge);
}
else
{
stride[0]=rectFull.dx*cspInfo.Bpp;
size_t bufsize0=stride[0]*rectFull.dy;
buf.alloc(bufsize0);
data[0]=buf;
}
calcDiff();
}
void TffPict::alloc(unsigned int dx,unsigned int dy,int Icsp,Tbuffer &buf,int edge)
{
rectFull=rectClip=Trect(0,0,dx,dy);
convertCSP(Icsp,buf,edge);
}
// copied from AviSynth
/*****************************
* Assembler bitblit by Steady
*****************************/
void TffPict::asm_BitBlt_MMX(BYTE* dstp, stride_t dst_pitch, const BYTE* srcp, stride_t src_pitch, int row_size, int height) {
if (height==0 || row_size==0) return;
const unsigned char *esi=srcp+(height-1)*src_pitch;unsigned char *edi=dstp+(height-1)*dst_pitch;
int row_size15=row_size-15;
for (;height;height--,esi-=src_pitch,edi-=dst_pitch)
{
int ebx;
for (ebx=0;ebx<row_size15;ebx+=16)
{
__m64 mm0=*(__m64*)(esi+ebx);
__m64 mm1=*(__m64*)(esi+ebx+8);
*(__m64*)(edi+ebx)=mm0;
*(__m64*)(edi+ebx+8)=mm1;
}
for (;ebx<row_size;ebx++)
edi[ebx]=esi[ebx];
}
_mm_empty();
}
void TffPict::asm_BitBlt_C(BYTE* dstp, stride_t dst_pitch, const BYTE* srcp, stride_t src_pitch, int row_size, int height)
{
if (dst_pitch == src_pitch && src_pitch == row_size) {
memcpy(dstp, srcp, src_pitch * height);
} else {
for (int y=height; y>0; --y) {
memcpy(dstp, srcp, row_size);
dstp += dst_pitch;
srcp += src_pitch;
}
}
}
void TffPict::clear(int Bpp,unsigned int black,unsigned char *dst,stride_t stride,unsigned int row_size,unsigned int height)
{
switch (Bpp)
{
case 1:
for (unsigned int y=0;y<height;y++)
memset(dst+y*stride,black,row_size);
return;
case 2:
black|=black<<16;
for (unsigned int y=0;y<height;y++)
for (uint32_t *p=(uint32_t*)(dst+y*stride),*pEnd=(uint32_t*)((uint8_t*)p+(row_size&~3));p!=pEnd;p++)
*p=black;
return;
case 3:
for (unsigned int y=0;y<height;y++)
for (uint8_t *p=dst+y*stride,*pEnd=p+row_size;p!=pEnd;p+=3)
{
p[0]=((uint8_t*)&black)[0];
p[1]=((uint8_t*)&black)[1];
p[2]=((uint8_t*)&black)[2];
}
return;
case 4:
for (unsigned int y=0;y<height;y++)
memsetd((uint32_t*)(dst+y*stride),black,row_size);
return;
}
}
void TffPict::draw_edges(uint8_t *buf, stride_t wrap, int width, int height, int w)
{
uint8_t *ptr, *last_line;
int i;
last_line = buf + (height - 1) * wrap;
for(i=0;i<w;i++) {
/* top and bottom */
memcpy(buf - (i + 1) * wrap, buf, width);
memcpy(last_line + (i + 1) * wrap, last_line, width);
}
/* left and right */
ptr = buf;
for(i=0;i<height;i++) {
memset(ptr - w, ptr[0], w);
memset(ptr + width, ptr[width-1], w);
ptr += wrap;
}
/* corners */
for(i=0;i<w;i++) {
memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */
memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */
memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */
memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */
}
}
void TffPict::createEdge(unsigned int Iedge,Tbuffer &buf)
{
if (edge>=Iedge) return;
edge=Iedge;
Trect rectFull0=rectFull,rectClip0=rectClip;
stride_t stride0[4];memcpy(stride0,stride,sizeof(stride));
unsigned char *data0[4];memcpy(data0,data,sizeof(data));
alloc(rectFull.dx,rectFull.dy,csp,buf,2*edge);
rectFull=rectEdge=Trect(0,0,rectFull.dx+edge*2,rectFull.dy+edge*2);
rectClip=Trect(edge,edge,rectFull0.dx,rectFull0.dy);
calcDiff();
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
{
edgeData[i]=data[i];
unsigned int dx=rectFull0.dx>>cspInfo.shiftX[i],dy=rectFull0.dy>>cspInfo.shiftY[i];
copy(data[i]+=diff[i],stride[i],data0[i],stride0[i],dx*cspInfo.Bpp,dy);
draw_edges(data[i],stride[i],dx,dy,edge);
}
rectFull=rectFull0;rectClip=rectClip0;
calcDiff();
}
void TffPict::md5sum(uint8_t sum[16]) const
{
memset(sum,0,16);
Tmd5 md5;
for (unsigned int i=0;i<cspInfo.numPlanes;i++)
for (unsigned int y=0;y<rectFull.dy>>cspInfo.shiftY[i];y++)
md5.sum(data[i]+y*stride[i],rectFull.dx>>cspInfo.shiftX[i]);
md5.done(sum);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -