#include "stdafx.h"
#include "MyJpeg.h"
MyJpeg::MyJpeg():
width(0),
height(0),
data(NULL),
data_mcu(NULL),
channel_num(0),
header_flag(0),
dc_y_prev(0),
dc_cb_prev(0),
dc_cr_prev(0)
{
for (int i = 0; i != 4; ++i)
{
root[i] = NULL;
}
for (int i = 0; i < 4; ++i)
{
mcu_channels[i] = NULL;
}
for (int i = 0; i < 4; ++i)
{
data_channels[i] = NULL;
}
for (int i = 0; i < 4; ++i)
{
memset(mcu_data_y[i], 0, sizeof(mcu_data_y[i]));
memset(mcu_data_cr[i], 0, sizeof(mcu_data_cr[i]));
memset(mcu_data_cb[i], 0, sizeof(mcu_data_cb[i]));
}
}
MyJpeg::~MyJpeg()
{
for (int i = 0; i != 4; ++i)
{
if (NULL != dht[i].root)
{
DeleteTree(dht[i].root);
}
}
for (int i = 0; i != 4; ++i)
{
if (NULL != mcu_channels[i])
{
delete mcu_channels[i];
}
}
for (int i = 0; i < 4; ++i)
{
if (data_channels[i] = NULL)
{
delete[]data_channels[i];
}
}
if (data != NULL)
{
delete[]data;
}
if (data_mcu != NULL)
{
delete[]data_mcu;
}
}
void MyJpeg::DeleteTree(HuffmanTree* p_root)
{
if (NULL != p_root->left)
{
DeleteTree(p_root->left);
}
if (NULL != p_root->right)
{
DeleteTree(p_root->right);
}
delete p_root;
p_root = NULL;
}
void MyJpeg::PreOrderTraverse(HuffmanTree * p_root)
{
if (p_root->is_leaf)
{
std::cout << p_root->value << " ";
}
if (NULL != p_root->left)
{
PreOrderTraverse(p_root->left);
}
if (NULL != p_root->right)
{
PreOrderTraverse(p_root->right);
}
}
void MyJpeg::MidOrderTraverse(HuffmanTree * p_root)
{
if (NULL != p_root->left)
{
MidOrderTraverse(p_root->left);
}
std::cout << p_root->value << " ";
if (NULL != p_root->right)
{
MidOrderTraverse(p_root->right);
}
}
void MyJpeg::BackOrderTraverse(HuffmanTree * p_root)
{
if (NULL != p_root->left)
{
BackOrderTraverse(p_root->left);
}
if (NULL != p_root->right)
{
BackOrderTraverse(p_root->right);
}
std::cout << p_root->value << " ";
}
void MyJpeg::ShowInHex(const char & c)
{
// 注意char类型,当char为 负数时
// 右移补位 1, 正数时补位 0
// 可以使用stl中的bitset取而代之
// 相同位数的不同类型间赋值,是将对应-位-赋值给受体
char cLow, cHigh;
cHigh = (c & 0xF0) >> 4;
cLow = c & 0x0F;
switch (cLow)
{
case 10:
cLow = 'A';
break;
case 11:
cLow = 'B';
break;
case 12:
cLow = 'C';
break;
case 13:
cLow = 'D';
break;
case 14:
cLow = 'E';
break;
case 15:
cLow = 'F';
break;
default:
cLow += 48;
break;
}
switch (cHigh)
{
case 10:
cHigh = 'A';
break;
case 11:
cHigh = 'B';
break;
case 12:
cHigh = 'C';
break;
case 13:
cHigh = 'D';
break;
case 14:
cHigh = 'E';
break;
case 15:
cHigh = 'F';
break;
default:
cHigh += 48;
break;
}
std::cout << cHigh << cLow << ' ';
/*static unsigned int char_count = 0;
char_count++;
if (char_count % 16 == 0)
{
std::cout << std::endl;
}*/
}
void MyJpeg::PrintBits(const unsigned int& src,
unsigned char num)
{
unsigned char count = 0;
while (count < num)
{
std::cout << ((src >> count) & 1);
count++;
}
std::cout << std::endl;
}
unsigned int MyJpeg::GetNCharacters(std::ifstream& ifs,
unsigned char * p_in,
unsigned int count
)
{
memset(p_in, 0, count);
unsigned int read_num = 0;
char c = 0;
char next_c = 0;
for (unsigned int i = 0; i < count; ++i)
{
if (ifs.get(c))
{
if ((unsigned char)c == 0xff)
{
if (ifs.get(next_c))
{
switch ((unsigned char)next_c)
{
case 0x00:
p_in[i] = c;
++read_num;
break;
case 0xD9:
p_in[i] = 0;
return read_num;
break;
default:
break;
}
}
}
else
{
p_in[i] = c;
++read_num;
}
}
else
{
std::cerr << "error reading a character" << std::endl;
std::exit(EXIT_FAILURE);
}
}
return read_num;
}
void MyJpeg::CopyNCharacters(unsigned char * dst,
unsigned char * src,
unsigned int count
)
{
for (unsigned int i = 0; i != count; ++i)
{
dst[i] = src[i];
}
}
void MyJpeg::ReadApp0(std::ifstream& ifs)
{
// 读取并计算该标记 段的长度
unsigned char temp[6];
GetNCharacters(ifs, temp, 2);
unsigned int len = 0;
len += temp[0];
len <<= 8;
len += temp[1];
unsigned char* read_src = new unsigned char[len - 2];
std::tr1::shared_ptr<unsigned char> read_src_smtpt(read_src);
GetNCharacters(ifs, read_src, len - 2);
unsigned char it = 0;
// 获得5个identifier数据
CopyNCharacters(app0.identifier, read_src + it, 5);
it += 5;
// 获得版本号
CopyNCharacters(app0.version, read_src + it, 2);
it += 2;
// x和y密度单位
CopyNCharacters(&app0.density_unit, read_src + it, 1);
it += 1;
// x分辨率
CopyNCharacters(temp, read_src + it, 2);
it += 2;
app0.density_x = 0;
app0.density_x += temp[0];
app0.density_x <<= 8;
app0.density_x += temp[1];
// y分辨率
CopyNCharacters(temp, read_src + it, 2);
it += 2;
app0.density_y = 0;
app0.density_y += temp[0];
app0.density_y <<= 8;
app0.density_y += temp[1];
// 缩略图水平分辨率
CopyNCharacters(&app0.thumbnail_h_pixel, read_src + it, 1);
it += 1;
// 缩略图垂直分辨率
CopyNCharacters(&app0.thumbnail_v_pixel, read_src + it, 1);
it += 1;
if (app0.thumbnail_h_pixel != 0 && app0.thumbnail_v_pixel != 0)
{
// RGB缩略图
//CopyNCharacters(app0.thumbnail_rgb_bitmap, read_src + it, 3);
}
}
void MyJpeg::ReadDqt(std::ifstream& ifs)
{
// 读取并计算该标记 段的长度
unsigned char temp[6];
GetNCharacters(ifs, temp, 2);
unsigned int len = 0;
len += temp[0];
len <<= 8;
len += temp[1];
unsigned char* read_src = new unsigned char[len - 2];
std::tr1::shared_ptr<unsigned char> read_src_smtpt(read_src);
GetNCharacters(ifs, read_src, len - 2);
unsigned int it = 0;
static unsigned char quant_table_cnt = 0;
// 获得量化表数据
CopyNCharacters(temp, read_src + it, 1);
it += 1;
// 获得高四位,确定精度 0:表示8位。1:表示16位
dqt[quant_table_cnt].precision = temp[0] >> 4;
// 获得低四位,确定量化表的编号
dqt[quant_table_cnt].table_id = temp[0] & 0x0f;
// 这里只考虑基本系统所以精度8位,共2个量化表
for (int i = 0; i != 64; ++i, ++it)
{
dqt[quant_table_cnt].quant_table[i] = *(read_src + it);
}
// 量化表计数机自加,静态static
quant_table_cnt++;
}
void MyJpeg::ReadSof(std::ifstream& ifs)
{
// 读取并计算该标记 段的长度
unsigned char temp[6];
GetNCharacters(ifs, temp, 2);
unsigned int len = 0;
len += temp[0];
len <<= 8;
len += temp[1];
unsigned char* read_src = new unsigned char[len - 2];
std::tr1::shared_ptr<unsigned char> read_src_smtpt(read_src);
GetNCharacters(ifs, read_src, len - 2);
unsigned int it = 0;
// 获得每个颜色分量每个pixel的位数
CopyNCharacters(&sof0.precision, read_src + it, 1);
it += 1;
// 获得图像的高度
CopyNCharacters(temp, read_src + it, 2);
it += 2;
sof0.heigth = 0;
sof0.heigth += temp[0];
sof0.heigth <<= 8;
sof0.heigth += temp[1];
this->height = sof0.heigth;
// 获得图像的宽度
CopyNCharacters(temp, read_src + it, 2);
it += 2;
sof0.width = 0;
sof0.width += temp[0];
sof0.width<<= 8;
sof0.width += temp[1];
this->width = sof0.width;
// 获得图像的颜色分量数目
CopyNCharacters(&sof0.component_num, read_src + it, 1);
it += 1;
this->channel_num = sof0.component_num;
// 对每个分量(每个占用一个字节),格式形如01 11 00
for (unsigned char i = 0; i < sof0.component_num; ++i)
{
// 获得id
CopyNCharacters(&sof0.component[i].id, read_src + it, 1);
it += 1;
// 垂直方向采样因子
CopyNCharacters(temp, read_src + it, 1);
it += 1;
sof0.component[i].sample_factor_v = (temp[0] & 0xf0) >> 4;
// 水平方向采样因子
sof0.component[i].sample_factor_h = temp[0] & 0x0f;
// 获得量化表号
CopyNCharacters(&sof0.component[i].quant_table_id, read_src + it, 1);
it += 1;
}
}
void MyJpeg::ReadDh
JPEG解码类 C++
需积分: 32 88 浏览量
2015-11-29
16:21:25
上传
评论 1
收藏 10KB RAR 举报
搬运工算我一个
- 粉丝: 0
- 资源: 1
最新资源
- 80632180.jpg
- 李旭国体注入追踪[5.0](1).zip
- semantic.c
- C语言基础-C语言编程基础之Leetcode编程题解之第39题组合总和.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第38题外观数列.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第37题解数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第36题有效的数独.zip
- C语言基础-C语言编程基础之Leetcode编程题解之第35题搜索插入位置.zip
- index.wxml
- C语言基础-C语言编程基础之Leetcode编程题解之第33题搜索旋转排序数组.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈