#include "JPEGDecoder.h"
int JPEG::Set(char* arg1, char* arg2)
{
InputFileName = arg1;
OutputFileName = arg2;
InputFile = fopen (InputFileName.c_str(),"rb");
OutputFile = fopen(OutputFileName.c_str(),"wb");
if(!InputFile) return 1;
else if(!OutputFile) return 2;
else
{
fseek(InputFile, 0, SEEK_END);// Reposition stream position indicator
ImageStreamLength = ftell(InputFile);// Get current position in stream
rewind (InputFile);// Set position indicator to the beginning
ImageStream = new unsigned char[ImageStreamLength];
fread(ImageStream, ImageStreamLength,1,InputFile);
if(ImageStream[0] != JPEGMarker || ImageStream[1] != SOI) return 3;
else return 4;
}
}
inline void JPEG::DecodeDQT()
{
//Length gives the length of QT and the information of QT
unsigned int Length = ImageStream[ImageStreamIndex] * 256 + ImageStream[ImageStreamIndex + 1] - LengthByte;
ImageStreamIndex += LengthByte; //Length: 2 bytes
unsigned int NumbOfTable = Length / (QTSize + InformationByte) ; // A single DQT segment may contain multiple QTs, each with its own information byte.
// only consider precision: 8bits
// QT information: 1bytes
// bits 0..3: number of QT
//bits 4..7: prescision of QT, 0 = 8 bit, otherwise 16 bit
// only consider precision: 8bits
int TableIndex;
ImageStreamIndex;// QT information: 1bytes
for(int i = 0; i < (int)NumbOfTable; i++)
{
unsigned int *QT = new unsigned int [BlockSize * BlockSize];
TableIndex = ImageStream[ImageStreamIndex] & 0xF;
ImageStreamIndex += InformationByte;
for(int i = 0; i < BlockSize * BlockSize; i++)
QT[ZagZigArray[i]] = ImageStream[ImageStreamIndex++];
QTable.push_back(QT);
QTIndex.push_back(TableIndex);
}
}
inline void JPEG::DecodeSOF()
{
//printf("The Image Information:\n");
// 2 bytes, this value equals to 8 + components * 3 value
//unsigned int Length = ImageStream[ImageStreamIndex] * 256 + ImageStream[ImageStreamIndex + 1];
ImageStreamIndex += LengthByte;// 2 bytes
unsigned int DataPrecision = ImageStream[ImageStreamIndex++];//1 bytes, this is in bits/sample, usually 8
ImageHeight = ImageStream[ImageStreamIndex] * 256 + ImageStream[ImageStreamIndex + 1];// 2 bytes, this must be > 0
ImageStreamIndex += ImageHeightByte; // 2 bytes
ImageWidth = ImageStream[ImageStreamIndex] * 256 + ImageStream[ImageStreamIndex + 1];// 2 bytes, this must be > 0
ImageStreamIndex += ImageWidthByte; // 2 bytes
char NumOfComponent = ImageStream[ImageStreamIndex];// 1 bytes, Usually 1 = gray scaled, 3 = color YCbCr or YIQ
// 4 = color CMYK
ChannelType = NumOfComponent;
ImageStreamIndex += QTComponentByte; //1 bytes
int VSF, HSF, QT;
for(int i = 0; i < NumOfComponent; i++)
{
VSF = ImageStream[ImageStreamIndex + 1] & 0xF;
HSF = ImageStream[ImageStreamIndex + 1] >> 4;
QT = ImageStream[ImageStreamIndex + 2];
ComponentList[ImageStream[ImageStreamIndex] - 1].Set(VSF, HSF, QT);
ImageStreamIndex += ComponentInformationByte;
}
}
inline void JPEG::DecodeDHT()
{
// This specify length of Huffman table
unsigned int Length = ImageStream[ImageStreamIndex] * 256 + ImageStream[ImageStreamIndex + 1] - LengthByte;
ImageStreamIndex += LengthByte;// 2 bytes
// HT information, 1 byte
//bit 0..3: number of HT
//bit 4: type of table
//bit 5..7: must be 0
while(1)
{
char HTInformation = ImageStream[ImageStreamIndex++];
if(!(HTInformation >> 4)) DCHTIndex.push_back(DCHTIndex.size() + ACHTIndex.size());
else ACHTIndex.push_back(DCHTIndex.size() + ACHTIndex.size());
unsigned int NumberOfCode[NumbeOfSymbolsByte];
unsigned int TotalNumberOfSymbol = 0;
int StartIndex = NumbeOfSymbolsByte;
for(int j = 0; j < NumbeOfSymbolsByte; j++)
{
// Number of symbols with codes of length 1..16, the index represesnts the length of the code
NumberOfCode[j] = ImageStream[ImageStreamIndex++];
if(NumberOfCode[j] != 0 && StartIndex > j) StartIndex = j;
TotalNumberOfSymbol += NumberOfCode[j];
}
vector<TableElement> TempTable;
for(int i = StartIndex; i < NumbeOfSymbolsByte; i++)
{
if(NumberOfCode[i] != 0)
for(int j = 0; j < (int)NumberOfCode[i]; j++ )
TempTable.push_back(TableElement(ImageStream[ImageStreamIndex++], i + 1));
}
Decoder.GenerateHuffmanCode(DCHTIndex.size() + ACHTIndex.size() - 1, TempTable);
if(ImageStream[ImageStreamIndex] == JPEGMarker && ImageStream[ImageStreamIndex + 1] != 0x00) break;
}
}
inline void JPEG::ByteStreamToBitsStream()
{
BitsStream = new char[(ImageStreamLength - ImageStreamIndex) * 8];
BitsStreamIndex = 0;
long unsigned int Index = 0;
while(1)
{
if(ImageStream[ImageStreamIndex] == JPEGMarker)
{
if(ImageStream[ImageStreamIndex+1] == EOI) break;
else if(ImageStream[ImageStreamIndex+1] == 0x00)
{
ByteToBits(BitsStream, JPEGMarker,Index);
Index += 8;
ImageStreamIndex += 2;
}
}
else
{
ByteToBits(BitsStream, ImageStream[ImageStreamIndex++],Index);
Index+=8;
}
}
}
inline unsigned char JPEG::HuffmanDecoding(int ComponentType, bool IsAC)//IsAC: 0 for DC,other for AC
{
int CodeLength = 0, SuperTableIndex = 0, ClusterTableIndex = 0;
int DCTableIndex = DCHTIndex[ComponentList[ComponentType].DCTableIndex];
int ACTableIndex = ACHTIndex[ComponentList[ComponentType].ACTableIndex];
int TableIndex = (!IsAC)? ComponentList[ComponentType].DCTableIndex:ComponentList[ComponentType].ACTableIndex;
TableIndex = (!IsAC)? DCHTIndex[TableIndex]:ACHTIndex[TableIndex];
char StreamBuffer[BufferSize];
unsigned char Symbol = 0;
bool IsJump = false;
while(1)
{
for(int i = 0; i < BufferSize; i++) StreamBuffer[i] = BitsStream[BitsStreamIndex + i];
if(SuperTableIndex == 0 && StreamBuffer[0] == '0' && StreamBuffer[1] == '0') system("pause");
IsJump = Decoder.StreamDecoding(StreamBuffer, CodeLength, SuperTableIndex, ClusterTableIndex, TableIndex, Symbol);
ClusterTableIndex = 0;
BitsStreamIndex += CodeLength;
if(IsJump) return Symbol;
}
}
inline void JPEG::DecodeDataUnit(int ComponentType, int* DataUnit, int &PreviusDC)
{
int NumOfBits = 0;
// for DC
NumOfBits = HuffmanDecoding(ComponentType, false);
DataUnit[0] = BitsToNum(NumOfBits, BitsStream, BitsStreamIndex, PreviusDC);
PreviusDC = DataUnit[0];
BitsStreamIndex += NumOfBits;
// for AC
unsigned char Symbol;
int Run, Size;
int i = 1;
while(1)
{
Symbol = HuffmanDecoding(ComponentType, true);
if(Symbol == EOB)
{
for(int j = i; j < BlockSize * BlockSize; j++) DataUnit[ZagZigArray[i++]] = 0;
break;
}
Run = Symbol >> 4;
Size = Symbol & 0xF;
if(Run != 0)
{
if(Symbol == ZRL)
i = ZagZigZero(DataUnit,i,16);
else
i = ZagZigZero(DataUnit,i,Run);
}
if(Size != 0)
{
DataUnit[ZagZigArray[i++]] = BitsToNum(Size, BitsStream, BitsStreamIndex);
BitsStreamIndex += Size;
}
if(i == BlockSize * BlockSize) break;
}
}
inline void JPEG::IQ(int ComponentType, int* DataUnit)
{
int TableIndex = QTIndex[ComponentList[ComponentType].QTIndex];
for(int i = 0; i < BlockSize * BlockSize; i++)
DataUnit[i] = DataUnit[i] * QTable[TableIndex][i];
}
inline void JPEG::IDCT(int* DataUnit)
{
int Temp[BlockSize * BlockSize];
for(int i = 0; i < BlockSize; i++)IDCTRow(i,DataUnit,Temp);
for(int i = 0; i < BlockSize; i++)IDCTCol(i,Temp,DataUnit);
for(int i = 0; i < BlockSize * BlockSize; i++) DataUnit[i] = Clamp(DataUnit[i] + 128);
}
inline void JPEG::ReconstuctSampleData(int ComponentType, int BlockRowStart,int BlockColStart, int* DataUnit)
{
int BlockRowEnd = min(BlockRowStart + BlockSize * (VSmax / ComponentList[ComponentType].VerticalSample),ImageHeight);
int BlockColEnd = min(
JPEG-Decoder.rar_it_jpeg
版权申诉
29 浏览量
2022-09-21
09:08:04
上传
评论
收藏 11KB RAR 举报
小波思基
- 粉丝: 72
- 资源: 1万+
最新资源
- 谷歌浏览器自动化测试版113.0.5672.0(包含linux,windows32/64,mac三个版本,不会自动更新)
- uniapp中tab切换,底部内容跟着移动,相反,底部移动,tab也跟着切换-组件
- 基于JS+TS实现跨平台3D相机控制器-附项目源码-优质项目分享.zip
- 跨相机-基于Rust实现的跨平台相机捕获-附项目源码-优质项目分享.zip
- odise 14离线安装包 大众斯柯达奥迪 5054 6153
- 网页设计期末作业-纯html加css+少量js-盗墓笔记旅游导航网站.rar
- 算法笔记模拟退火.rar
- MATLAB大数据仿真案例-蚁群算法(ACO)用于求解旅行商(TSP)问题.rar
- 基于yolov5的吸烟行为检测源码+模型.zip
- MySQL基础知识-个人笔记.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈