#include "yuv2jpg.h"
#include <stdio.h>
void ProcessUV(unsigned char* pUVBuf,unsigned char* pTmpUVBuf,int width,int height,int nStride)
{
int i=0;
while(i<nStride*height){
pUVBuf[i] = pTmpUVBuf[i/2];
i++;
}
}
int QualityScaling(int quality)
{
if (quality <= 0) quality = 1;
if (quality > 100) quality = 100;
if (quality < 50)
quality = 5000 / quality;
else
quality = 200 - quality*2;
return quality;
}
void DivBuff(unsigned char* pBuf,int width,int height,int nStride,int xLen,int yLen)
{
int xBufs = width/xLen;
int yBufs= height/yLen;
int tmpBufLen = xBufs * xLen * yLen;
unsigned char* tmpBuf = (unsigned char*)malloc(tmpBufLen);
int i;
int j;
int k;
int n;
int bufOffset = 0;
for (i = 0; i < yBufs; ++i)
{
n = 0;
for (j = 0; j < xBufs; ++j)
{
bufOffset = yLen * i * nStride + j * xLen;
for (k = 0; k < yLen; ++k)
{
memcpy(tmpBuf + n,pBuf +bufOffset,xLen);
n += xLen;
bufOffset += nStride;
}
}
memcpy(pBuf +i * tmpBufLen,tmpBuf,tmpBufLen);
}
free(tmpBuf);
}
void SetQuantTable(unsigned char* std_QT,unsigned char* QT, int Q)
{
int tmpVal = 0;
int i;
for (i = 0; i < DCTBLOCKSIZE; ++i)
{
tmpVal = (std_QT[i] * Q + 50L) / 100L;
if (tmpVal < 1)
{
tmpVal = 1L;
}
if (tmpVal > 255)
{
tmpVal = 255L;
}
QT[FZBT[i]] = (unsigned char)tmpVal;
}
}
void InitQTForAANDCT(JPEGINFO *pJpgInfo)
{
unsigned int i = 0;
unsigned int j = 0;
unsigned int k = 0;
for (i = 0; i < DCTSIZE; i++)
{
for (j = 0; j < DCTSIZE; j++)
{
pJpgInfo->YQT_DCT[k] = (float) (1.0 / ((double) pJpgInfo->YQT[FZBT[k]] *
aanScaleFactor[i] * aanScaleFactor[j] * 8.0));
++k;
}
}
k = 0;
for (i = 0; i < DCTSIZE; i++)
{
for (j = 0; j < DCTSIZE; j++)
{
pJpgInfo->UVQT_DCT[k] = (float) (1.0 / ((double) pJpgInfo->UVQT[FZBT[k]] *
aanScaleFactor[i] * aanScaleFactor[j] * 8.0));
++k;
}
}
}
unsigned char ComputeVLI(short val)
{
unsigned char binStrLen = 0;
val = abs(val);
if(val == 1)
{
binStrLen = 1;
}
else if(val >= 2 && val <= 3)
{
binStrLen = 2;
}
else if(val >= 4 && val <= 7)
{
binStrLen = 3;
}
else if(val >= 8 && val <= 15)
{
binStrLen = 4;
}
else if(val >= 16 && val <= 31)
{
binStrLen = 5;
}
else if(val >= 32 && val <= 63)
{
binStrLen = 6;
}
else if(val >= 64 && val <= 127)
{
binStrLen = 7;
}
else if(val >= 128 && val <= 255)
{
binStrLen = 8;
}
else if(val >= 256 && val <= 511)
{
binStrLen = 9;
}
else if(val >= 512 && val <= 1023)
{
binStrLen = 10;
}
else if(val >= 1024 && val <= 2047)
{
binStrLen = 11;
}
return binStrLen;
}
void BuildVLITable(JPEGINFO *pJpgInfo)
{
short i = 0;
for (i = 0; i < DC_MAX_QUANTED; ++i)
{
pJpgInfo->pVLITAB[i] = ComputeVLI(i);
}
for (i = DC_MIN_QUANTED; i < 0; ++i)
{
pJpgInfo->pVLITAB[i] = ComputeVLI(i);
}
}
int WriteSOI(unsigned char* pOut,int nDataLen)
{
memcpy(pOut+nDataLen,&SOITAG,sizeof(SOITAG));
return nDataLen+sizeof(SOITAG);
}
int WriteEOI(unsigned char* pOut,int nDataLen)
{
memcpy(pOut+nDataLen,&EOITAG,sizeof(EOITAG));
return nDataLen + sizeof(EOITAG);
}
int WriteAPP0(unsigned char* pOut,int nDataLen)
{
JPEGAPP0 APP0;
APP0.segmentTag = 0xE0FF;
APP0.length = 0x1000;
APP0.id[0] = 'J';
APP0.id[1] = 'F';
APP0.id[2] = 'I';
APP0.id[3] = 'F';
APP0.id[4] = 0;
APP0.ver = 0x0101;
APP0.densityUnit = 0x00;
APP0.densityX = 0x0100;
APP0.densityY = 0x0100;
APP0.thp = 0x00;
APP0.tvp = 0x00;
//memcpy(pOut+nDataLen,&APP0,sizeof(APP0));
memcpy(pOut+nDataLen,&APP0.segmentTag,2);
memcpy(pOut+nDataLen+2,&APP0.length,2);
memcpy(pOut+nDataLen+4,APP0.id,5);
memcpy(pOut+nDataLen+9,&APP0.ver,2);
*(pOut+nDataLen+11) = APP0.densityUnit;
memcpy(pOut+nDataLen+12,&APP0.densityX,2);
memcpy(pOut+nDataLen+14,&APP0.densityY,2);
*(pOut+nDataLen+16) = APP0.thp;
*(pOut+nDataLen+17) = APP0.tvp;
return nDataLen + sizeof(APP0)-2;
}
int WriteDQT(JPEGINFO *pJpgInfo,unsigned char* pOut,int nDataLen)
{
unsigned int i = 0;
JPEGDQT_8BITS DQT_Y;
DQT_Y.segmentTag = 0xDBFF;
DQT_Y.length = 0x4300;
DQT_Y.tableInfo = 0x00;
for (i = 0; i < DCTBLOCKSIZE; i++)
{
DQT_Y.table[i] = pJpgInfo->YQT[i];
}
//memcpy(pOut+nDataLen , &DQT_Y,sizeof(DQT_Y));
memcpy(pOut+nDataLen,&DQT_Y.segmentTag,2);
memcpy(pOut+nDataLen+2,&DQT_Y.length,2);
*(pOut+nDataLen+4) = DQT_Y.tableInfo;
memcpy(pOut+nDataLen+5,DQT_Y.table,64);
nDataLen += sizeof(DQT_Y)-1;
DQT_Y.tableInfo = 0x01;
for (i = 0; i < DCTBLOCKSIZE; i++)
{
DQT_Y.table[i] = pJpgInfo->UVQT[i];
}
//memcpy(pOut+nDataLen,&DQT_Y,sizeof(DQT_Y));
memcpy(pOut+nDataLen,&DQT_Y.segmentTag,2);
memcpy(pOut+nDataLen+2,&DQT_Y.length,2);
*(pOut+nDataLen+4) = DQT_Y.tableInfo;
memcpy(pOut+nDataLen+5,DQT_Y.table,64);
nDataLen += sizeof(DQT_Y)-1;
return nDataLen;
}
unsigned short Intel2Moto(unsigned short val)
{
unsigned char highBits = (unsigned char)(val / 256);
unsigned char lowBits = (unsigned char)(val % 256);
return lowBits * 256 + highBits;
}
int WriteSOF(unsigned char* pOut,int nDataLen,int width,int height)
{
JPEGSOF0_24BITS SOF;
SOF.segmentTag = 0xC0FF;
SOF.length = 0x1100;
SOF.precision = 0x08;
SOF.height = Intel2Moto((unsigned short)height);
SOF.width = Intel2Moto((unsigned short)width);
SOF.sigNum = 0x03;
SOF.YID = 0x01;
SOF.QTY = 0x00;
SOF.UID = 0x02;
SOF.QTU = 0x01;
SOF.VID = 0x03;
SOF.QTV = 0x01;
SOF.HVU = 0x11;
SOF.HVV = 0x11;
SOF.HVY = 0x11;
// memcpy(pOut + nDataLen,&SOF,sizeof(SOF));
memcpy(pOut+nDataLen,&SOF.segmentTag,2);
memcpy(pOut+nDataLen+2,&SOF.length,2);
*(pOut+nDataLen+4) = SOF.precision;
memcpy(pOut+nDataLen+5,&SOF.height,2);
memcpy(pOut+nDataLen+7,&SOF.width,2);
*(pOut+nDataLen+9) = SOF.sigNum;
*(pOut+nDataLen+10) = SOF.YID;
*(pOut+nDataLen+11) = SOF.HVY;
*(pOut+nDataLen+12) = SOF.QTY;
*(pOut+nDataLen+13) = SOF.UID;
*(pOut+nDataLen+14) = SOF.HVU;
*(pOut+nDataLen+15) = SOF.QTU;
*(pOut+nDataLen+16) = SOF.VID;
*(pOut+nDataLen+17) = SOF.HVV;
*(pOut+nDataLen+18) = SOF.QTV;
return nDataLen + sizeof(SOF)-1;
}
int WriteByte(unsigned char val,unsigned char* pOut,int nDataLen)
{
pOut[nDataLen] = val;
return nDataLen + 1;
}
int WriteDHT(unsigned char* pOut,int nDataLen)
{
unsigned int i = 0;
JPEGDHT DHT;
DHT.segmentTag = 0xC4FF;
DHT.length = Intel2Moto(19 + 12);
DHT.tableInfo = 0x00;
for (i = 0; i < 16; i++)
{
DHT.huffCode[i] = STD_DC_Y_NRCODES[i + 1];
}
//memcpy(pOut+nDataLen,&DHT,sizeof(DHT));
memcpy(pOut+nDataLen,&DHT.segmentTag,2);
memcpy(pOut+nDataLen+2,&DHT.length,2);
*(pOut+nDataLen+4) = DHT.tableInfo;
memcpy(pOut+nDataLen+5,DHT.huffCode,16);
nDataLen += sizeof(DHT)-1;
for (i = 0; i <= 11; i++)
{
nDataLen = WriteByte(STD_DC_Y_VALUES[i],pOut,nDataLen);
}
DHT.tableInfo = 0x01;
for (i = 0; i < 16; i++)
{
DHT.huffCode[i] = STD_DC_UV_NRCODES[i + 1];
}
//memcpy(pOut+nDataLen,&DHT,sizeof(DHT));
memcpy(pOut+nDataLen,&DHT.segmentTag,2);
memcpy(pOut+nDataLen+2,&DHT.length,2);
*(pOut+nDataLen+4) = DHT.tableInfo;
memcpy(pOut+nDataLen+5,DHT.huffCode,16);
nDataLen += sizeof(DHT)-1;
for (i = 0; i <= 11; i++)
{
nDataLen = WriteByte(STD_DC_UV_VALUES[i],pOut,nDataLen);
}
DHT.length = Intel2Moto(19 + 162);
DHT.tableInfo = 0x10;
for (i = 0; i < 16; i++)
{
DHT.huffCode[i] = STD_AC_Y_NRCODES[i + 1];
}
//memcpy(pOut+nDataLen,&DHT,sizeof(DHT));
memcpy(pOut+nDataLen,&DHT.segmentTag,2);
memcpy(pOut+nDataLen+2,&DHT.length,2);
*(pOut+nDataLen+4) = DHT.tableInfo;
memcpy(pOut+nDataLen+5,DHT.huffCode,16);
nDataLen += sizeof(DHT)-1;
for (i = 0; i <= 161; i++)
{
nDataLen = WriteByte(STD_AC_Y_VALUES[i],pOut,nDataLen);
}
DHT.tableInfo = 0x11;
for (i = 0; i < 16; i++)
{
DHT.huffCode[i] = STD_AC_UV_NRCODES[i + 1];
}
//memcpy(pOut + nDataLen,&DHT,sizeof(DHT));
memcpy(pOut+nDataLen,&DHT.segmentTag,2);
memcpy(pOut+nDataLen+2,&DH
- 1
- 2
前往页