B67687/Ithmb-Codec

GitHub: B67687/Ithmb-Codec

该项目是一个基于 Rust 开发的 Apple .ithmb 缩略图缓存文件编解码器,解决了在非苹果环境下读取和转换早期 iPod/iPhone 专有图像格式的问题。

Stars: 0 | Forks: 0

ITHMB Codec # ImageGlass v10 的 ITHMB 编解码器 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Rust](https://img.shields.io/badge/Rust-1.85+-5C3A21?style=flat-square&logo=rust&logoColor=white)](https://rust-lang.org) [![Platform](https://img.shields.io/badge/platform-linux--x64%20%7C%20linux--arm64%20%7C%20macos--x64%20%7C%20macos--arm64%20%7C%20windows--x64-lightgrey)](README.md#build-from-source) 概念渲染图 概念渲染图 — 非实际截图。
Built with AI assistance — see CREDITS.md
DeepSeek v4 Flash Oh My OpenAgent Harness OpenCode Oh My OpenAgent

一个纯 Rust 编解码器库、CLI 工具和 ImageGlass v10 插件,用于解码和编码 Apple `.ithmb` 缩略图缓存文件 —— 这是 iPod Classic/Nano/Photo/Video、iPhone 2G 和 iPod Touch 用于存储照片和专辑封面缩略图的格式。 **核心特性** - 54 个内置配置文件(+ 1 个推测性的已禁用配置),涵盖已知的 iPod/iPhone 格式 - 8 个解码器(RGB565、RGB555、ReorderedRGB555、UYVY、YCbCr420、CLCL、CL、JPEG) - 7 个合成编码器,适用于所有原始格式 - 经过往返验证的测试(486+ 个通过) - PhotoDB/ArtworkDB 读取、写入和完整性检查 - 多帧 F 前缀原始文件支持 - 用于 iPhone 兼容性的 BGR15 通道交换 - 通过纯 Rust JPEG 解码器进行 JPEG 嵌入式 T 前缀解码 - 跨平台(Linux x64/ARM64、macOS x64/ARM64、Windows x64) - C ABI 库,可 FFI 集成到现有应用程序中 - 用于解码、检查和帧提取的 CLI 工具 - YUV 转换路径的全面 SIMD 加速(SSE2+AVX2+NEON 运行时分发) **T 前缀** — 包含嵌入的 JPEG。 ✅ 完全支持(已在 1,183 个真实文件上验证)。 **F 前缀**(例如 `F1019_1.ithmb`)— 原始未压缩缩略图(RGB565、RGB555、UYVY、YCbCr420、CLCL nibble-chroma)。 ✅ 与 iOpenPod 经验验证的集合(跨越多个 iPod 型号的 50+ 个配置文件)进行了交叉比对,并在真实的 iPod Classic 6G 样本(F1061/F1055/F1060)上得到确认。
🎖️ 特别感谢 SaviiOpenPod 社区
感谢他们提供硬件验证 —— 购买多个 iPod 型号并跨固件版本测试配置文件。配置文件的调整融合了来自 iOpenPod 社区的反馈。
## 目录 - [工作原理](#how-it-works) - [致谢](#acknowledgments) - [安装](#install) - [从源码构建](#build-from-source) - [测试与验证](#testing--validation) - [架构](#architecture) - [CLI 工具](#cli-tool) - [C ABI](#c-abi) - [配置参考](#profile-reference) - [限制](#limitations) - [故障排除](#troubleshooting) - [开发](#development) - [对生态系统的贡献](#contributions-to-the-ecosystem) - [更新日志](#changelog) - [许可证](#license) ## 工作原理 1. **Peek 读取** — 将整个文件读入内存(峰值内存主要由解码后的位图占据,对于 iPhone 照片通常为几 MB)。32 MB 的大小限制可防止因异常输入导致 OOM。 2. **JPEG 扫描** — 检查在 512 字节内是否出现 JPEG SOI 标记(`FF D8`),随后跟随 JFIF 或 Exif。如果匹配,则提取 JPEG payload(SOI→EOI),通过 `jpeg-decoder` 解码,并通过配置系统公开其 EXIF 方向标签(0x0112)。 3. **原始回退** — 如果未找到 JPEG,解码器会将前 4 个字节(大端序前缀)与 54 个已知配置进行匹配,并运行相应的原始解码器(RGB565、RGB555、Reordered RGB555、UYVY、YCbCr420、YUV422 interlaced、CLCL nibble-chroma 或 CL per-pixel chroma)以生成 BGRA 输出。如果前缀与任何已知配置均不匹配,则在拒绝该文件之前,会扫描其内部嵌入的 JPEG 标记(字节级 carving)。可以通过 `profiles.json` 激活其他解码器变体:YCbCr 4:2:0 的色度平面交换、per-pixel vs shared nibble chroma、字节序切换、隔行场序、填充帧处理以及 BGR15 格式的通道交换。 4. **PhotoDB/ArtworkDB** — Apple 的 iPod 缩略图数据库(PhotoDB、ArtworkDB)使用基于二进制块的格式(MHFD→MHSD→MHNI 条目)。当文件以 `mhfd` 开头时,编解码器会解析块树,提取单个缩略图(内联像素数据或外部 `.ithmb` 文件引用),并通过匹配其格式 ID 的原始解码器对每个缩略图进行解码。支持读取、写入和完整性检查。 ### 文件大小限制 ## 安装 ### 库 将 `ithmb-core` crate 添加到您的 `Cargo.toml` 中: ``` [dependencies] ithmb-core = { git = "https://github.com/B67687/ithmb-codec" } ``` 或者直接使用 CLI 二进制文件(参见[发布版本](https://github.com/B67687/ithmb-codec/releases))。 ### CLI 工具 ``` cargo install --git https://github.com/B67687/ithmb-codec ithmb-cli ``` 这将安装 `ithmb` 二进制文件。 ## 从源码构建 ### 环境要求 - [Rust](https://rust-lang.org) 1.85 或更高版本(edition 2024) - C 编译器工具链(用于原生代码链接) ### 构建 ``` # Clone 仓库 git clone https://github.com/B67687/ithmb-codec.git cd ithmb-codec # 以 release 模式构建所有内容 cargo build --release ``` 该工作区会生成五个产物: | Crate | 二进制/库文件 | 位置 | |-------|---------------|----------| | `ithmb-core` | `libithmb_core.rlib`(静态库) | `target/release/` | | `ithmb-cli` | `ithmb`(CLI 二进制文件) | `target/release/` | | `ithmb-core-cabi` | `libithmb_core_cabi.so` / `.dylib` / `.dll`(C ABI 动态库) | `target/release/` | | `ithmb-python` | `libithmb_python.so` (PyO3 abi3-py312) | `target/release/` | | `ithmb-gen` | `ithmb-gen`(示例生成器二进制文件) | `target/release/` | ### 交叉编译 为其他目标进行交叉编译需要通过 `rustup target add` 安装相应的目标工具链: ``` # Linux x86-64 (x64 主机上的默认设置) cargo build --release # Linux ARM64 (aarch64) rustup target add aarch64-unknown-linux-gnu cargo build --release --target aarch64-unknown-linux-gnu # macOS ARM64 rustup target add aarch64-apple-darwin cargo build --release --target aarch64-apple-darwin # Windows x64 (从 Linux 交叉编译) rustup target add x86_64-pc-windows-gnu cargo build --release --target x86_64-pc-windows-gnu ``` 启用 SIMD 加速: ``` cargo build --release --features simd ``` 可用特性:`simd`(SSE2/AVX2/NEON YUV 转换)、`cache`(LRU 原始文件缓存)、`metrics`(解码时间计数器)。 ## 测试与验证 ``` cargo test ``` 跨越 12 个套件的 **486+ 个测试**:roundtrip(RGB565:65,536 个值,RGB555:32,768 个)、fuzz(覆盖所有 8 个解码器的 350+ 个输入 + 10,000 次随机字节突变)、2 个 libfuzzer 目标(120 万+ 次迭代,0 次崩溃)、并发压力测试、统计验证 + golden vector 验证、YUV 容差、解析器、推测性解码器路径(CL、CLCL、旋转、色度交换)、buffer-too-small 防护、trailing-padding 容差、JPEG carving 回退、多帧原始解码、旋转 roundtrip、BGR15 通道交换、PhotoDB roundtrip 写入/完整性/JPEG blob 解码、特定设备格式表、损坏 fuzz、格式 ID 配置测试、编码器辅助工具(隔行场 + BT.601 颜色转换)以及解码器回退路径。 整个工作区的 **12 个测试套件**,全部通过。 **真实设备验证:** - **iPod Classic 6G (Reuhno):** 成功解码了真实的 F1061/F1055/F1060 .ithmb 文件(BGR15 通道交换,MSB 复制 —— 均确认正确)。30 个参考 PNG 与解码器输出匹配。 - **iOpenPod (TheRealSavi):** 在购买并测试的多个 iPod 型号上经验性地验证了 50+ 个配置。确认“iPod Nano 和 iPod Classic 型号没有已知问题”。我们的 54 个配置源自相同的格式 ID 源 —— 硬件验证由 iOpenPod 的测试涵盖。参见 [iOpenPod#140](https://github.com/TheRealSavi/iOpenPod/issues/140)。 - **iPhone 5 (iOS 7):** 956 个 T 前缀文件 —— 100% 提取 - **Jakarade.com F00-F08:** 227 个公开的 T 前缀文件 —— 100% JPEG+EXIF 检测 - **MVS CTF 2026 (iOS 18):** 扫描了 iPhone 14 Plus 的完整文件系统映像 —— 找到了 3 个 `.ithmb` 文件,但使用的是不同的专有格式(iOS Photos 框架,此编解码器无法解码) ## 架构 该项目被组织为一个包含五个 crate 的 Rust 工作区: ### ithmb-core(库) 核心解码库。所有解码器逻辑都位于此处;用于 FFI、CLI 或其他语言的封装都会调用此 crate。 按领域组织的 **21 个模块**: | 模块 | 用途 | |--------|---------| | `pipeline.rs` | 中央分发 —— 读取格式前缀,分发到正确的解码器,应用裁剪/旋转后处理;接受 `&AtomicBool` 用于取消 | | `jpeg.rs` | JPEG 解码器封装(`jpeg-decoder` crate),EXIF 方向解析 | | `rgb565.rs` | RGB565 解码器(16 位 RGB 5/6/5) | | `rgb555.rs` | RGB555 解码器(15 位 RGB 5/5/5) | | `reordered_rgb555.rs` | 重排序的 RGB555 解码器(字节交换变体) | | `uyvy.rs` | UYVY 4:2:2 + 隔行 UYVY 解码器(使用 `--features simd` 时 YUV→BGRA 采用 SSE2/AVX2/NEON) | | `ycbcr420.rs` | YCbCr 4:2:0 平面解码器(使用 `--features simd` 时 YUV→BGRA 采用 SSE2/AVX2/NEON) | | `clcl.rs` | CLCL nibble-chroma 解码器(使用 `--features simd` 时 YUV→BGRA 采用 SSE2/AVX2/NEON) | | `cl.rs` | CL per-pixel chroma 解码器(使用 `--features simd` 时 YUV→BGRA 采用 SSE2/AVX2/NEON) | | `yuv.rs` | 共享的 YUV 转换辅助工具,SSE2/AVX2/NEON 运行时分发 | | `simd.rs` | SSE2/AVX2/NEON YUV 转换分发(特性门控) | | `device_profiles.rs` | 18 个设备的 iPod/iPhone 格式查找表 | | `enc.rs` | 用于所有原始格式的合成编码器 | | `enc_helpers.rs` | 共享的编码器辅助工具(InterlaceFields, BT.601) | | `profile.rs` | 配置结构体(IthmbVariantProfile, IthmbEncoding) | | `profile_db.rs` | 内置配置数据库(54 个条目) | | `profile_parser.rs` | 外部 `profiles.json` 的 JSON 解析器 | | `cache.rs` | LRU 原始文件缓存(特性门控) | | `metrics.rs` | 解码时间计数器(特性门控) | | `error.rs` | 类型化错误枚举(`DecodeError`)+ 解码后的图像类型(`DecodedImage`) | | `photodb/` | PhotoDB/ArtworkDB 块解析器、写入器、完整性检查器和类型定义 | **数据流** ``` .ithmb file → JPEG/EXIF scan ──→ JPEG slice → jpeg-decoder crate → BGRA ├─ No JPEG → prefix lookup → raw decoder → BGRA │ └→ no prefix + JPEG scan → byte-level SOI carving → jpeg-decoder → BGRA │ └→ no prefix + mhfd magic → PhotoDB parser → entries → raw decoder → BGRA └─ external .ithmb reference → read file → raw decoder → BGRA ``` **多帧支持** — F 前缀 `.ithmb` 文件可能包含多个串联的原始帧(由 Keith 的 iPod Photo Reader、ithmbrdr、libgpod 和 iOpenPod 确认)。编解码器从文件大小检测帧数。调用者可以通过帧索引(从 0 开始)访问各个帧;超出范围的索引将返回错误。嵌入 JPEG 的 T 前缀文件始终为单帧。 ### ithmb-cli(CLI 二进制文件) 用于解码、检查和分析 `.ithmb` 文件的命令行工具。使用 `clap` 进行参数解析,并使用 `png` crate 输出 PNG。 ``` # 将文件解码为 PNG ithmb input.ithmb output.png # 仅打印文件 metadata ithmb --info input.ithmb # 列出所有已知 profiles ithmb --list-profiles # 从多帧文件中提取特定帧 ithmb --frame 2 input.ithmb output.png # Raw BGRA 输出 (无 PNG 编码) ithmb --raw input.ithmb output.bin ``` ### ithmb-core-cabi(C ABI 动态库) 一个 `cdylib`,通过 `ig_plugin_get_api()` 实现了 ImageGlass v10 原生插件 ABI,从而能够集成到 Windows 上的 ImageGlass 图像查看器中。C ABI 层将所有解码逻辑委托给 `ithmb-core`。它与核心库分开构建,仅在集成 ImageGlass 插件时需要。 ### ithmb-python(PyO3 绑定) 一个 `cdylib`,通过 PyO3 (abi3-py312) 将 ithmb-core 暴露给 Python 3.12+。使用 `maturin build` 构建。 ### ithmb-gen(示例生成器) 一个 CLI 工具,用于生成开发过程中使用的合成 `.ithmb` 测试向量和参考 PNG。
Architecture diagram
## CLI 工具 `ithmb` CLI 工具支持四种模式: | 命令 | 描述 | |---------|-------------| | `ithmb input.ithmb [output.png]` | 解码为 PNG(根据扩展名自动检测格式) | | `ithmb --info input.ithmb` | 打印元数据(大小、前缀、配置、帧数) | | `ithmb --list-profiles` | 将 54 个配置的数据库打印为格式化表格 | | `ithmb --frame N input.ithmb [output.png]` | 从多帧文件中提取第 N 帧 | 输出选项:使用 `--raw` 输出原始 BGRA 二进制数据,使用 `--format bin` 指定输出二进制格式,扩展名为 `.png` 时自动选择输出 PNG。 ## 基准测试 解码吞吐量(divan,使用 `--features simd` 解码 256×256): | 解码器 | 时间 | 吞吐量 | |---------|------|-----------| | RGB565 | 34 µs | 7.8 GB/s | | RGB555 | 41 µs | 6.4 GB/s | | ReorderedRGB555 | 365 µs | 718 MB/s | | UYVY | 105 µs | 2.5 GB/s | | YCbCr 4:2:0 | 103 µs | 2.6 GB/s | | CLCL | ~200 µs | ~1.3 GB/s | | CL | ~200 µs | ~1.3 GB/s | | Pipeline (decode_ithmb) | 127 µs | 2.1 GB/s | 运行命令:`cargo bench --features simd` ## C ABI `ithmb-core-cabi` crate 编译为 `cdylib`(`.so`/`.dylib`/`.dll`),暴露了 ImageGlass v10 插件 ABI 入口点 `ig_plugin_get_api()`。这允许: - 在 Windows 上与 [ImageGlass](https://imageglass.org) 集成,以进行原生的 `.ithmb` 查看 - 从 C/C++、Python(通过 `ctypes`/`cffi`)或任何支持 C FFI 的语言进行 FFI 集成 - 无需子进程调用的零开销跨语言解码 ## 配置参考 **54 个已知配置**(+ 1 个推测性禁用的配置 —— 参见代码库中的注释),涵盖从 iPod Photo 4G 到 iPhone 2G 以及 iPod Nano 7G 的设备。最大帧大小:480×864 (RGB565, 830 KB)。有关包含尺寸、编码和设备映射的完整表格,请参见 [PROFILES.md](PROFILES.md)。可以通过 `profiles.json` 在运行时添加外部配置。 每个配置定义了像素编码、尺寸、每帧的字节长度以及后处理标志(裁剪、旋转、通道交换、尺寸交换、隔行扫描、填充)。 ## 限制 ## 故障排除 | 症状 | 可能原因 / 解决方法 | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | 文件无法打开 | 可能使用了未知的格式变体。请[提交编解码器 issue](https://github.com/B67687/ithmb-codec/issues)并附带样本。 | | 图像乱码 / 颜色错误 | JPEG 误报或原始解码器不匹配(罕见)。请[提交编解码器 issue](https://github.com/B67687/ithmb-codec/issues)。 | | “File too large” 错误 | 文件超过了 **32 MB** 限制 —— 正常的 iPhone 照片不应出现此情况。如果发生,请提交 issue。 | ## 开发 该库是通过迭代的研究、实现、审查和发布周期开发而成的: 1. **格式调查** — 发现并分析了 33 个开源 .ithmb 实现 2. **格式表提取** — iOpenPod(50+ 个条目)、libgpod、iLounge 讨论帖以及 Keith 的 iPod Photo Reader 为 54 个配置提供了尺寸/编码表 3. **实现** — 纯 Rust 工作区,包含 8 个解码器、JPEG 解码、PhotoDB/ArtworkDB 支持、CLI 工具、PyO3 Python 绑定和示例生成器 4. **测试** — 跨越 roundtrip、fuzz、libfuzzer、解析器、推测性路径、buffer-too-small 防护、trailing-padding 容差、JPEG carving 回退、多帧原始解码、旋转 roundtrip、字节级损坏 fuzz、BGR15 通道交换、PhotoDB roundtrip 写入、PhotoDB 完整性、PhotoDB JPEG blob 解码、特定设备格式表、并发压力测试以及格式 ID 配置测试的 486+ 个单元测试 5. **审查周期** — 5 轮多智能体审查:修复了约 47 项发现,涵盖内存安全、线程、ABI 兼容性、缓冲区溢出、整数溢出和纵深防御 6. **发布** — 通过 GitHub Releases 发布
Development pipeline diagram
完整版本历史请参见 [CHANGELOG.md](CHANGELOG.md)。 ### 质量流水线 发布前在本地运行的质量检查: ``` cargo clippy --all-targets -- -D warnings # Lint cargo test # All tests (486+ across 12 suites) cargo audit # Advisory check cargo fuzz build # Fuzz targets compile check ``` ## 对生态系统的贡献 除了构建一个可用的编解码器外,该项目还为 .ithmb 逆向工程领域做出了几项原创性贡献: - **多 OSS 格式合并** — 从 **22 个独立的实现**(iOpenPod、libgpod、Keith's iPod Photo Reader、clickwheel、gnupod、pygpod、ithmb-rs、OrgZ、andrewmalta/ithmb、wrinklykong/pyithmb、Reuhno、podkit、Steee29、keyj (Jeff Luyten)、Mixtape 等)中提取格式表,并将它们相互之间以及与现有表进行交叉比对。在设备配置中发现了 **15 处尺寸差异**,包括倒置的 Nano 5G/6G 配置、错误的 Nano 3G 格式,以及根据真实 iPhone 2G (iOS 1.1.4) 样本对 iOS 1.x 配置的修正。识别出 **18 个未出现在任何单一实现表中的格式 ID**。合并后的交叉参考涵盖了 **54 个唯一的格式 ID** —— 这是最完整的公开参考。 - **特定设备格式表** — 所有先前的工具都维护着所有已知格式 ID 的扁平列表。该项目映射了 **18 代 iPod/iPhone** 实际进行缩略图显示和封面艺术展示时所需的格式,从而使同步工具能够进行按设备的配置选择。 - **PhotoDB/ArtworkDB 写入支持** — 所有现有工具都是只读的(从设备的照片数据库中提取缩略图)。该项目实现了 `TryBuildPhotoDb`,能够从零开始编写有效的 ArtworkDB 二进制文件 —— 从而实现无需 iTunes 即可将封面艺术同步到 iPod。 - **通过社区进行硬件验证** — 发起了与 iOpenPod 的跨项目合作,其开发者购买了多个 iPod 型号,并跨固件世代验证了解码器。这填补了一个长期存在的空白:以前没有任何 OSS .ithmb 解码器进行过系统的硬件确认。 - **32 MB 文件大小限制(从头研究)** — 所有先前的解码器都引用 libgpod 的 256 MB 限制,但没有证据确认它是一个真实的固件常量。该项目独立推导出了 32 MB:跨 **54 个配置** 的最大帧大小为 829 KB,来自 5 个 RE 工具的多帧串联从未超过 ~40 帧,并且公开的 .ithmb 文件调查发现没有大于 1 MB 的文件。32 MB 是 2 的幂,涵盖了所有已知数据。于 2026-06-30 重新验证:40×P1007 = 31.64 MB(余量 376 KB)。 - **BGR15 iPhone 兼容性** — 通过真实的 iPod Classic 6G 样本 (Reuhno) 确认,iPhone 缩略图使用反向通道顺序(使用 `xBBBBBGGGGGRRRRR` 而不是标准的 `xRRRRRGGGGGBBBBB`)。添加了 `SwapRgbChannels` 标志 —— 这是第一个将 iPhone 像素布局与 iPod 布局区分开来的解码器。 - **推测性配置更正** — F1064 配置(320×240 YCbCr)在社区推测中流传多年。与每个公开实现进行了交叉检查:均未包含。已将其禁用并说明了理由。还将 CLCL nibble 缩放比例从 ×17(最初的 2005 Whirlpool RE)更正为 ×16,并与 2 个独立的实现进行了交叉验证。 - **合成测试向量 (CC0)** — 在此项目之前,不存在公开的 F 前缀测试数据。Reuhno 贡献了生成的 CC0 向量,涵盖了 3 种插槽几何结构(带有不同内容矩形的 56×55 插槽、128×128、320×320)以及 30 个参考 PNG。这些是用于原始 .ithmb 解码的首批公开测试向量。 - **负面认知:iOS Photos ≠ iPod Classic** — 下载并分析了两个 iOS 固件映像(9.3.5 和 iOS 18),确认它们的 .ithmb 文件使用的是完全不同的、此编解码器无法解码的专有格式。记录了关于 .ithmb 跨平台兼容性的一个常见误解。 ## 更新日志 版本历史请参见 [CHANGELOG.md](CHANGELOG.md)。 ## 许可证 MIT — 详见 [LICENSE](LICENSE)。 最初的 IthmbDecoder 参考实现(PR [#2316](https://github.com/d2phap/ImageGlass/pull/2316))是 GPL-3.0 协议。本库是一个净室实现,参考了该 PR 中描述的格式行为,但未使用任何 GPL 代码。
标签:Apple, ImageGlass插件, Rust, 可视化界面, 图像处理, 多媒体工具, 文件格式解析, 编解码器, 网络流量审计, 通知系统