JEPG/main.cpp
2024-01-15 21:01:00 +08:00

124 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <fstream>
#include <list>
int main() {
std::fstream jpg_in;
jpg_in.open("/Users/dongl/code/Binarization/WechatIMG7.jpg", std::ios::in);
if (!jpg_in.is_open()) {
perror("jpg 打开失败");
}
// 校验是否是jpg文件
char file_header[2] = {0};
// ARM 小端字节序 jpg标识头是0xffd8 所以小端0xd8ff
uint16_t jpg_header = 0xd8ff;
// 读取标识头 n-1 个字读 3-1=2
jpg_in.get(file_header, 3);
if (memcmp(file_header, &jpg_header, 2) == 0) {
printf("FFD8 是jpg\n");
}
std::list<std::string> application_segments;
std::list<std::string> dqt_segments;
std::list<std::string> frame_segments;
std::list<std::string> huffman_segments;
std::list<std::string> scan_segments;
std::string segments_buf = "";
char key_marker = 0xFF; // 关键头
char head_marker = 0xD8; // 文件头
char app_marker = 0xE0; // app段
char dqt_marker = 0xDB; // 定义量化头
char frame_marker = 0xC0; // 帧段
char huffman_marker = 0xC4; // huffman表
char scan_marker = 0xDA; // 扫描段
char foot_marker = 0xD9; // 文件尾
//RSTn (Restart Marker)0xFFD0 至 0xFFD7表示重启标记用于在解码过程中进行数据恢复。
//APPn (Application Segment n)0xFFE1 至 0xFFEF表示其他应用段可以用于存储各种应用程序或设备的相关信息。
char buf[1024] = {0};
jpg_in.get(buf, sizeof(buf));
char FFE0[2];
uint16_t tmp1;
memcpy(&FFE0, &buf, 2);
memcpy(&tmp1, &FFE0, 2);
while (jpg_in.get(buf, sizeof(buf))) {
// 读取取出来的文件缓存
for (const auto &item: buf) {
// 查看是不是新的段
if (item == key_marker && segments_buf != "") {
// 添加段
// 添加应用段
if (segments_buf[1] == app_marker)
application_segments.push_back(segments_buf);
// 定义量化表
else if(segments_buf[1] == dqt_marker)
dqt_segments.push_back(segments_buf);
// 添加帧段
if (segments_buf[1] == frame_marker)
frame_segments.push_back(segments_buf);
// huffman段
if (segments_buf[1] == huffman_marker)
huffman_segments.push_back(segments_buf);
// 添加扫描段
else if(segments_buf[1] == scan_marker)
scan_segments.push_back(segments_buf);
// 文件尾
else if(segments_buf[1] == foot_marker) {
segments_buf = "";
break;
}
segments_buf = "";
}
// 添加到段缓存
segments_buf.push_back(item);
}
}
std::fstream segments_out;
segments_out.open("/Users/dongl/code/Binarization/jpg_segments_out.txt",
std::ios::out | std::ios::ate);
if (!segments_out.is_open()) {
perror("jpg_segments_out 打开失败");
}
segments_out << "application_segments:\n";
for (const auto &segments: application_segments) {
segments_out << segments;
segments_out << "\n";
}
segments_out << "dqt_segments:\n";
for (const auto &segments: dqt_segments) {
segments_out << segments;
segments_out << "\n";
}
segments_out << "frame_segments:\n";
for (const auto &segments: frame_segments) {
uint16_t tmp;
uint16_t frame_size;
memcpy(&tmp, segments.c_str()+2, 2);
memcpy(&frame_size, &tmp, 2);
segments_out << "frame_size: " << frame_size << "\n";
}
segments_out << "huffman_segments:\n";
for (const auto &segments: huffman_segments) {
segments_out << segments;
segments_out << "\n";
}
segments_out << "scan_segments:\n";
for (const auto &segments: scan_segments) {
segments_out << segments;
segments_out << "\n";
}
segments_out.close();
jpg_in.close();
return 0;
}