鼠标指针文件格式解析

news/2024/4/20 23:27:32/文章来源:https://blog.csdn.net/Amherstieae/article/details/129128154

鼠标指针文件格式解析

文章目录

  • 鼠标指针文件格式解析
    • windows
      • ico文件格式分析
        • 文件头:
        • 图像数据头段:
        • 图像数据段:
      • Ani动态光标格式解析
        • 数据结构:
        • 'anih'
        • 'seq '
        • **'rate'**
        • 'LIST'
      • cur静态光标文件格式解析
    • macOS
    • Linux

windows

ico文件格式分析

是一种图标文件,文件后缀名一般位icon或者ico

文件格式:文件头,图像数据头,图像数据两部分

文件头:

6字节

typeICONDIR = packed record					idReserved: SmallInt; // Reserved		保留位,必须为0idType: SmallInt; // Resource type		光标资源类型,作为ico时值为1,作为cur时值为2idCount: SmallInt; // Image Count		标记了文件中包含的图像数量end; // 6 bytes

图像数据头段:

紧接着文件头的就是图像数据头段了,它存放着文件中每个图像宽度、高度、颜色数量、数据段的偏移等信息,大小为16 * idCount。它是一个数组,每项数据16字节,定义如下:

typeICONDIRENTRY = packed recordbWidth: Byte; // Width of the image										图像宽bHeight: Byte; // Height of the image (2 * Height)						图像高bColorCount: Byte; // Number of colors in image (0 when >= 8 bpp)		图像颜色数bReserved: Byte; // Reserved											保留位数wPlanes: SmallInt; // Color Planes   (-> xHotspot [Cursor])				X坐标热点,与Y同为0时代表左上角wBitCount: SmallInt; // Bits per pixel (-> yHotspot [Cursor])			Y坐标热点dwBytesInRes: Integer; // How many bytes in this resource?				数据大小dwImageOffset: Integer; // Where in the file is this image?				数据偏移量end; // 16 bytes

读取完图像数据头段后,就可以知道文件中每个图标的大小,颜色位数了,同时直接根据数据段的偏移,读取图像数据段。图像数据的偏移是从文件最开始算起的。

图像数据段:

图像数据为多个图像的DIB数据,根据数据头段的偏移来定位。定位后,读取BIH信息。从BIH信息中,判断颜色位数大于8位的,记取XOR调色盘数据(小于8位的不存在XOR调色盘,只包含有一个MASK调色盘)。读取完XOR调色盘后,初始化图像DIB头,然后在文件中读取DIB数据。

存疑,没懂,先放着

最后又变成分析bmp文件了,像素值是原始数据

Ani动态光标格式解析

Ani动态光标格式解析 - 孤影对酌 - 博客园 (cnblogs.com)

文件类型关系:

bmp ∈ (ico == cur ) ∈ ani

数据结构:

ani文件结构在010里并没有直接的模板,而是以RIFF为开头标志位的文件,因此也可以使用RIFF模板来分析

本文是在孤影对酌师傅的文章基础上进行了一些备注,以供自己学习和分析

Ani文件中的数据是按区段存放的,区段数据结构如下:

标识符(4字节ASCII),数据长度(一个DWORD),数据

按照此规则来看Ani文件,文件起始12字节(12字节指以下标识符、数据长度和ACON三个部分)可以理解为标准文件头,除数据长度外,其余两个字段不会改变:

0x0000    52 49 46 46    标识符'RIFF'
0x0004    40 4D 00 00    数据长度,指整个文件的大小
0x0008    41 43 4F 4E    'ACON'

标准头之后,就是各个区段了,在孤影对酌师傅的探索中共发现了:‘anih’, ‘rate’, 'seq ', 'LIST’4种区段('seq '区段标识最后一个字符是空格,共4个字符)。

‘anih’

此区段数据长度恒为36,每4字节为一组,另外,数据长度36加上块大小4和名称4共44,里面存储的是一个结构体:

struct _anih
{DWORD    dwHeaderSize;     //结构体大小,恒为36DWORD    dwNumFrames;      //图像帧数,代表转为gif有多少帧,且该数与LISTchunk数量相等DWORD    dwNumSteps;       //播放帧数,当'seq '存在时可能大于dwNumFramesDWORD    dwWidth;          //图像宽度DWORD    dwHeight;         //图像高度DWORD    dwBitCount;       //色彩位数DWORD    dwNumPlanes;      //设备平面数DWORD    dwDisplayRate;    //显示频率(Time Delay,单位为1/60秒)DWORD    dwFlags;          //标志
};

dwFlags的第0位为1时,表示图像帧数据格式为Icon或Cursor,为0表示图像帧数据为位图raw数据,使用_anih结构中的尺寸、色彩深度等信息。

第1位解释为bool型,表示文件是否含有’seq '段。

'seq ’

010显示顺序位**先rate后seq **

此区段为可选段(不一定存在),段内的数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

0x0000    73 65 71 20    标识符'seq '
0x0004    24 00 00 00    数据长度
0x0008    00 00 00 00    数组元素[0],值为0表示此处显示第0帧图像
0x000C    01 00 00 00    数组元素[1],值为1表示第一帧图像
0x0010    02 00 00 00    [2],第2帧
0x0014    03 00 00 00    [3],第3帧
0x0018    00 00 00 00    [4],第0帧
0x001C    04 00 00 00    ...
0x0020    05 00 00 00
0x0024    01 00 00 00
0x0028    00 00 00 00

此区段存储的是播放顺序,当Ani文件播放时,按照DWORD数组下标递增,依次从此数组中取出图像帧号,再到存储图像帧数据的’LIST’段中获取对应的图像帧进行显示。所以在一次播放中,同一个图像帧可以出现多次。_anih结构中的dwNumSteps即为播放起始数组下标。

此区段不存在时,'LIST’中图像帧的顺序即为播放顺序,_anih结构中的dwNumSteps为播放起始帧号。

‘rate’

此区段为可选段,段内数据为一个DWORD数组,长度为 “区段数据长度” / sizeof(DWORD)。

表示每一帧的播放速率,gif的每一帧都是匀速播放的,rate的存在代表这个播放的速率不一定相同

0x0000    72 61 74 65    标识符'rate'
0x0004    24 00 00 00    数据长度
0x0008    0F 00 00 00    x 1/60秒 = Time Delay
0x000C    0F 00 00 00
0x0010    0F 00 00 00
0x0014    0F 00 00 00
0x0018    46 00 00 00
0x001C    0F 00 00 00
0x0020    0F 00 00 00
0x0024    0F 00 00 00
0x0028    0F 00 00 00

此区段内存储的为播放频率(Time Delay),同样以1/60秒为单位,当’seq '存在时,按相同下标与’seq '中的每个元素相对应,数组大小与’seq '相等。当’seq '不存在时,与’LIST’中图像帧相对应,数组大小等于_anih结构中的dwNumFrames。

‘LIST’

同样拥有12字节“标准头”,探索中发现,此区段内存储的数据有两种可能:

1.Ani文件的名称、作者

2.图像帧数据

当存储名称、作者信息时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    26 00 00 00    数据长度
0x0008    49 4E 46 4F    标识符'INFO'表示此列表为信息列表0x000C    49 4E 41 4D    标识符'INAM'表示名称
0x0010    0C 00 00 00    数据长度
0x0014    68 65 61 72 74 73 74 69 63 6B 31 00    字符串'heartstick1'0x0020    49 41 52 54    标识符'IART'表示作者
0x0024    06 00 00 00    数据长度
0x0028    68 75 61 6C 69 00    字符串'huali'

当存储图像帧数据时,格式为:

0x0000    4C 49 53 54    标识符'LIST',前12字节为“标准头”
0x0004    90 11 00 00    数据长度
0x0008    66 72 61 6D    标识符'fram'表明此列表为图像数据帧列表0x000C    69 63 6F 6E    标识符'icon'标识图像数据帧数据区段
0x0010    BE 08 00 00    数据长度
0x0014    00 00 02 00    图像数据
...       ...            多帧图像

至此,数据结构解析完毕。

此时有一个疑问,在icon的图像数据中,数据块的大小和图片的大小和像素有什么关系呢?

此时的这个图像数据是一个cur的文件格式

我们可以按照ico图标文件来进行分析

cur静态光标文件格式解析

很好,这次是彻底没有模板可以借助了

让我们从零开始分析一个文档吧

看了出题人写的文章,了解到cur文件也是和ico文件同属一宗,但唯一不同的是有一个标志位表明这是一个cur文件

这个标志位是全文档的第三个字节
在这里插入图片描述

唯二一篇可以参考的文章

从Windows动态指针到MacOS动态指针——ANI2GIF - 哔哩哔哩 (bilibili.com)

CURSOR 文件格式解析_jinhaijian的博客-CSDN博客

全称为CURSOR

因此,剩下的部分可以按照ico图标文件进行分析

macOS

从Windows动态指针到MacOS动态指针—— 在Windows上制作指针 - 哔哩哔哩 (bilibili.com)

是xml的形式,后缀名为cape文件

结构如下:

{'Author': '','CapeName': '','CapeVersion': 1.0,'Cloud': False,'Cursors': {'com.apple.coregraphics.Arrow': {'FrameCount': 1,'FrameDuration': 1.0,'HotSpotX': 0.0,'HotSpotY': 0.0,'PointsHigh': 32.0,'PointsWide': 32.0,'Representations': [b'']}},'HiDPI': False,'Identifier': 'local.error404.Unnamed.635739212.539397.A9D5CFB1-558B-46DD-95BB-3E8D6ED022D8.693110507.131993','MinimumVersion': 2.0,'Version': 2.0
}

例子

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict><key>Author</key><string>小蓝蓝</string><key>CapeName</key><string>蓝蓝的测试图标</string><key>CapeVersion</key><real>1.0</real><key>Cloud</key><false/><key>Cursors</key><dict><key>com.apple.coregraphics.Arrow</key><dict><key>FrameCount</key><integer>34</integer>					#代表帧数<key>FrameDuration</key><real>0.1</real><key>HotSpotX</key>						#代表生效的点的位置<real>0.0</real><key>HotSpotY</key><real>0.0</real><key>PointsHigh</key><real>32.0</real>						#代表图像大小,32*32<key>PointsWide</key><real>32.0</real><key>Representations</key><array><data>base64转图片,图片类型为tiff</data></array></dict><key>com.apple.coregraphics.IBeam</key><dict><key>FrameCount</key><integer>28</integer><key>FrameDuration</key><real>0.1</real><key>HotSpotX</key><real>0.0</real><key>HotSpotY</key><real>0.0</real><key>PointsHigh</key><real>32.0</real><key>PointsWide</key><real>32.0</real><key>Representations</key><array><data>base64转图片,图片类型为tiff</data></array></dict><key>com.apple.coregraphics.Move</key><dict><key>FrameCount</key><integer>24</integer><key>FrameDuration</key><real>0.1</real><key>HotSpotX</key><real>0.0</real><key>HotSpotY</key><real>0.0</real><key>PointsHigh</key><real>32.0</real><key>PointsWide</key><real>32.0</real><key>Representations</key><array><data>base64转图片,图片类型为tiff</data></array></dict><key>com.apple.cursor.17</key><dict><key>FrameCount</key><integer>52</integer><key>FrameDuration</key><real>0.1</real><key>HotSpotX</key><real>0.0</real><key>HotSpotY</key><real>0.0</real><key>PointsHigh</key><real>32.0</real><key>PointsWide</key><real>32.0</real><key>Representations</key><array><data>base64转图片,图片类型为tiff</data></array></dict><key>com.apple.cursor.18</key><dict><key>FrameCount</key><integer>31</integer><key>FrameDuration</key><real>0.1</real><key>HotSpotX</key><real>0.0</real><key>HotSpotY</key><real>0.0</real><key>PointsHigh</key><real>32.0</real><key>PointsWide</key><real>32.0</real><key>Representations</key><array><data>base64转图片,图片类型为tiff</data></array></dict></dict><key>HiDPI</key><false/><key>Identifier</key><string>local.小蓝蓝.蓝蓝的测试图标.1673433937.428604.949CA744-8B80-4D9F-A8F6-7DA1877E517E.1673433937.428639</string><key>MinimumVersion</key><real>2.0</real><key>Version</key><real>2.0</real>
</dict>
</plist>

Linux

文档好像很复杂捏

挖巨坑

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_71594.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java基础】IO流

IO流 最后一定要关闭流&#xff0c;防止资源泄露 字节流 一次读取1字节&#xff0c;8比特 FileInputStream import org.junit.jupiter.api.Test;import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;public class CopyBytes {pub…

分布式之Raft共识算法分析

写在前面 在分布式之Paxos共识算法分析 一文中我们分析了paxos算法&#xff0c;知道了其包括basic paxos和multi paxos&#xff0c;并了解了multi paxos只是一种分布式共识算法的思想&#xff0c;而非具体算法&#xff0c;但可根据其设计具体的算法&#xff0c;本文就一起来看…

DAMA认证|数据治理产业上规模需要做到“三化”

数据治理是开启数据安全体系化建设的第一步&#xff0c;需要从产业层面做大做强&#xff0c;支撑数据安全整体框架&#xff0c;为数据流通提供安全保障&#xff0c;推动促进数字化产业进一步发展。 规模化发展是数据治理产业的瓶颈&#xff0c;行业数字化业务的复杂性和过多的定…

Spring Boot 日志文件,你都会了吗?

目录 1、日志文件的作用 2、日志的使用 2.1、从程序中得到日志对象 2.2、使用日志 2.3、日志格式 3、日志级别 3.1、这样的日志级别有什么用&#xff1f; 3.2、日志级别分类和使用 3.3、日志级别设置 4、日志持久化 5、更简单的日志输出——lombok 5.1、对比 5.2、…

Linux下安装MySQL8.0的详细步骤(解压tar.xz安装包方式安装)

Linux下安装MySQL8.0的详细步骤 第一步&#xff1a;下载安装配置 第二步&#xff1a;修改密码&#xff0c;并设置远程连接&#xff08;为了可以在别的机器下面连接该mysql&#xff09; 第三步&#xff1a;使用Navicat客户端连接 搞了一台云服务器&#xff0c;首先要干的活就是…

批处理删除指定文件或文件夹

声明&#xff1a;1-2节参考了 https://blog.csdn.net/weixin_43960383/article/details/1243673841. DEL1.1 DEL 的命令参数使用 del 命令能指定文件&#xff0c;Del (erase)[Drive:][Path]FileName指删除指定文件。指定要删除的文件或文件集的位置和名称。语法格式如下&#x…

Unity毛发系统TressFX Exporter

Unity 数字人交流群&#xff1a;296041238 一&#xff1a;在Maya下的TressFX Exporter 插件安装步骤&#xff1a; 1. 下载Maya的TressFX Exporter插件 下载地址&#xff1a;TressFX Exporter 链接&#xff1a;https://github.com/Unity-China/cn.unity.hairfx.core/tree/m…

利用OpenCV的函数equalizeHist()对图像作直方图均衡化处理

如果一幅图像的灰度值集中在某个比较窄的区域&#xff0c;则图像的对比度会显得比较小&#xff0c;不便于对图像的分析和处理。 图像的直方图均衡化可以实现将原图像的灰度值范围扩大&#xff0c;这样图像的对比度就得到了提高&#xff0c;从而方便对图像进行后续的分析和处理…

Cosmos 基础教程(二)-- Run a Node, API, and CLI

有很多不同的方法来运行Cosmos区块链的节点。您将探索如何使用simapp 进行此操作。 1、编译simapp Cosmos SDK存储库包含一个名为 simapp 的文件夹。在这个文件夹中&#xff0c;您可以找到运行Cosmos SDK模拟版本的代码&#xff0c;这样您就可以在不实际与链交互的情况下测试…

化解射频和微波设计挑战的六个技巧

即使是最自信的设计人员&#xff0c;对于射频电路也往往望而却步&#xff0c;因为它会带来巨大的设计挑战&#xff0c;并且需要专业的设计和分析工具。这里将为您介绍六条技巧&#xff0c;来帮助您简化任何射频PCB 设计任务和减轻工作压力&#xff01; 1、保持完好、精确的射频…

由浅入深,一起来刷Java高级开发岗面试指南,面试必定无忧!

前言 我只想面个CV工程师&#xff0c;面试官偏偏让我挑战造火箭工程师&#xff0c;加上今年这个情况更是前后两男&#xff0c;但再难苟且的生活还要继续&#xff0c;饭碗还是要继续找的。在最近的面试中我一直在总结&#xff0c;每次面试回来也都会复盘&#xff0c;下面是我根…

【2022.12.9】Lammps+Python 在计算g6(r)时遇到的问题

目录写在前面绘制g6( r )执行步骤【updated】如何检查图像的正确性&#xff1a;不是编程问题&#xff0c;而是数学问题的一个小bug废稿2则&#xff1a;写在前面 全部log&#xff1a; 【2022.11.16】LammpsPythonMATLAB在绘制维诺图时遇到的问题 绘制g6( r )执行步骤【updated…

面试中经常被问到的【宏定义】,改变你对【C\C++】中宏定义的认识。

最近遇到挺多宏定义的代码&#xff0c;其实挺烦的&#xff0c;每次看复杂的宏定义看到一半就懵了&#xff0c;今天盘一盘它。本篇设计宏定义的原理、使用方法、使用技巧。 目录 一、宏定义原理 二、宏定义定义复杂功能函数 2.1 定义注册函数 三、宏定义实现条件编译 四、宏…

扬帆优配|五千亿巨头一度涨停! 4天3倍,港股又现“狂飙”股!

周一&#xff0c;A股三大指数走势分化。到午间收盘&#xff0c;沪指震荡走高涨近1%&#xff0c;深证成指涨0.75%&#xff0c;创业板指继续弱势调整。 盘面上&#xff0c;钢铁、煤炭、大金融等权重板块团体走强&#xff0c;三大通讯运营商一同拉升&#xff0c;其间我国电信盘中一…

超25亿全球月活,字节依然没有流量

&#xff08;图片来源于网络&#xff0c;侵删&#xff09; 文|螳螂观察 作者| 搁浅虎鲸 注意看&#xff0c;这个男人叫梁汝波&#xff0c;是字节跳动的联合创始人&#xff0c;也是接棒张一鸣的新任CEO。 在字节跳动十周年之际&#xff0c;他发表了激情昂扬的演讲。“激发创…

linux高级命令之互斥锁

互斥锁学习目标能够知道互斥锁的作用1.互斥锁的概念互斥锁: 对共享数据进行锁定&#xff0c;保证同一时刻只能有一个线程去操作。注意:互斥锁是多个线程一起去抢&#xff0c;抢到锁的线程先执行&#xff0c;没有抢到锁的线程需要等待&#xff0c;等互斥锁使用完释放后&#xff…

02- OpenCV绘制图形及图像算术变换 (OpenCV基础) (机器视觉)

知识重点 OpenCV用的最多的色彩空间是HSV. 方便OpenCV做图像处理img2 img.view() # 浅拷贝img3 img.copy() # 深拷贝split(mat) 分割图像的通道: b, g, r cv2.split(img) # b, g, r 都是数组merge((ch1, ch2, ch3)) 融合多个通道cvtColor(img, colorspace): 颜…

Learning C++ No.11【string类实现】

引言&#xff1a; 北京时间&#xff1a;2023/2/19/8:48&#xff0c;昨天更新了有关进程状态的博客&#xff0c;然后在休息的时候&#xff0c;打开了腾讯视屏&#xff0c;然后看到了了一个电视剧&#xff0c;导致上头&#xff0c;从晚上6点看到了10点&#xff0c;把我宝贵的博客…

【NestJS】中间件

中间件是在路由处理程序之前调用的函数&#xff0c;所以在中间件函数中可以访问请求和响应。 中间件函数需要执行 next() 将控制传递给下一个中间件函数&#xff0c;否则请求会被挂起。 可以使用 nest g mi XXX 创建中间件。 局部中间件 nest g res usernest g mi ajax、编写…

klog bug:仅输出到日志文件,不打印到命令行/stderr

一、 问题描述 开发k8s插件&#xff0c;使用klog作为日志工具&#xff0c;开发完成发现在设置将日志打印到文件后&#xff0c;Error级别的日志信息仍然会输出到命令行&#xff0c;过多日志打印会使后期将服务部署于docker有卡死的风险&#xff08;docker的bug&#xff0c;日志…