


开发能读写分层图像文件且不丢失数据的库
开发或维护处理分层图像二进制格式的库时使用。它会把底层解析与面向用户的API分开,按顺序读写文件各部分,保留未知数据,重建图层组,用读-写-再读的往返测试检查改动,并通过自动化流程发布。
要使用这个AI规则
## 只安装任务需要的依赖,并使用项目自带的命令
更改代码前,先阅读贡献者文档。
使用仓库的环境管理器和任务命令,不要从无关的运行时调用工具。
只设置任务所需的依赖组:
- 为解析和测试安装默认开发依赖;
- 涉及合成或光栅化时,添加可选渲染组;
- 仅在构建文档时包含文档依赖组;
- 某些新的运行时与操作系统组合可能不支持可选的科学计算包或绘图包。
使用规范命令执行以下操作:
- 构建已编译的扩展模块和分发产物;
- 运行包含覆盖率统计的完整测试套件;
- 通过节点标识符运行单项测试;
- 测量特定行为时,运行不含覆盖率统计的测试;
- 运行代码检查、格式化和静态类型检查;
- 构建HTML文档,并检查文档中注明的输出目录。
不要把可选渲染依赖视为核心解析要求。
如果请求的可选操作缺少所需依赖,应给出明确的安装说明。
## 把底层二进制读写与面向用户的API分开
将底层二进制解析与高层用户API分开。
底层:
- 按照规范读取和写入原始二进制格式;
- 对文件头、记录、带标签的数据块、描述符、图像资源、蒙版、通道和压缩数据进行建模;
- 提供明确的`read(fp)`和`write(fp)`序列化方法;
- 保留尚无法解释的未知数据。
高层:
- 通过易用的接口封装底层文档结构;
- 从扁平二进制记录中重建面向用户的对象树;
- 提供图层类型、效果、蒙版、渲染和文档操作;
- 在契约允许时,将高成本解析推迟到数据被访问之时。
内部代码应从定义底层具体类型的模块中导入这些类型。
公共使用方应通过受支持的包导出项使用它们。
除非出于兼容性需要,否则不要在公共方法中泄露底层表示细节。
## 按顺序读写文件的各个部分,并保留未知数据
将各部分的顺序、长度、签名和数值宽度视为文件格式契约的一部分。
典型的分层图像文件包含五个顺序排列的部分:
1. 固定大小的文件头,包含签名、版本、尺寸、通道和颜色模式。
2. 颜色模式数据,例如索引调色板。
3. 图像资源,例如颜色配置文件、参考线和缩略图。
4. 图层和蒙版信息,包含图层记录、通道数据和带标签的数据块。
5. 扁平化的合成图像数据。
规范要求时,应验证固定的文件头大小,例如26字节。
按顺序读取和写入各部分;不要根据便于使用的内存对象推断边界。
序列化方法应返回写入的字节数,使调用方能够核对大小。
往返处理时,将未知有效载荷保留为字节,不要将其丢弃。
## 从扁平的记录列表重建图层组
当格式以扁平列表存储层级时,应解释明确的边界记录,不要仅凭相邻关系作出假设。
识别组开始和组结束标记,并使用栈或经过验证的等效状态机重建父子关系。
至少测试以下情况:
- 组外的普通记录;
- 一个包含多个子项的组;
- 嵌套组;
- 空组;
- 格式错误或不成对的边界标记;
- 原始记录顺序的保留情况。
保留扁平的底层记录列表用于序列化,同时通过高层API提供树结构。
不要让树结构重建过程修改无关的二进制记录。
## 通过注册表添加带标签的数据块,不支持的块原样保留
为二进制结构提供共享基础契约,支持类级读取和实例级写入。
由小型基本元素递归组合复杂结构。
在以下方面一致地使用带类型的数据类功能:
- 生成初始化方法;
- 字段验证;
- 类型提示;
- 受控的表示形式;
- 必要时可预测地转换为元组或序列。
验证器应与类型注解保持一致;对于链式构造器或感知具体类的构造器,应使用返回相同实例类型的返回类型。
对于可扩展的带标签数据块:
- 使用固定宽度的标签键及其关联有效载荷;
- 通过注册表将已知标签映射到处理器类;
- 读取标签的类型化数据前,先检查该标签;
- 完整保留不受支持的数据块,以便日后写回;
- 将公共便捷访问与内部记录访问分开。
不要注册会消耗字节却无法忠实写回这些字节的处理器。
## 加快压缩和像素计算,同时不破坏回退路径
优化性能敏感路径前,先进行度量。
可用时,对高成本的压缩或解压缩使用已编译的编解码器,但要保留正确的纯语言实现作为回退。
当延迟解析不改变语义时,对蒙版、效果和通道数据使用延迟加载。
如果数组向量化能够提高吞吐量,则将其用于大规模像素和混合模式计算。
每项优化都必须保留:
- 二进制输出兼容性;
- 错误行为;
- 确定性结果;
- 未经优化的回退实现;
- 对已编译依赖或可选依赖不可用环境的支持。
使用相同的测试夹具检验优化实现和回退实现。
不要为了提高速度而悄然改变结果。
## 用读-写-再读的测试检查改动,并添加类型提示
按照包结构组织测试,将底层二进制测试与高层API测试分开。
将具有代表性的二进制测试夹具放在专用目录中,并对多个文件进行参数化测试。
将往返验证作为主要不变量:
1. 读取二进制文件。
2. 修改一个受控字段。
3. 写入文件。
4. 再次读取结果。
5. 验证预期变更,并确认无关数据得到保留。
为每个新的函数签名添加正确的类型提示。
使数据类验证器与类型注解保持一致。
对于返回自身类实例的方法,使用项目的兼容类型。
开发期间运行针对性测试,完成前再运行相关的完整套件、代码检查、格式化和类型检查。
检查覆盖率变化,不要只把覆盖率百分比当作正确性的证明。
## 通过自动化流程发布,并明确说明不支持的功能
按照项目文档中的版本标准选择发布版本,包括正式版、预发布版和发布后版本。
在变更日志的新版本标题下,总结自上一个标签以来的更改。
使用自动打标签所要求的准确发布分支模式。
针对主分支提出发布请求,并且只在获得批准后合并。
让已配置的自动化流程为合并后的准确提交打标签、构建分发包、创建托管发布并发布到包注册表。
当发布工作流负责打标签时,不要手动创建标签。
确保自动化凭据只具备触发下游工作流所需的最低权限,并且绝不将其暴露。
声称某项功能可用前,检查文档中关于以下事项的限制:
- 没有字体引擎时的文本渲染;
- 受支持和不受支持的调整操作;
- 已实现的图层效果子集;
- 嵌入对象的提取与编辑之间的区别;
- 在不解释未知数据的情况下将其保留。
明确说明不受支持的行为,不要静默地用近似行为代替。
最后报告已运行的测试、未执行的可选路径、兼容性风险,以及影响所请求更改的任何限制。
