📄 vjpeg.c
字号:
for( j = 0 ; j<8 ; j++)
{
//if((i + (j<<2)+1)>= (OldSize.cx<<1))
//break;
*(pdst->pData +dstadr+j) = *(psrc->pData+srcadr + (j<<2)+2);
}
}
for( i=0 ; i<(OldSize.cx<<1) ; i += 32) //first line 'v'
{
srcadr = (i+ ((k*OldSize.cx*3)>>1));
dstadr = (((((k >>4)*NewSize.cx)*3)<<3) + ((k%16)<<2)+ (i*12));
dstadr += 320;
for( j = 0 ; j<8 ; j++)
{
//if((i + (j<<2)+1)>= (OldSize.cx<<1))
//break;
*(pdst->pData +dstadr+j) = *(psrc->pData+srcadr + (j<<2)+3);
}
}
}
pdst->ActLen = (((NewSize.cx * NewSize.cy)*3)>>1);
pnewsize->cx = NewSize.cx;
pnewsize->cy = NewSize.cy;
return 1;
}
UINT8 V558_YUV411PointToBlock(PV558_JPEGBUF psrc, PV558_JPEGBUF pdst,PV558_SIZE psize,PV558_SIZE pnewsize)
{
UINT16 i, j, k;
UINT32 srcadr,dstadr,h;
V558_JPEGBUF src,dst;
V558_SIZE OldSize,NewSize;
OldSize = *psize;
src = *psrc;
dst = *pdst;
NewSize.cx = (((OldSize.cx+31)>>5)<<5);
NewSize.cy = (((OldSize.cy+7)>>3)<<3);
if( dst.Len < (((OldSize.cx * OldSize.cy)*3)>>1))
return 0;
if((OldSize.cx != NewSize.cx) || (OldSize.cy != NewSize.cy) )
{
for( h=0 ; h < (((NewSize.cx * NewSize.cy)*3)>>1) ; h++)
*(dst.pData+h) = 0;
}
for( k=0 ; k< OldSize.cy ; k++)
{
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i+ ((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
for( j = 0 ; j<2 ; j++)
{
//if((i + (j<<2)+1)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+(j<<2)) = *(src.pData+srcadr + (j*6) );
*(dst.pData +dstadr+(j<<2)+1) = *(src.pData+srcadr + (j*6)+1);
*(dst.pData +dstadr+(j<<2)+2) = *(src.pData+srcadr + (j*6)+2);
*(dst.pData +dstadr+(j<<2)+3) = *(src.pData+srcadr + (j*6)+3);
}
}
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i+ 12+((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
dstadr += 64;
for( j = 0 ; j<2 ; j++)
{
//if((i + 16 + (j<<2)+1)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+(j<<2)) = *(src.pData+srcadr + (j*6) );
*(dst.pData +dstadr+(j<<2)+1) = *(src.pData+srcadr + (j*6)+1);
*(dst.pData +dstadr+(j<<2)+2) = *(src.pData+srcadr + (j*6)+2);
*(dst.pData +dstadr+(j<<2)+3) = *(src.pData+srcadr + (j*6)+3);
}
}
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i+ 24 + ((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
dstadr += 128;
for( j = 0 ; j<2 ; j++)
{
//if((i + (j<<2)+2)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+(j<<2)) = *(src.pData+srcadr + (j*6) );
*(dst.pData +dstadr+(j<<2)+1) = *(src.pData+srcadr + (j*6)+1);
*(dst.pData +dstadr+(j<<2)+2) = *(src.pData+srcadr + (j*6)+2);
*(dst.pData +dstadr+(j<<2)+3) = *(src.pData+srcadr + (j*6)+3);
}
}
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i+36+ ((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
dstadr += 192;
for( j = 0 ; j<2 ; j++)
{
//if((i + (j<<2)+2)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+(j<<2)) = *(src.pData+srcadr + (j*6) );
*(dst.pData +dstadr+(j<<2)+1) = *(src.pData+srcadr + (j*6)+1);
*(dst.pData +dstadr+(j<<2)+2) = *(src.pData+srcadr + (j*6)+2);
*(dst.pData +dstadr+(j<<2)+3) = *(src.pData+srcadr + (j*6)+3);
}
}
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i + ((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
dstadr += 256;
for( j = 0 ; j<8 ; j++)
{
//if((i + (j<<2)+2)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+j) = *(src.pData+srcadr + (j*6)+4);
}
}
for( i=0 ; i<((OldSize.cx*3)>>1) ; i += (16*3))
{
srcadr = i + ((k*OldSize.cx*3)>>1);
dstadr = ((((((k >>3)*NewSize.cx)*3)>>1) + k%8) +i)<<3;
dstadr += 320;
for( j = 0 ; j<8 ; j++)
{
//if((i + (j<<2)+2)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+j) = *(src.pData+srcadr + (j*6)+5);
}
}
}
pdst->ActLen = (((NewSize.cx * NewSize.cy)*3)>>1);
pnewsize->cx = NewSize.cx;
pnewsize->cy = NewSize.cy;
return 1;
}
UINT8 V558_YUV400PointToBlock(PV558_JPEGBUF psrc, PV558_JPEGBUF pdst,PV558_SIZE psize,PV558_SIZE pnewsize)
{
UINT16 i, j, k;
UINT32 srcadr,dstadr,h;
V558_JPEGBUF src,dst;
V558_SIZE OldSize,NewSize;
OldSize = *psize;
src = *psrc;
dst = *pdst;
NewSize.cx = (((OldSize.cx+7)>>3)<<3);
NewSize.cy = (((OldSize.cy+7)>>3)<<3);
if( dst.Len < ((OldSize.cx * OldSize.cy)))
return 0;
if((OldSize.cx != NewSize.cx) || (OldSize.cy != NewSize.cy) )
{
for( h=0 ; h < (NewSize.cx * NewSize.cy) ; h++)
*(dst.pData+h) = 0;
}
for( k=0 ; k< OldSize.cy ; k++)
{
for( i=0 ; i<OldSize.cx ; i += 8)
{
srcadr = i+ k*OldSize.cx;
dstadr = ((((k >>3)*NewSize.cx) + k%8) +i)<<3;
for( j = 0 ; j<8 ; j++)
{
//if((i + (j<<2)+1)>= (OldSize.cx<<1))
//break;
*(dst.pData +dstadr+j) = *(src.pData+srcadr + j);
}
}
}
pdst->ActLen = (NewSize.cx*NewSize.cy);
pnewsize->cx = NewSize.cx;
pnewsize->cy = NewSize.cy;
return 1;
}
/******************************************************************************
Description:
将YUV422/YUV420/YUV411/YUV400的以点来排列的数据转换成以8*8 block排列的数据。
Parameters:
1,psrc:输入的数据块。用于存放转换之前的数据。
2,pdst:输出的数据块。用于存放转换之后的数据。
3,psize:将要转换的原始数据的图像大小。
4,pnewsize:经过补数后,数据的图像大小。
5,YUVType:输入数据的格式。 0:YUV422 ; 1:YUV420 ; 2:YUV411 ; 3:YUV400。
Returns:
如果转换成功,返回1,否则,返回0。
Remarks:
因为jpeg的图像是由8*8 block的YUV数据压缩后生成的,所以,它对输入要压缩的数据的
大小有限制。当为YUV422的时候,width是16的倍数,height是8的倍数;当为YUV420的时
候,width是16的倍数,height是16的倍数;当为YUV411的时候,width是32的倍数,height
是8的倍数;当为YUV400的时候,width是8的倍数,height是8的倍数。因此,此函数会根据
不同的YUV输入格式,将不是相应数据倍数的width和height补齐。然后,psize将是相应补齐
的width和height。
******************************************************************************/
UINT8 V558_YUVPointToBlock(PV558_JPEGBUF psrc, PV558_JPEGBUF pdst,PV558_SIZE psize,PV558_SIZE pnewsize, UINT8 YUVType)
{
UINT8 value;
switch(YUVType)
{
case V558_YUV_422:
value = V558_YUV422PointToBlock(psrc , pdst, psize,pnewsize, V558_PYUV_422_YUYV);
break;
case V558_YUV_420:
value = V558_YUV420PointToBlock(psrc , pdst, psize,pnewsize);
break;
case V558_YUV_411:
value = V558_YUV411PointToBlock(psrc , pdst, psize,pnewsize);
break;
case V558_YUV_400:
value = V558_YUV400PointToBlock(psrc , pdst, psize,pnewsize);
break;
default:
break;
}
return value;
}
/******************************************************************************
Description:
将YUV422/YUV420/YUV411/YUV400的以点来排列的数据转换成以8*8 block排列的数据,其中,当YUV422时,还支持不同的yuv排列。
Parameters:
1,psrc:输入的数据块。用于存放转换之前的数据。
2,pdst:输出的数据块。用于存放转换之后的数据。
3,psize:将要转换的原始数据的图像大小。
4,pnewsize:经过补数后,数据的图像大小。
5,YUVType:输入数据的格式。 0:YUV422 ; 1:YUV420 ; 2:YUV411 ; 3:YUV400。
6,encdatatype:输入yuv的排列格式。 0:yyuv ; 1:yuyv ; 2:uyvy。
Returns:
如果转换成功,返回1,否则,返回0。
Remarks:
因为jpeg的图像是由8*8 block的YUV数据压缩后生成的,所以,它对输入要压缩的数据的
大小有限制。当为YUV422的时候,width是16的倍数,height是8的倍数;当为YUV420的时
候,width是16的倍数,height是16的倍数;当为YUV411的时候,width是32的倍数,height
是8的倍数;当为YUV400的时候,width是8的倍数,height是8的倍数。因此,此函数会根据
不同的YUV输入格式,将不是相应数据倍数的width和height补齐。然后,psize将是相应补齐
的width和height。
******************************************************************************/
UINT8 V558_YUVTypePointToBlock(PV558_JPEGBUF psrc, PV558_JPEGBUF pdst, PV558_SIZE psize, PV558_SIZE pnewsize, UINT8 YUVType, UINT8 encdatatype)
{
UINT8 value;
switch(YUVType)
{
case V558_YUV_422: value = V558_YUV422PointToBlock(psrc , pdst, psize,pnewsize, encdatatype);break;
case V558_YUV_420: value = V558_YUV420PointToBlock(psrc , pdst, psize,pnewsize);break;
case V558_YUV_411: value = V558_YUV411PointToBlock(psrc , pdst, psize,pnewsize);break;
case V558_YUV_400: value = V558_YUV400PointToBlock(psrc , pdst, psize,pnewsize);break;
default: break;
}
return value;
}
void _ISR_LbufFull(void)
{
UINT32 len,adr;
UINT16 line = 0;
UINT8 *ptr,temp0,temp1,temp2,temp3;
UINT16 i,j;
if(!gJpegContext.pcall)
return;
len = GetYuvLbufSize(&line);
gJpegContext.decline += line;
gJpegContext.declinesum += line;
if(gJpegContext.header.YUVType==V558_YUV_420) //angela 1122
{
len/=3;
len*=4;
}
if(gJpegContext.dst.Len < gJpegContext.dst.ActLen + len)
{
gJpegContext.pcall(MSG_READ_YUV, &gJpegContext.dst);
gJpegContext.dst.ActLen = 0;
}
ptr = gJpegContext.dst.pData + gJpegContext.dst.ActLen;
switch(gJpegContext.mode)
{
case V558_DECODE_ONLY:
{
switch(gJpegContext.header.YUVType)
{
case V558_YUV_422:
GetYuv422Data(ptr);
break;
case V558_YUV_420:
GetYuv420Data(ptr);
break;
case V558_YUV_411:
GetYuv411Data(ptr);
break;
case V558_YUV_400:
GetYuv400Data(ptr);
break;
default:
break;
}
}
break;
case V558_DECODE_IPP:
case V558_DECODE_LCDIF:
{
gJpegContext.header.YUVType = V558_YUV_422;
for(j = 0; j < line; j++)
{
adr = LBUF1BASEADR;
adr += j * LBUF_UNITSIZE;
V558_ReadSram(adr, ptr, gJpegContext.decodewidth << 1);
for(i=0 ; i< (gJpegContext.decodewidth >> 1) ; i++)
{
adr = (i<<2);
switch(gJpegContext.decdatatype)
{
case V558_PYUV_422_YYUV:
temp0 = *(ptr+adr);
temp1 = *(ptr+adr+1);
temp2 = *(ptr+adr+2);
temp3 = *(ptr+adr+3);
*(ptr+adr) = temp1;
*(ptr+adr+1) = temp3;
*(ptr+adr+2) = temp0;
*(ptr+adr+3) = temp2;
break;
case V558_PYUV_422_YUYV:
temp0 = *(ptr+adr);
*(ptr+adr) = *(ptr+adr+1);
*(ptr+adr+1) = temp0;
temp0 = *(ptr+adr+2);
*(ptr+adr+2) = *(ptr+adr+3);
*(ptr+adr+3) = temp0;
break;
default:
break;
}
}
ptr += (gJpegContext.decodewidth << 1);
}
}break;
}
V558_SetReg((UINT16)V558_REG_BIU_MEM_LOW_WORD_H, 0);
V558_SetReg((UINT16)V558_REG_BIU_MEM_LOW_WORD_L, 0);
V558_SetReg((UINT16)V558_REG_BIU_MEM_HIGH_WORD, 0);
gJpegContext.dst.ActLen += len;
if(gJpegContext.declinesum >= gJpegContext.decMaxlinesum)
{
PV558_JPEGCALLBACK pcall;
pcall = gJpegContext.pcall;
gJpegContext.pcall = NULL;
V558_CtrlIntEnable(V558_INT_8BUF_FULL, 0);
// gJpegContext.declinesum = 0;
gJpegContext.State = V558_JPEG_INITED;
pcall(MSG_READ_YUV_DONE, &gJpegContext.dst);
}
//if(gJpegContext.decline >= gJpegContext.decMaxline)
//{
// gJpegContext.pcall(MSG_READ_YUV, &gJpegContext.dst);
// //gJpegContext.pcall = NULL;
// //V558_CtrlIntEnable(V558_INT_8BUF_FULL, 0);
// gJpegContext.decline = 0;
//}
else
V558_JpegRestartDecoder();
}
static void WriteQT(void)
{
UINT8 i, j;
if(gJpegContext.header.QTCount == 0)
return;
V558_JpegStartWrQTable();
for(i = 0; i < gJpegContext.header.QTCount; i++)
{
for(j = 0; j < 64; j++)
V558_JpegWriteQtable(gJpegContext.header.QT[i][j]);
}
}
static void WriteHT(void)
{
UINT8 i, j;
if(gJpegContext.header.HTCount == 0)
return;
V558_JpegStartWrHTable();
for(i = 0; i < gJpegContext.header.HTCount; i++)
{
V558_JpegSelectHTable(i);
for(j = 0; j < gJpegContext.header.HTLen[i]; j++)
V558_JpegWriteHtable(gJpegContext.header.HT[i][j]);
}
}
static void WriteComponents(void)
{
UINT8 i;
if( (gJpegContext.header.QTCount == 0) || (gJpegContext.header.HTCount == 0) )
return;
V558_JpegSetComponentNum(gJpegContext.header.CompCount | (gJpegContext.header.QTCount << 4));
for(i = 0; i < 4; i++)
V558_JpegSetComponentParm(i, gJpegContext.header.Comp[i]);
}
//====================================================
//
// Layer 3 function of Jpeg part
//
//====================================================
static void EncodeJpg(UINT8 mode, PV558_JPEGBUF pbuf, PV558_JPEGCALLBACK pcall)
{
V558_SIZE size;
V558_RECT rect;
UINT32 vwc;
UINT8 ratio;
gJpegContext.mode = mode;
gJpegContext.buf = *pbuf;
//memcpy(gJpegContext.buf, pbuf, sizeof(V558_JPEGBUF));
gJpegContext.pcall = pcall;
pbuf->ActLen = 0;
V558_LbufSetYuvMode(0);
V558_CtrlSwReset(V558_SW_RESET_JPG);
switch(gJpegContext.mode)
{
case V558_CAPTURE_FRAME:
case V558_CAPTURE_FRAMEVIDEO:
V558_LcdGetALDisRect(&rect);
size.cx = rect.width;
size.cy = rect.height;
V558_LbufSetWorkmode(4);
break;
case V558_CAPTURE_STILLBRC:
case V558_CAPTURE_STILLBRC_THUMBNAIL:
case V558_CAPTURE_VIDEO:
V558_IppSelectPrefilter(1);
V558_IppGetCapSize(&size);
V558_LbufSetWorkmode(0);
break;
default:
return;
}
V558_JpegSetImageSize(size);
size.cx += 15;
size.cx >>= 4;
size.cx <<= 4;
size.cy += 7;
size.cy >>= 3;
size.cy <<= 3;
V558_LbufSetImageSize(size);
vwc = size.cx;
vwc *= size.cy;
vwc >>= 1;
V558_JpegSetVWC(vwc);
if(gJpegContext.entcr)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -