弄了这么些天,还没有找到我要的像素点的RGBA值。先这样放下。va_arg几个月的间断。数组传递又一塌糊涂。。。

#include<iostream>
#include<fstream>
#include <stdarg.h> //--尝试用那个三个点的可变参数...所以要这个头文件,不用头文件就要像宽度高度一样连续5个读取
using namespace std;
typedef unsigned char byte;//新名//------------------下面这些是宏,左边名换右边的字符串或数字或代码
#define mark_NUm 8
#define IS_PNG(x) (0x89==x[0])&&(0x50==x[1])&&(0x4E==x[2])&&(0x47==x[3])&&(0x0D==x[4])&&(0x0A==x[5])&&(0x1A==x[6])&&(0x0A==x[7])
#define MARK_LOC(loc_0x) (loc_0x+0x04)//返回此块标识在文件中头地址
#define DATA_LOC(loc_0x) (loc_0x+0x08)//返回此块数据在文件中头地址
#define END_LOC(loc_0x,imp_0x)  (loc_0x+0xC+imp_0x)//返回此块的下一块地址
#define FIND_IHDR(x,off)(('I'==x[off])&&('H'==x[off+1])&&('D'==x[off+2])&&('R'==x[off+3]))
#define FIND_IDAT(x,off)(('I'==x[off])&&('D'==x[off+1])&&('A'==x[off+2])&&('T'==x[off+3]))
#define FIND_IEND(x,off)(('I'==x[off])&&('E'==x[off+1])&&('N'==x[off+2])&&('D'==x[off+3]))
#define IHDRloc 0x08
#define widthloc   0x10
#define heigtloc  0x14
#define BitDepthloc 0x15//图像深度
#define ColorTypeloc 0x16
#define CompressionMethodloc 0x17//压缩方法(LZ77派生算法)
#define FilterMethodloc 0x18//滤波器方法
#define InterlaceMethodloc 0x19 //--------------自己定义的class类,主要是IHDR块class PngMsg
{
private :     byte width[4];//图像宽度,单位像素byte height[4];//图像高度,单位像素byte BitDepth;//图像深度//索引彩色1.2.4.8;灰度1.2.4.8.16;真彩色8.16byte ColorType;//0灰度1.2.4.8.16;2真彩色8.16;3索引彩色1.2.4.8//4带α通道数据的灰度8.16;6带α通道数据的真彩色8.16byte CompressionMethod;//压缩方法(LZ77派生算法)byte FilterMethod;//滤波器方法byte InterlaceMethod;//0:非隔行扫描;1:Adam7int IDATloc;int DATNUM;int IENDloc;int offSet;
public:   void PNGReadImageFile(const char* Imgname);void display(); template<typename T>void Dis(int count, T* O_O, ...);template<typename T>void Read(ifstream* imgF,int count, T  *O_O, ...);//写过java的数据库。发现有三个点表可扩展的。C的就来试试啦yoho!};//-----用来测试输出的template<typename T>//函数模版void PngMsg::Dis( int count,T* O_O, ...){va_list theThis;va_start(theThis,count);// _crt_va_start(a,b)把b的地址+b这个的偏移量加给进去=下一个的地址;  for (; count > 0; count--){ T* temp=va_arg(theThis, T*);cout << hex << ((*temp) &(0xFF))<< endl;}va_end(theThis);}//---使用三个点的读取。传入的是地址。template<typename T>void PngMsg::Read(ifstream *imgF, int count, T *O_O, ...){va_list theThis;//参数串va_start(theThis, count);//定位在给出的参数名的下一个位置O_O for (; count > 0; count--){ //T** temp;//temp = new T*;//(*temp) = va_arg(theThis, T*); //imgF->read((char*)(*temp), sizeof(T));//cout << hex << ((*(*temp)) &(0xFF)) << " ";//delete temp;//================================T* temp = va_arg(theThis, T*); //_crt_va_start(curLOC,type)把curLOC的当前地址上的数值返回;并把原来curLOC+type长度=下一个的地址;imgF->read((char*)temp, sizeof(*temp));//cout <<((*temp) &(0xFF)) << " ";}va_end(theThis);}//暂时没有用处void PngMsg::display(){cout << "宽" << hex << width << endl;cout << "高" << height << endl; }void PngMsg::PNGReadImageFile(const char* Imgname)
{ifstream imgF(Imgname, ios::binary);if (!imgF) {cerr << "open error!" << endl;abort();}byte mark[mark_NUm];imgF.read((char*)mark, sizeof(mark));if (!(IS_PNG(mark))){imgF.close();cerr << "no PNG!" << endl;abort();}//=========================================================基础数据获取imgF.seekg(widthloc);imgF.read((char*)width, sizeof(width));//imgF.seekg(heigtloc);//顺序与上面连接就注释掉了imgF.read((char*)height, sizeof(height)); //imgF.seekg(BitDepthloc);//顺序与上面连接就注释掉了Read(&imgF, 5,&BitDepth, &ColorType,& CompressionMethod, &FilterMethod, &InterlaceMethod);//循环读入对应数据//Dis(5, &BitDepth, &ColorType, &CompressionMethod, &FilterMethod, &InterlaceMethod); //测试显示对应数值for (int i = 0; i < 4; i++)cout << (width[i] & 0xff) << ":";for (int i = 0; i < 4; i++)cout << (height[i] & 0xff) << ":";//==========================================================定位IDAT块imgF.seekg(0, ios::end);int size = imgF.tellg();offSet = IHDRloc;int imp = 0;for (bool fg = true; fg&& offSet < size;){//cout << "offset:" << offSet << " size:" << size << "imp" << imp << endl;imgF.seekg(offSet);imgF.read((char*)mark, sizeof(mark));//cout << (0xff & mark[0]) << (0xff & mark[1]) << (0xff & mark[2]) << (0xff & mark[3]) << endl;imp = mark[2]* 0x100 + mark[3];//cout << "offset:"<<offSet << " size:" << size <<"imp"<<imp<< endl;cout << (0xff & mark[4]) << (0xff & mark[5]) << (0xff & mark[6]) << (0xff & mark[7]) << endl;if (FIND_IDAT(mark, 4)) fg = false;else{offSet = END_LOC(offSet,imp);}}if (offSet >= size ){imgF.close();cerr << "PNG 数据丢失:IDAT" << endl;abort();}IDATloc = MARK_LOC(offSet);DATNUM = imp;//-----------------------------------------------------------------------int pixscnt;pixscnt = (width[2] * (0x100) + width[3])*(height[2] * (0x100) + height[3]);cout << pixscnt << endl;//像素//--------------------------------------------------------------------------- offSet = END_LOC(offSet, imp);imp = 0;for (bool fg = true; fg&& offSet < size;){cout << "offset:" << offSet << " size:" << size << "imp" << imp << endl;imgF.seekg(offSet);imgF.read((char*)mark, sizeof(mark));cout << (0xff & mark[0]) << (0xff & mark[1]) << (0xff & mark[2]) << (0xff & mark[3]) << endl;imp = mark[2] * 0x100 + mark[3];cout << "offset:" << offSet << " size:" << size << "imp" << imp << endl;cout << (0xff & mark[4]) << (0xff & mark[5]) << (0xff & mark[6]) << (0xff & mark[7]) << endl;if (FIND_IEND(mark, 4)) fg = false;else{offSet = END_LOC(offSet, imp);}}if (offSet >= size){imgF.close();cerr << "PNG 数据丢失:IEND" << endl;abort();}IENDloc = MARK_LOC(offSet);//==================================================/*  int i = 0;for (; i < 4; i++)cout << (width[i] & 0xff) << ":"; for (int i = 0; i < size; i++){cout << hex << (mark[i] & 0xff) << ":";if (i % 4 == 0)cout << endl;}*/imgF.close(); //WriteImage(imgbuf, size);
}
int main(){//readImageFile("mm.png");//C/C++的//ReadImageFile("mm.png");//C++的 PngMsg t;t.PNGReadImageFile("mm.png");system("pause");return 0;}

png数据块IHDR_IDAT_END读取相关推荐

  1. Linux文件存储结构,包括目录项、inode、数据块

    2019独角兽企业重金招聘Python工程师标准>>> 先说inode 理解inode,要从文件储存说起.文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sec ...

  2. 基于STM32的RC522模块读写数据块以及电子钱包充值扣款系统的设计

    目录 前言 STM32F103ZET6单片机 RC522 相关引脚连接 准备工作 Mifare卡 读卡过程 最终实现功能 代码 RC522.C代码 RC522.H main.c led.h 前言 本人 ...

  3. oracle数据块格式小结

    Oracle数据块可分为三层  更细化 Cache layer--20字节,包含DBA.块类型.块格式.SCN:数据块被读取时进行完整性检查,确保没有损坏或fracture,即块更新信息只有部分被写入 ...

  4. C++用snap7库对PLC数据块进行读写

    目录 必须读懂的PLC 进行读写 16进制HEX和10进制DEC转换 参考 必须读懂的PLC DBg_s7Client.DBRead(nDBNum, nVarAddr, nSize, byData); ...

  5. strace分析mysql_使用Strace跟踪oracle读取数据块

    使用Strace跟踪oracle读取数据块 oracle是一个C语言程序,通过调用系统的io函数来实现io的过程,在linux下可以通过strace工具来 很方便查看进程对io函数的调用过程. 测试场 ...

  6. 【操作系统】磁盘转速速度为7200PRM,平均寻道时间为6ms,每磁道存储1MB数据。如果数据块大小为4KB,则读取一块数据时,数据平均传输速率为

    磁盘转速速度为7200PRM,平均寻道时间为6ms,每磁道存储1MB数据.如果数据块大小为4KB,则读取一块数据时,数据平均传输速率为 背景知识 7200PRM = 7200r/min = 120r/ ...

  7. 关于 RMAN 备份 数据块 一致性的讨论

    今天和 杭州恒生 的一个朋友讨论一个RMAN 在备份时数据块一致性的问题. 关于RMAN 的备份原理参考blog: RMAN 系列(一)---- RMAN 体系结构概述 http://blog.csd ...

  8. 索引块与数据块的区别

    一.索引块与数据块的区别 大家都知道,索引可以提高检索效率,因为它的二叉树结构以及占用空间小,所以访问速度块.让我们来算一道数学题:如果表中的一条记录在磁盘上占用 1000字节的话,我们对其中10字节 ...

  9. Oracle的逻辑结构(表空间、段、区间、块)——Oracle数据块(一)

    Oracle 的逻辑结构 ( 表空间.段.区间.块 ) --块 Oracle 存储数据的最小单位是数据块.Oracle 管理 数据库 数据文件的存储空间被称为数据块,一个数据块是数据库使用的最小数据单 ...

最新文章

  1. Linux环境网络库
  2. SLA 99.99%以上!饿了么实时计算平台3年演进历程
  3. java Annotation 简单理解
  4. 博客搬到CSDN了,以后就老实的呆在这儿吧~~
  5. OpenStack(二)——Keystone组件
  6. 算法训练 字符串的展开c语言
  7. [翻译]VC++中创建并使用自定义控件
  8. 关闭共享的DOS命令
  9. 利息高的贷款通过率会高一些吗?
  10. k8s上部署java应用(activiti)实践
  11. Servlet(四):转发与重定向、路径问题
  12. 对于elemnet-ui的el-upload的使用总结(移除上传文件判断,action等问题)
  13. Oracle的diag文件可以删除,oracle11g rac diag/tnslsnr/pgis2/listener/alert 中的文件能删除吗...
  14. springboot2 oauth2 jwt认证服务器和资源服务器
  15. git基于某个分支新建分支
  16. 通过openwrt路由器访问桥接模式下的光猫
  17. c语言报告收获,c语言学习心得体会(最新整理)
  18. [项目管理]工业工程理论在软件项目中的实践
  19. Springboot源码分析第一弹 - 自动装配实现
  20. SQL Server Management Studio(SMSS)删除连接记录

热门文章

  1. 虚幻游戏武器素材推荐
  2. 计算机网络——ARPANET设计思想
  3. java redis 去重_redis去重方案
  4. 微信小程序实现非常简单的数字时钟
  5. js---javascript BOM
  6. 2022年山东省安全员C证特种作业证考试题库及在线模拟考试
  7. c++编写函数把华氏温度转换为摄氏温度。
  8. 全球及中国色彩滤镜矩阵行业研究及十四五规划分析报告
  9. 深度:分析了279家海外老年行业创新创业公司,看到了老年行业创新趋势与重点机会!
  10. 进击的爬虫-003-beautifulsoup实现猫眼电影前100爬取